开发维护一个ios sdk的7个注意点
笔者工作中大部分时间都在开发和维护糯米ios的hybird组件sdk,目前该sdk输出在手百、地图、钱包、销售通、糯米商户等app上。从平时的工作中反思得出一些心得,总结归纳成文档,自我梳理也希望能给其他输出sdk的同学一些建议。
开发维护一个良好的ios sdk,需要考虑的因素很多,主要有明确需求、划分模块,制定接口,制定性能期望、确定代码管理方式、制定代码编写规范、管理对第三方sdk的依赖、考虑支持平台、测试、选择发布方式、撰写开发文档并提供demo示例。为了提供通用建议,笔者主要写了以下七个注意点:
1、source control
不管开发团队中rd是一人还是多人,将源码通过源码管理软件管理起来是代码库得到持续维护的前提条件。目前,我们公司推荐使用的是git。利用git可以方便快捷的进行创建、切换、合并分支; 管理提交记录;快速代码回滚等操作,同时版本库本地化、支持离线提交,实乃rd开发必备的一个利器。
2、代码接口设计
开放最小功能接口,只对外开发满足开发所需的最小的接口集。
开放的每个接口命名良好,输入输出注释清晰无歧义,功能单一。
面向接口编程,提供扩展点方便用户定制功能。
3、代码开发
a、使用Objective-C开发,在sdk中如果对系统类编写了Category,那么category中的方法强烈建议加特定前缀,防止冲突。sdk中的所有类和enum建议增加特定前缀。
b、模块划分清晰,高内聚低耦合
c、代码简洁保证可读性。
d、命名良好,类和函数符合功能单一的特性
4、第三方库依赖
在sdk中可能存在对第三方库OtherLib 版本1.0的依赖,使用sdk的application可能依赖OtherLib的其他版本,该情况下怎么管理OtherLib目前主要有以下三种方案:
1) sdk在文档中说明依赖的第三方库及其版本,由application开发者去管理第三方库,解决版本不兼容的问题。application开发者工作量变大。
2) sdk打包的时候将第三方库集成进去,该情况下,需要application开发者适配使用sdk集成的第三方库版本。实质同方案一,只不过使用的otherLib是通过sdk集成进去的。
3) sdk打包的时候通过撰写脚本将第三方库导出的符号重命名之后再集成进去,该方案本质上解决了sdk中的otherLib和application中otherLib的冲突。缺点是增加了安装包大小,application集成了两份otherLib。
5、 platforms
需要考虑使用我们提供的sdk的application支持的the base deployment target。如果sdk不支持低版本的ios系统,并使用了高版本ios系统提供的功能,那么当运行在低版本设备上时,会导致crash。
6、 Distribution方式
目前主流的发布方式有Cocoapods、Framework、.a三种。
A、 开源方式: 推荐使用Cocoapods。Cocoapods的主要原理是sdk的提供者通过编写合适的 PodSpec 文件来提供sdk的基本信息,包括仓库地址,需要编译的文件,依赖等,用户使用 Podfile 文件指定想要使用的框架,CocoaPods 会创建一个新的工程来管理这些框架和它们的依赖,并把所有这些框架编译到成一个静态的 libPod.a。然后新建一个 workspace 包含你原来的项目和这个新的框架项目,最后在原来的项目中使用这个 libPods.a。目前组件hybird sdk通过Cocoapods管理集成进糯米app。
B、 非开源方式
库是共享代码的方式,分为静态库和动态库,其中静态库链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝。动态库链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存。ios中静态库的形式有.a和.framework;动态库的形式有.dylib和.framework。注意在ios上,系统的.framework是动态库,我们自己建立的.framework是静态库。
Framework可以将资源文件包含在自己的bundle中。
Library只包含二进制代码,其他的图片等资源文件需要单独提供。ios8之前只支持静态Library的方式。
由于目前ios11已经发布,推荐在非开源发布的情况下使用Framework的形式,开发者集成Framework更加简单。Framework的自包含能力更强,无须单独提供.h头文件。
7、 测试
sdk的主要用途是提供给其他的开发者使用,这样特殊的场景非常适合测试驱动开发。 测试驱动开发的基本思想就是在开发功能代码之前,先编写测试代码。也就是说在明确要开发某个功能后,先思考如何对这个功能进行测试,完成测试代码的编写,然后编写相关的代码满足这些测试用例。后续循环进行添加其他功能,直到完成全部功能的开发。
保留所有的测试用例代码入库并加入到source control,让这些测试用例作为后续开发和重构的安全网,每次提交新代码,都自动执行。