iOS开发

workspace管理静态库和多个项目, 及cocoaPods的

2018-11-14  本文已影响67人  大猿媛

项目背景

项目需求:
在已有项目A的前提下,抽离出一个和项目A有公共业务甚至模块的项目B,对于公共业务和模块当然是想维护一份代码实现两个项目同步;差异性在于两个项目的主题风格、项目模块架构不一致,有各自独立的业务和功能。
开发思路:
1、copy出另一个target实现项目B的业务模块;否定原因:两个项目的UI、架构不一致,在didFinishlaunch时就有差异,这种需要通过判断当前target的方式进行差异性开发,代码会比较杂乱和难以维护,图片等资源文件的分离使用也很难做到,另外还会增大开发包的体积
2、组件化开发;将公共基础模块和业务模块完全独立,使用pod管理不同组件,两个独立项目中进行各自的引用;否定原因:1)开发时间紧迫,人手不足,完全抽离组件不太理想 ,2)对于公共业务模块,两个项目的风格也不尽相同,某种程度上不能完全独立,3)现状是公共的业务模块也需要开发升级,抽离出去就需要不停维护,这种不稳定状态实际上不适合封装成组件
3、workspace工作区开发;采纳原因:1)不同于组件抽离,workspace内的静态库可以灵活抽取,不用像组件那样需要完全和外部解耦,可以把工具,三方库,category等自定义的和项目AB公共的业务模块都放在静态库, 2)由于静态库被项目引用后,图片资源通过bundle管理并且内置于项目,所以图片资源可以独立两份于两个项目中,3)公共业务只需在静态库中进行开发,两个项目引用静态库就好,静态库把外部使用的类的头文件设置好就可以了;
4、具体开发过程和遇到的问题,就往下看吧

项目配置

实际开发项目:一个workspace中一个静态库和两个项目

一、创建workspace工作区,cocoaTouch static library,projectA 和 projectB
1.1 workspace文件,不多说,直接上图,创建好后只会生成一个.xcworkspace文件,无其他文件生成 选择创建workspace
1.2 创建静态库,由于苹果不支持开发者使用动态库,所以我们使用静态库(当然也可以选择动态库CocoaTouch Framework再改成静态库,还是有不同的) 选择创建静态库
静态库最后一步 静态库创建的时候最好和workspace文件在同一目录下,便于管理
1.3 两个项目的创建和日常创建项目无异,只是要和静态库一样,选择addTo和group到刚刚创建的workspace 最终的文件目录, 如图,两个项目一个静态库在一个workspace下 workspace文件目录
二、静态库的配置和项目中的使用

1、由于我们是在workspace中创建静态库,和独立的静态库使用不同(将.a文件拖拽入项目即可),而是在同一个workspace里,一起编译,具体往下看

1.1 前往静态库的target的Build phases,添加copy Files,以便项目中引用静态库暴露的头文件

如何将静态库中的类暴露出去

1.2 项目引用.a静态库,Link binary with libraries下,add
libCommonLibrary.a
1.3 访问静态库的类,#import<CommonLibrary/CommonLibrary.h>
至此,项目中如何应用静态库和访问其类就结束了,心好累吧

静态库中xib和图片资源的管理

先解释一下这个过程,在项目A中引入.a静态库,对于[NSBundle mainBundle]返回的是项目A的bundle,那么.a中的xib和图片资源肯定是不在项目A的bundle中的,所以在.a中如何加载xib和图片呢,下面要讲,如何管理静态库中的资源文件

对于bundle可以理解为一个捆绑包,个人理解bundle为一个独立的空间,而我们的可执行(executable)工程,打包完之后,也是一个捆绑包,我们称之为主bundle,这个主bundle包含了可执行代码,如各个viewcontroller的可执行代码,和相关资源例如图片资源等。

使用bundle管理静态库中的xib和图片资源
bundle如何使用
//其中一个项目的名称是qmp_ios,这样可以判断静态库当前是哪个项目加载的
+ (BOOL)isQMP{
    return [[[NSBundle mainBundle]bundlePath]containsString:@"qmp_ios"];
}
//xib资源所在的bundle
+ (NSBundle *)commonBundle{
    NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"CommonBundle.bundle"];
    NSBundle *bundle1 =  [NSBundle bundleWithPath: path];

    return bundle1;
}
//qmp_ios引入的图片资源QMPimgBundle.bundle
+ (NSBundle *)qmpImgBundle{
    
    NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"QMPimgBundle.bundle"];
    NSBundle *bundle1 =  [NSBundle bundleWithPath: path];
    
    return bundle1;
}
//xinzhi_ios引入的图片资源XZimgBundle.bundle
+ (NSBundle *)xzImgBundle{
    NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"XZimgBundle.bundle"];
    NSBundle *bundle1 =  [NSBundle bundleWithPath: path];
    
    return bundle1;
}

+ (NSString *)getBundlePath: (NSString *) assetName{
    NSBundle *myBundle = [BundleTool commonBundle];
    if (myBundle && assetName) {
        return [[myBundle resourcePath] stringByAppendingPathComponent: assetName];
    }
    return nil;
}
//用此类替代[UIImage imageNamed] 访问正确路径下的图片,bundle下的图片可以直接[UIImage imageNamed: bundle+图片名]
+ (UIImage*)imageNamed:(NSString*)imageName{
    if ([BundleTool isQMP]) {
        if ([imageName containsString:@"activity_user"]) {
            NSLog(@"----");
        }
        return [UIImage imageNamed:[NSString stringWithFormat:@"QMPimgBundle.bundle/%@",imageName]];

    }else{
        return [UIImage imageNamed:[NSString stringWithFormat:@"XZimgBundle.bundle/%@",imageName]];
    }
    
}

至此,bundle的创建和使用就此结束,而在项目内部(不牵扯静态库)用到的图片及xib和平时普通的用法还是一样的,因为项目内的Bundle就是xib和图片所在的bundle

静态库中的类和项目中的类如何相互调用

先讲,这种workspace机构,.a静态库只能被项目引用,不能引用项目(项目是可以引用项目的),那就意味着项目可以随意调用.a暴露出来的静态库中的类,那.a如何调用项目的类呢,以上讲了背景,我们的.a不是完全独立解耦的,项目A和B的公共业务模块还在.a里,所以.a 是存在需要调用项目业务模块的情况的;

如何使用cocoaPods

上面讲过,静态库被引入项目之后,编译执行环境都是项目的环境,所以静态库需要的环境(build phases,三方库,系统库),项目中也需要实现配置,那么......

workspace 'WorkSpaceQMP.xcworkspace'
target 'CommonLibrary' do
  platform :ios,'8.0'
  project 'CommonLibrary/CommonLibrary.xcodeproj'
  pod 'AFNetworking', '~> 3.1.0'
  pod 'MJRefresh', '~> 3.1.0'
  pod 'SDWebImage'
end

target 'qmp_ios' do
  platform :ios,'8.0'
  project 'qmp_ios/qmp_ios.xcodeproj'
 pod 'AFNetworking', '~> 3.1.0'
  pod 'MJRefresh', '~> 3.1.0'
  pod 'SDWebImage'
  pod 'YYText'
最后一个步骤,git管理

我的一个不知道是否错了的步骤: 创建仓库并初始化——>clone到本地文件夹——>代码复制到此文件夹——>add,commit,push——>发现两个项目是空,git提示subModule的相关信息

遇到的问题
上一篇下一篇

猜你喜欢

热点阅读