iOS之开发SDK(.framework和.bundle)(包括支持ATS和ssl双向验证及瘦身)

SDK

Posted by LuochuanAD on November 9, 2016 本文总阅读量

前言

我的SDK涉及到网络请求,图片,界面的背景色,字体颜色等等;

分析

  • 开发出来的SDK是给别人用的, 所以新建一个.plist文件统一管理界面UI, 同时会将.plist文件和图片放到.bundle文件中.

  • 网络请求我用的是AFN,在导入到SDK中时我将AFN的文件的前缀添加SH,为了避免重复(注:我将所有的文件都添加了SH前缀,不仅仅是AFN).

步骤:

一,新建项目

.framework创建选择左边的.命名为SHTestSDK. 如下:

​ ​ ​ ​

二,将SHTestSDK.h文件删除

​ 为什么删除,因为用不到
​ ​

三,代码文件导入:

​ 这步有个关于图片.plist的读取,还有其他的一些代码处理,在后面再说 ​ ​ ​ ​ ​ 可以看到上面的所有文件都加了SH前缀,包括AFNetworking. Products下的SHTestSDK.framework为红色字,因为还没编译,所以显示不可用的状态. ​

四,.framework建立:

​ 虽然说支持了armv7和arm64.就不需要再添加armv7s,但是在在这里我添加了. ​ ​ ​ Build Active Architecture Only 设置为NO的意思是当前打包的.framework支持所有的设备.否则打包时只能用当前版本的模拟器或真机运行. ​ ​ ​ Build Setting 搜索linking     设置Dead Code Stripping 为NO是编译选项优化,包瘦身,(可不改)  Mach-O Type 选中StaticLibrary (静态库)  Xcode默认是动态库. ​ ​ ​ 如果.framework中有需要支持mrc文件运行的:添加-fno-objc-arc ​ ​ ​ 将需要呈现给来的头文件,直接从Project拖到Public中. 不想呈现出来的.h文件不建议拖到Private中.  这里说明一点,如果你呈现出来的.h文件中import其他的头文件,那么你import的其他头文件也要呈现出来(即拖到Public中). 如果不想呈现出太多的.h文件. 那么在.h文件中@class 声明, 在.m文件import. ​ ​ ​ 编译之前,要选择release模式 ​ ​ ​ 选择模拟器和真机各编译一次Command+B . 此时.framework显示为可用状态. 如果想再次编译,请先product-clean一次. ​ ​ ​ ​ ​ 右键SHTestSDK.framework show in finder 一个用模拟器测试,一个用于ipa打包 ​ ​ ​ 以上就是.framework静态库的打包. ​如果你开发出来的.framework很小,可以在终端用:lipo -create "真机版本路径" "模拟器版本路径" -output "合并后的文件路径" 合并成一个.framework. 如果太大,还是不要合并的好. ​

五,.bundle的建立

​ 在桌面新建文件夹SHTest 将图片和.plist拷贝到里面. 给SHTest添加后缀.bundle 就可以直接生成.bundle文件. ​ ​

六,集成

​ 将.framework和.bundle拖入到要集成的项目中,就可以了. ​在.framework中读取.bundle里面的资源,用以下方法.   ​ ​


​-(UIImage *)imagesNamesFromCustomBundle:(NSString *)imgName
​{
​NSBundle *myBundle=[NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"这里填写bundle的名字" ofType:@"bundle"]];
​
​NSString *img_path=[[myBundle resourcePath] stringByAppendingPathComponent:imgName];
​
​return [UIImage imageWithContentsOfFile:img_path];
​}
​

​
​NSString *pathString1=[[NSBundle mainBundle]pathForResource:@"这里填写bundle的名字" ofType:@"bundle"];
​NSBundle *resourceBundle=[NSBundle bundleWithPath:pathString1];
​NSString *pathString=[resourceBundle pathForResource:@"这里填写.plist的名字" ofType:@"plist"];
​NSDictionary *sources=[[NSDictionary alloc]initWithContentsOfFile:pathString];
​

​ ​注意,SDK包要支持ATS和SSL双向验证,请看我另外一篇博客:iOS之支持ATS和ssl双向验证 ​这里是将ca.cer,server.cer.client.p12证书都放在.bundle中.那么在.framework的代码里面获取可以通过以下方法: ​ ​


​- (NSString *)trustCenyification:(NSString *)str{
​NSBundle *myBundle=[NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"这里填写你的bundle名字" ofType:@"bundle"]];
​NSString *path=[[myBundle resourcePath] stringByAppendingPathComponent:str];
​return path;
​}
​调用[self trustCenyification:@"server.cer"]
​

由于我.framework的UIWebView调用的是http页面,所以我在info.plist设置了Allow Arbitrary Loads=YES.同时将info.plist拖到了.framework的Project中.那么将这个SDK集成到其他的项目app中,也需要这么设置. ​ ​注意,SDK包开发完成后,需要对SDK瘦身,请看我另外一篇博客:iOS之开发的SDK(.framework)瘦身 ​ ​下面是项目集成SDK(亲测,是可以的) ​注意跳转到SDK中的控制器,用present跳转. ​ ​ ​ ####​补充: 如果静态库中有category类, 则要在静态库的项目中[Other Linker Flags]添加参数[-ObjC]或[-all_load]. 如果静态库中添加.tbd或.dylib, 则在你需要集成的项目中也要添加.并且在[Build Setting]中将 [AllowNo-modular Includes inFramework …]设置为YES. ​

参考

​旧版原文在CSDN上 https://blog.csdn.net/luochuanAD/article/details/53096795 ​ ​http://www.jianshu.com/p/43d55ae49f59 ​ ​http://blog.csdn.net/bravegogo/article/details/52699698 ​ ​http://www.jianshu.com/p/11710e7ab661
​ ​http://blog.sina.com.cn/s/blog_87533a080102vzyg.html ​ ​http://www.jianshu.com/p/43d55ae49f59 ​ ​ ​ ​ ​ ​ ​ ​ ​