iOS 高级篇 - 《SDK制作完整篇》
问题记录:随着项目的越来越多业务,急需把一些模块整理,打包弄成SDK的形式,通过Cocoapods导入到工程,同时也对工程进行组件化考虑,但是问题就来了,有一部分代码属于核心部分,不适合开源,同时很多业务逻辑需要依赖第三方的开源框架来完成。,而且后期可能要给合作的公司调用SDK来展开合作。
然后就查看网上资料,老实说,虽然网上的感觉就那些步骤,很简单的样子,但自己走出来的坑,只有自己最清楚,各种心累...,现在总算摸着门槛了,死也要记录一下。
我要处理大概什么步骤呢?
1、需要把工程里面的业务逻辑代码和相关工具类抽出来👏。(急不来,细心,而且业务流程要熟悉,最好是先在原来工程中整理好,然后把方法和属性命名风格统一,需要考虑暴露什么接口出去给外部调用)
2、好了,花了很大力气把源码都抽出来了,问题来了,接下来该怎么处理了呢?然后就参考网上的各种博文。
想想需求,就是pod xxx,就导入了xxx,和第三方库FMDB等,其中xxx中包括一个xxx.framework和一些.h,.m文件(基本就参考了Pod进来的高德地图的SDK的方式)
1、【一个不可泄露的核心源码的.Framework】
2、【业务逻辑:包括{.h,.m}文件,另外依赖一些第三方框架,如FMDB等】
3、【Pod方式导入】
1、【一个不可泄露的核心源码的.Framework】
framework总结思考🤔:
制作这个Framework,假如需要依赖一些第三方库,如AFNetworking,导入头文件的时候,但是Framework中肯定是没有AFNetworking源码的,有人介绍说直接改类前缀,但感觉肯定不是这样的(但时间确实紧时,老是说,假如还没找到合适的方式来处理这个问题,这样也是一个很笨的方法,至少行得通)
再后来我参考别人的博客,成功弄好Framework之后,回头再看其实就是依赖就是依赖,理解依赖的含义,不是要你打包进去Framework中的,在制作Framework时那个文件需要,就直接导入头文件,如< AFNetworking/AFNetworking.h>
然后打包好之后,假如是直接Framework给别人使用的话,直接在使用说明文档中指明要依赖AFNetworking框架,这个很笨拙,但也是一个方案。
另外一个方案就是不用叫别人手动依赖AFNetworking框架,这个步骤就由自己自动给他依赖就行了,想想平时Pod导入一些开放平台的SDK时,假如Pod A,执行之后,发现A是pod进来了,但同时也Pod进来了B和C等等,这不正是我也需要的吗?
别急请接着往下看...
2、【业务依赖一些第三方框架,如FMDB等】
平时都是在工程中使用别人的开源框架,如FMDB,老实说,集成通过Pod方式来集成,就是舒服。在现在我需要我很多业务逻辑也需要依赖这些,我也想这样处理这一步。
现在Framework我制作好了。我要将Framework与AFNetworking/FMDB等,同时和我业务逻辑代码结合在一起。
我是需要把这些如FMDB等都下载下来,然后把业务逻辑结合吗🙄,后面假如别人使用你的代码,他的工程中也有FMDB呢,不就冲突了吗?发现有人说Xcode全局修改FMDB前缀等,要死的节奏吗🙄
大概的步骤:
这一步我们就可以在终端命令行中下载一个模板工程
然后把上面制作好的Framework文件和业务逻辑文件{.h和.m}文件添加到工程中,等等,AFNetworking/FMDB等第三方库咋办呢?
其实吧,模板工程中,有一个xxx.podspec的文件,在这个配置文件中,可以配置你的系统依赖库和第三方依赖框架的😄,配置好之后,就基本完成了。剩下的就是需要将这个文件push到一个远程服务器。然后就可以通过pod search xxx查找到了。
创建一个模板工程
pod lib create xxx
模板工程创建过程
模板工程结构如下:
文件目录结构
1、删除ReplaceMe.m,替换成自己的代码【用上面的Framework文件和其他代码替换掉】
替换文件
2、然后修改podspec文件,这个文件就是配置着你这个工程中需要开源出去的代码位置以及依赖系统库和第三方库的信息。所需要第三方依赖就是通过这个文件来配置的。
刚刚接触,我也不信,我配置了,但怎么知道就是我想要的那种Pod A 就导入 A 、B、C框架的形式呢,毕竟这些都是别人博客写着的,实际效果怎么样,假如没有试过的话,心虚虚的,老是觉得是不是错了,没有信心往下一个步骤进行了,毕竟刚刚接触,遇到了很多莫名其妙的异常,反正让你烦躁就是了
这个是我工程中的podspec文件,模板工程中有,自行修改一下
#
# Be sure to run `pod lib lint OMCDriveHelper.podspec' to ensure this is a
# valid spec before submitting.
Pod::Spec.new do |s|
s.name = 'DemoSDKSample'
s.version = '0.1.4'
s.summary = 'A short description of DemoSDKSample.'
s.description = <<-DESC
TODO: Add long description of the pod here,Add long description of the pod here.
DESC
s.homepage = 'https://github.com/baiwulong/DemoSDKSample'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'baiwulong' => '1204803180@qq.com' }
s.source = { :git => 'https://github.com/baiwulong/DemoSDKSample.git', :tag => s.version.to_s }
s.ios.deployment_target = '8.0'
#自己的逻辑代码
s.source_files = "DemoSDKSample/Classes/**/*.{h,m}"
#依赖自己的或别人的Framework文件
s.vendored_frameworks = 'DemoSDKSample/Classes/*.framework'
#系统依赖库
s.frameworks = 'UIKit', 'CoreLocation','Foundation'
#依赖第三方框架
s.dependency 'AFNetworking'
s.dependency 'Qiniu'
s.dependency 'FMDB'
end
修改好了之后呢,别急,终端前往Example文件,cd 模板工程中的Example
中执行Pod install
命令
cd 模板工程中的Example,Pod install
看到没有,是不是和平时常见的一样熟悉呢,原来依赖真是这样的添加的,毕竟以前没接触过,看别人的和自己亲自操作过一次,感觉不一样,😄(修改了podspec文件,假如需要看效果,就需要到Example中Pod install
一下,和个人感觉是和修改了podfile文件差不多)
pod install会自动导入相关的依赖
此时工程中的结构发生改变了,pod install就根据.podspec配置来给demo添加依赖,并且把配置目录中的代码制作成pod库目录,通过pod方式加载进入工程。
工程结构发生变化了
关于头文件调用的注意事项⚠️:
注意⚠️:Framework的代码,和一些{h.m}文件的头文件引用
假如是第三方
#import <xxx/xxx.h>,否者就是#import "xxx.h"
另外xxxFramework:
xxxFramework中的xxxFramework.h头文件中的暴露头文件的话,需要使用
#import < xxxFramework/A.h>
#import < xxxFramework/B.h>
#import < xxxFramework/C.h>
完成到这一步后,大部分工作都做好了,但还得继续...
为了能让代码和Framework可以pod方式导入到工程,还需要那几个步骤呢?
1、在GitHub上创建一个远程仓库,如我创建了一个DemoSDKSample的仓库
GitHub上创建仓库
下面基本是引用优秀博客的
创建好仓库后,就进行git操作就行了
把工程添加到仓库,打上标签tag ,这个tag对应podspec文件中的
如s.version = '0.1.0'
,那代码就需要打上一个tag为0.1.0
的标签tag,然后推送到远程仓库(终端自己使用git 命令来操作或使用sourcetree软件来操作都可以)
注意:远程仓库不需要创建gitignore文件,因为pod lib创建了
提交自己仓库代码到远程仓库
git init :初始化git
git status : 查看状态,如果有不想要的文件,可以用gitignore忽略掉
提交到本地缓存区 `git add .``
提交到本地仓库 git commit -m ''
查看远程仓库地址 git remote(查看有没有远程地址)
绑定远程地址 git remote add origin 远程仓库地址
推送自己代码到远程仓库 git push origin master
git tag -a 0.0.1 -m '0.0.1' :添加标签tag
git push --tags:推送本地标签到远程仓库中
注册trunk
* 注册trunk,不是任何人都能推送,因为cocoapods依赖trunk服务器管理,所以需要通过trunk推送自己的podspec([cocoapods官网](https://link.jianshu.com?t=https://blog.cocoapods.org/CocoaPods-Trunk/))
* 命令:`pod trunk register EMAIL [NAME]`
* pod trunk register [58999050@qq.com](https://link.jianshu.com?t=mailto:58999050@qq.com) yuanzheng
* 验证成功后,点击邮箱就好了,打开会有点慢.
推送自己的podspec到cocoapods的索引库
pod trunk push HttpManager.podspec --allow-warnings
- 注意:必须cd 进入到podspec目录下,才能执行这个代码
- 注意:podspec文件中的s.version版本号要跟最新Tag一致
- 注意:podspec文件中的s.source仓库地址也不能写错
测试能否索引到
pod search 自己仓库
发现索引不到,其实已经上传到cocoapods上了,只不过需要重新更新索引文件
怎么更新pod索引文件?
原理:pod setup成功后会生成~/Library/Caches/CocoaPods/search_index.json文件
把search_index.json文件文件删除,重新执行pod search,就会重新更新索引.
终端执行:
rm ~/Library/Caches/CocoaPods/search_index.json
pod search xxx
报错❌:
处理方法:pod trunk push DemoSDKSample.podspec --allow-warnings --use-libraries
(有引用框架时,需加入 --use-libraries)
- ERROR | [iOS] xcodebuild: Returned an unsuccessful exit code. You can use `--verbose` for more information.
报错❌:远程没有创建对应的tag标签
处理方法,添加远程对应的tag,然后重新执行
warning: Could not find remote branch 0.1.0 to clone.
fatal: Remote branch 0.1.0 not found in upstream origin
反正就是需要细心,需要耐性,有问题就网上找解决方法,
成功后的截图:
屏幕快照 2018-04-12 上午11.17.53.png
屏幕快照 2018-04-12 上午11.19.56.png
好多好文章,推荐:
教你如何从0到1实现组件化架构
SDK制作专题