I'm Terrence

iOS项目部分代码独立子工程

项目在迭代到一定程度的时候,自然而然地,就有需求去将某部分功能的代码独立出来,这也是个必然经过的重构阶段。
网上关于这部分的资料其实已经很全了,在这里我就总结一下这方面重构的感悟吧。

mov files

这次commit log最多字眼字眼就是mov files了。一移动文件,svn肯定就有增有减的标记。一开始挺怕删的文件比加进去的多的,所以每次都数一下两者文件数量是否一致。
在这个动作之前,肯定肯定会对要操作的文件进行showInFinder,打开了,发现这真是个有趣的地方。
不同习惯的开发者,创建新文件的风格是不同
习惯不好的,对xcode的文件结构即使已经分了group了,但show in finder进去一团糟。
在这里总结出第一条:
new file的时候,finder文件结构尽量和xcode目录结构一样,一个文件夹对应一个group

还有有个小技巧:
每次改变finder文件结构后,最好都clean一下项目,然后再build,不然有大概率报错找不到头文件。

在子工程里面

Resource

这里应该是最麻烦的地方了。原来在主工程用到mainBundle的地方,通通要改成对应的子bundle。

bundle

创建子工程bundle具体操作如下图
上图



在主项目里面

Build Settings -> user header Search paths

要在这里添加.a文件进去。

Build Phases -> Copy Bundle Resources

把子工程的资源文件.bundle添加进去。

Build Phases -> Target Dependencies

配置依赖,把在子工程添加进去。这样每次编译的时候,就会先把里面的子工程编译过了,再去搞主工程。没弄这个的话,每次一动子工程什么地方了,必须特定对那个子工程进行build···

子工程加载图片 imageName:?

从上面步骤下来,子工程用代码加载子bundle图片是加载不出来的,特别是iOS7,连xib 都load不出图片来。7以上是可以的。
因为直接用imageName:是有问题的,load 出来是nil来的。
看api才知道,imageName:是load from main bundle的,对于子bundle,代码要做如下处理

+ (NSString *)resourceName:(NSString *)name withBundleName:(NSString *)bundleName
{
    return [NSString stringWithFormat:@"%@.bundle/%@", bundleName, name];
}

+ (UIImage *)imageNamed:(NSString *)imageName withBundleName:(NSString *)bundleName
{
    NSBundle *bundle = [self bundleNamed:bundleName];
    if (SystemLessThan(8.0)) {
        NSString *path = [[bundle resourcePath] stringByAppendingPathComponent:imageName];
        UIImage *image = [UIImage imageWithContentsOfFile:path];
        return image;
    }
    else {
        return [UIImage imageNamed:imageName inBundle:bundle compatibleWithTraitCollection:nil];
    }
}

+ (NSArray *)loadNibNamed:(NSString *)name owner:(id)owner withBundleName:(NSString *)bundleName
{
    NSBundle *bundle = [self bundleNamed:bundleName];
    return [bundle loadNibNamed:name owner:owner options:nil];
}

+ (NSBundle *)bundleNamed:(NSString *)bundleName
{
    NSString *bundlePath = [[NSBundle mainBundle] pathForResource:bundleName ofType:@"bundle"];
    return [NSBundle bundleWithPath:bundlePath];
}

这里需要特别注意,这个方法无法直接加载image assets里@2x图片,必须逐一把图片拉出来,然后加进bundle里面,才可以成功读取···