背景:我们的项目之前进行了组件化拆分,登陆和个人中心以及基础网络请求抽离在一个模块里,摄像头模块,家模块。抽成的模块都以Framework的引入项目。这个可以提高编译速度,但是调试起来比较麻烦,大家一直想做成pod。最近一个项目要给合作商提供两个sdk,一个是设备接入,一个是设备控制,需要先把基础的网络请求以及一些工具类抽出来给大家用,但是之前的Framework还包含登陆,这些是sdk不需要的。
1.针对网络请求的Framework里包含太多登陆业务的问题,我本来想到的是把模块做成一个pod,然后里边分成两个subspec:网络请求和登陆。想法挺好,但是实施起来太糟心了。代码耦合严重,导致我拆了一天, pod最后一步验证一直出错,而且里边用了prefixHeader,导致拆分的时候解耦一个subspec太难了,最后我想到一个更好的办法:在原来的framework新建一个target:只把基础网络请求和工具类的部分包含进来,这样还是一份代码,打出来的framework里也不包含我们公司自己的登陆业务。完美!!
2.设备接入有蓝牙,wifi等不同模块,我们的想法是搞成一个pod,内部分多个subspec,这样别人想用哪个,直接pod install就可以了。因为不能暴露源码,所以需要先做成Framework,然后再让对应的framework支持pod。
1.如何让原有的组件支持cocoapod?大致分为以下几个步骤:
- 创建并设置一个私有的Spec Repo。
- 创建Pod的所需要的项目工程文件,并且有可访问的项目版本控制地址。
- 创建Pod所对应的podspec文件。
- 本地测试配置好的podspec文件是否可用。
- 向私有的Spec Repo中提交podspec。
- 在个人项目中的Podfile中增加刚刚制作的好的Pod并使用。
- 更新维护podspec。
创建并设置一个私有的Spec Repo。
spec repo 其实远端是一个git仓库,里边包含了很多spec文件。是当你使用了Cocoapods后他会被clone到本地的~/.cocoapods/repos目录下,这个是官方的repo
我们需要自己创建一个这样的仓库,如果公司之前没有这个仓库,需要在gitlab上新建一个远端仓库,然后把地址复制一下,在命令行输入:
# pod repo add [Private Repo Name] [GitHub HTTPS clone URL]
$ pod repo add WTSpecs https://coding.net/wtlucky/WTSpecs.git
执行完进入~/.cocoapods/repos 路径下就可以看到你刚刚创建的私有库
创建Pod的所需要的项目工程文件,并且有可访问的项目版本控制地址
这个是LMFramework,里边包含了登陆,个人中心,地区切换,网络请求等,我打算只把网络请求的部分做成pod,我更改了文件夹结构,把对应的部分放在一个文件夹里。由于这个本来就在内网的gitlab上,所以不用重新建git仓库了。
创建Pod所对应的podspec文件
cd到对应的目录下 执行命令
pod spec create LMFramework
然后开始编辑podspec,这个是一个ruby的文件
Pod::Spec.new do |spec|
spec.name = "LMFramework"
spec.version = "1.0.4"
spec.summary = "A short description of LMFramework."
spec.homepage = "一个可以访问到的地址,这个项目的主页"
spec.license = "MIT"
spec.author = { "jeremylu" => "jingya.lu-a1079@aqara.com" }
spec.platform = :ios, "10.0"
spec.source = { :git => "上一步的git地址", :tag => "#{spec.version}" }
//设置源码的地址,当前目录是podspec所在的路径
// *只遍历当前文件夹 **/*遍历当前文件夹以及子文件夹,
s.source_files = 'NetworkFramework/Classes/*.{h,m}'
//依赖的第三方库,多个的话,换行
spec.dependency 'AFNetworking','3.2.0'
//依赖的系统库:最好写上
spec.frameworks = 'Foundation','UIKit'
//项目里包含的framework
spec.vendored_frameworks = 'LMFramework/NetworkFramework/*.framework'
//buildingsetting里的配置
s.pod_target_xcconfig = { 'ENABLE_BITCODE' => 'NO' }
end
设置subspec可以看
这个文件写好后,执行命令
pod lib lint
来本地验证这个podspec文件是否有效
这一步出问题比较多,会报各种错误。
可以允许xcode building类型的warning,但是不允许有error。
pod lib lint --allow-warnings
这种错误
- ERROR | [iOS] xcodebuild: Returned an unsuccessful exit code.
一般没有详细信息,可以用
pod lib lint --verbose
来看详细的信息。
本地测试配置好的podspec文件是否可用。
自己建一个demo,然后设置podfile
source 'https://cdn.cocoapods.org/'
source 'http://git.aqara.com/root/APP_aqara_home_iOS_podspec.git'
platform :ios, '10.3'
inhibit_all_warnings!
target 'LoginDemo' do
//path以podfile的位置作为当前位置,设置源文件位置
pod 'LMFramework', :path => '~/LMFramework/NetworkFramework'
end
然后pod install,看下代码是否可以用,我第一次弄的时候是可以的,后来弄一直导入没成功,直接进行下一步也是可以的,这个主要是用来调试代码用的。
向私有的Spec Repo中提交podspec。
首先要把改动的代码都提交了,然后新建一个tag推送到远端。之后向repo中提交,只需要执行一个命令
$ pod repo push WTSpecs PodTestLibrary.podspec #前面是本地Repo名字 后面是podspec名字
完成之后这个组件库就添加到我们的私有Spec Repo中了,可以进入到~/.cocoapods/repos/WTSpecs目录下查看
至此,我们组件库就完成了。
在个人项目中的Podfile中增加刚刚制作的好的Pod并使用。
更新维护podspec。
每次想要发版本,需要先把代码都提交,然后打一个tag,执行命令
pod repo push WTSpecs PodTestLibrary.podspec
碰到的问题
framework如何支持pod?
podspec里设置对应的framework里的地址
s.vendored_frameworks = 'XRGcSDKPods/Classes/*.framework'
s.user_target_xcconfig = { 'ENABLE_BITCODE' => 'NO' }
#设置不支持bitcode
build failure
Ld .../Build/Intermediates.noindex/App.build/Release-iphonesimulator/App.build/Objects-normal/arm64/Binary/App normal arm64
答案看链接5.
frameworkA依赖FrameworkB,如何连调?
两个地方都要勾选,原因见这里
更新:
问题1: podspec文件验证时碰到这个错误。
pod lib lint TestSDK.podspec --allow-warnings --use-libraries
问题2:私有库B依赖私有库A,然后在demo工程podfile这么写
pod 'LMCameraFramework', :path => '../APPCameraFramework'
执行pod install,报错说找不到库A。
解决办法:在podfile里把库A的podsepc repo地址加上就好了。