一、SDK简介
库是程序代码的集合,是可执行代码的二进制格式,可以被载入内存中执行
根据源代码的公开与否,可以分为开源库和闭源库
开源库公开源代码,可以看到具体实现,如AFNetworking、SDWebImage等
闭源库不公开源代码,是经过编译的二进制文件,如微信SDK,腾讯地图SDK等
闭源库又分为静态库和动态库
静态库,链接时会被复制到可执行文件中,文件形式为.a或.framework,使用静态库可减少编译时间。
动态库,链接时不复制,程序运行时由系统动态加载到内存中,文件形式为.dylib.或framework,使用动态库可减小包大小。
二、SDK常用命令
设备的CPU架构:
1、模拟器:
4s-5:i386
5s-?:x86_64
2、真机
3gs-4s:armv7
5-5c :armv7s
5s-? :arm64
lipo -info XXX.a
lipo -create Debug-iphoneos/XXX.a Debug-iphonesimulator/XXX.a -output XXX.a
lipo XXX.a -thin arm64 -output XXX-arm64.a
info常用于对外输出检查静态库的架构信息,create常用于合并真机和模拟器版本,一般写在自动打包的脚本中
三、SDK对外输出
对外输出SDK时,必要的元素包括通过测试的SDK本身、Demo、接入文档、测试报告等。
1、接入文档
接入文档中需说明SDK的接入方式和依赖的系统动态库
接入文档中需说明SDK需要的工程配置,如SDK中包括类别方法,需在Build Setting选项卡中Other Linker Flags中加入-ObjC或-force_load等配置
接入文档中需说明SDK需要的权限配置,如NSLocationWhenInUseUsageDescription、NSFaceIDUsageDescription等
接入文档中需说明SDK编译环境
2、SDK
SDK必须使用官方正式版Xcode编译(15年XcodeGhost)
SDK必须使用Release模式编译(优化代码,Debug模式包含NSLog和测试功能入口)
SDK必须包含真机和模拟器(避免宿主模拟器编译报错)
SDK必须支持应有架构
SDK应该支持bitcode
SDK应该在头文件或info中包含静态版本号(便于排查问题)
SDK应该提供版本号的查询API(便于接入方进行版本差异化处理)
SDK如果以.a静态库形式输出,应包括.h和.a,如果有资源还应包括bundle(均不限于一个)
SDK如果以.framework静态库形式输出,宿主工程需额外引入bundle
SDK如果以.framework动态库形式输出,还需提供对应的dSYM符号文件
四、SDK开发原则
1、必须加类前缀
iOS没有命名空间,Apple建议开发者为自己的项目添加统一的类前缀,避免和iOS的某些系统符号冲突,但目前没有强制校验,App体量增长后统一的前缀也不容易贯彻执行。
开发SDK为避免与宿主App或系统符号冲突,必须添加类前缀。
其他iOS内的顶级符号也需注意,如全局变量、C函数名等。
如果SDK包含资源,资源命名也需注意。
2、 类别方法名必须加前缀
因为类别方法也会在类加载过程中被添加到类的方法列表中,且后添加的先被找到。所以SDK内的类别方法如果和宿主App同名,会有覆盖或者被覆盖的情况出现。
3、禁止使用Runtime替换系统方法实现。
部分App选择使用Runtime替换系统方法实现的方式完成自动化埋点等需求,如ViewController生命周期方法、按钮点击、手势等,如果SDK替换了系统方法实现,会导致宿主App此部分功能异常。
4、禁止调用Apple私有方法
调用Apple私有方法会导致宿主App有被拒的风险,如使用prefs:root=引导用户进入各个权限设置页面等功能。
5、尽量避免在load方法中加入逻辑
启动时间是衡量一个App性能的重要指标,如无必要,尽量避免在SDK开发中出现使用load方法的情况
五、工程搭建
开发SDK,SDK工程的产物为.a或.framework,导入App Demo工程进行联调或测试,以.a为例,如图:
由于Demo中Debug较复杂,实际开发中,会选择更便捷的工程组合进行联调:
1、子工程方式,如图:
需要修改Demo工程Build Settings选项卡Header Search Paths,添加头文件的相对路径。
需要修改Demo工程Build Phases选项卡Link Binary With Libraries,添加SDK。
2、单工程多Target方式,如图:
需要修改Demo工程Build Phases选项卡Link Binary With Libraries,添加SDK。
因为在同一个工程目录内,Header Search Paths无需配置。
3、Workspace方式,如图:
Demo工程配置与子工程方式相同。
4、Pod
pod lib create JDPLibrary
几种方式各有利弊,如何选择需从项目规模、工程配置、打包脚本和最重要的业务等方面综合考虑。
六、第三方库
原则上,SDK开发中尽量少使用或者不使用第三方库,以避免外部的依赖和不可控因素。实际开发中,由于工期、稳定性等因素,不可避免得使用一些成熟的第三方库。为了避免与宿主App可能出现的符号冲突,有几种方式可以选择:
1、改名
优点:改名后通过测试既代表比较稳定了,后续不会因为宿主升级第三方库对自身造成影响
缺点:修改类名、全局变量名、枚举名、C方法名等工作量较繁琐;SDK包含一份第三方库的代码,如果宿主App也依赖,这部分属于冗余代码。
改名方式:Xcode->Rename;宏命令
2、编译时不包含第三方库
优缺点与前一种方式相反,SDK可能受到宿主App升级或修改第三方库的影响,但无冗余代码。
编译方式:编译时只引入头文件,对外输出时,额外输出一个依赖库的全集,并在接入文档中写明版本号。
3、Pods管理