iOS 应用的 Theme 开发

今天终于把去年想做的一件事搞定: 完成新版Theme管理组件并开源。

这是我第一次做主题管理开发。所以先网上了解了下,普遍做法是把主题相关的图片资源放在一个文件夹,再用的时候通过切换不同的文件夹来实现主题切换。

而在公司的项目里,同事换了一个思路,他给每个主题建了一个plist文件。在plist为保存图片名和其对应的Key。这样,相同的Key在不同的plist可以对应不同的图片,然后就通过换plist文件来换主题。plist的好处是还可以保存不同主题的颜色值,字体大小等信息。

但是呢,在使用的时候发现这个方案有以下缺陷:

  1. 增加一个新图片,就要到每个主题的plist里添加一下对应的key;
  2. 在我们的项目里,几个主题之间只是有一部分的区别,这样新建主题的时候需要从其他主题里先把相同的值全复制过来,然后再改;
  3. 图片没有分文件夹,导致同一个Key在不同主题下对应的图片资源放在一起有命名上的麻烦,时间长了难管理。

看到这些问题后,我做了第一步改进是设置了一个Base Theme,把几个主题里相同的东西抽出来,放在这里。其他主题只留不一样的。在读取资源的时候先看当前主题,没找到就去Base Theme找。

但再一想,主题多了的话,每个主题的base部分可能不一样。于是我又想到了继承。即主题可以设置一个父主题。这样当在这个主题没找到资源的话,就去父主题找。

同样的道理,对于Color、Font这些,也是一样的道理。不同的Key对应的值也可能是一样的。于是我改成颜色的Key可以指定和其他的某个Key一样就行,组件会自己找过去。

最后对于图片资源问题,我不再往plist里添加了。我把所有主题资源按照bundle来管理,然后用文件名来做Key。这样很轻巧的同时解决图片管理问题。

Bundle加主题继承合在一起,就能使每个主题只增加自己想改的部分,大大减少了创建新主题的工作量。

最后,按照以上思路,新版主题管理终于完成!这个组件叫AWLThemeManager,已经放到CocoaPods上了。欢迎大家拍砖。

2015/3/12 22:16 下午 posted in  iOS

自备翻墙梯: Shadowsocks

在天朝搞技术的,都得有个梯子。

以前我用的是GoAgent,平时偶尔翻墙都用的这个。GoAgent 的好处是方便、免费;坏处就是不稳定:防火墙大姨妈来的时候就不好使了。后来尝试了下shadowsocks,感觉速度稳定,够快。现在有了服务器,就准备自己搭一个。

Shadowsocks有很多实现,官方教程写的很详细,按照教程做就好。我用的是python版本,官方有中文教程,写的很简单,我就不重复了。这里我就补充一点没有的吧。

Shadowsocks本身是不支持直接后台运行。我们可以用Supervisor来实现这点,官方也是这么说的,只是太简单了。对于我这种刚玩服务器的新手来说看不懂啊。只好自己研究下怎么用Supervisor。下面就是我总结的一些要点。

  1. 安装:
    如果是按照官方文档来的话,此时应该已经装过 setuptools。可以直接用 easy_install:

    easy_install supervisor
    
  2. 创建默认conf:
    第一次安装成功后,需要自己手动生成一个配置文件。生成脚本名为「echo_supervisord_conf」。可以在输出的安装日志里看到这个文件在哪,我的是在「/usr/bin」文件夹下。找到后如下命令生成conf:

    echo_supervisord_conf >/etc/supervisord.conf
    

    然后用vim打开生成conf文件,转到文件结尾处,去掉「[include]」和「files」前的分号。改成如下:

    [include]
    files = /etc/supervisord.conf.d/*.conf
    

    记得「[include]」前的分号也要移除,不然「files」这句不起作用。这一步的目的是指定supervisor去哪找要调用程序的配置文件。其实偷懒的话,也可以直接在这个「supervisord.conf」里写。但这样不好管理,所以找个目录,按程序分文件写。这个目录可以按照自己的来,上面是按照我的来;

  3. 切换到上一步「files」定义的目录下,创建shadowsocks.conf。写入下面内容:

    [program:shadowsocks]
    command=ssserver -c /etc/shadowsocks.json
    autorestart=true
    user=nobody
    
  4. 如果在shadowsocks配置的端口小于1024,那上面的「user=nobody」要改成「user=root」。

  5. 然后,可以把Supervisor配置成服务,方便管理。我用的centOS系统, 其他系统可自行搜索。在「/etc/init.d/」创建「supervisord」,然后用vim输入下面代码:

    #!/bin/sh
    #
    # /etc/rc.d/init.d/supervisord
    #
    # Supervisor is a client/server system that
    # allows its users to monitor and control a
    # number of processes on UNIX-like operating
    # systems.
    #
    # chkconfig: - 64 36
    # description: Supervisor Server
    # processname: supervisord
    
    # Source init functions
    . /etc/init.d/functions
    
    RETVAL=0
    prog="supervisord"
    pidfile="/tmp/supervisord.pid"
    lockfile="/var/lock/subsys/supervisord"
    
    start()
    {
            echo -n $"Starting $prog: "
            daemon --pidfile $pidfile supervisord -c /etc/supervisord.conf
            RETVAL=$?
            echo
            [ $RETVAL -eq 0 ] && touch ${lockfile}
    }
    
    stop()
    {
            echo -n $"Shutting down $prog: "
            killproc -p ${pidfile} /usr/bin/supervisord
            RETVAL=$?
            echo
            if [ $RETVAL -eq 0 ] ; then
                    rm -f ${lockfile} ${pidfile}
            fi
    }
    
    case "$1" in
    
      start)
        start
      ;;
    
      stop)
        stop
      ;;
    
      status)
            status $prog
      ;;
    
      restart)
        stop
        start
      ;;
    
      *)
        echo "Usage: $0 {start|stop|restart|status}"
      ;;
    
    esac
    

    然后保存。然后设置权限,启动:

    chmod +x /etc/init.d/supervisord 
    chkconfig supervisord on
    service supervisord start
    

以上就是全部,如果shadowsocks没有起来,可以通过这个命令看日志:

supervisorctl tail -f shadowsocks stderr
2014/7/9 0:13 上午 posted in  Other

网站根目录的跳转设置

2014/7/6 16:11 下午 posted in  Other

Finally

终于,我也有自己的博客了!

不容易啊,都拖了好多年了……

现在走出了第一步,希望以后能坚持下来。不求产出很多,只要有就好了。

2014/7/6 14:10 下午 posted in  Other