前言
我的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