iOS 组件化及framework开发经验

1,787 阅读3分钟

背景:我们的项目之前进行了组件化拆分,登陆和个人中心以及基础网络请求抽离在一个模块里,摄像头模块,家模块。抽成的模块都以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

image.png

我们需要自己创建一个这样的仓库,如果公司之前没有这个仓库,需要在gitlab上新建一个远端仓库,然后把地址复制一下,在命令行输入:

# pod repo add [Private Repo Name] [GitHub HTTPS clone URL]
$ pod repo add WTSpecs https://coding.net/wtlucky/WTSpecs.git

执行完进入~/.cocoapods/repos 路径下就可以看到你刚刚创建的私有库

image.png

创建Pod的所需要的项目工程文件,并且有可访问的项目版本控制地址

image.png 这个是LMFramework,里边包含了登陆,个人中心,地区切换,网络请求等,我打算只把网络请求的部分做成pod,我更改了文件夹结构,把对应的部分放在一个文件夹里。由于这个本来就在内网的gitlab上,所以不用重新建git仓库了。

创建Pod所对应的podspec文件

cd到对应的目录下 执行命令

pod spec create LMFramework

image.png 然后开始编辑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文件是否有效

image.png 这一步出问题比较多,会报各种错误。 可以允许xcode building类型的warning,但是不允许有error。 pod lib lint --allow-warnings 这种错误 - ERROR | [iOS] xcodebuild: Returned an unsuccessful exit code. 一般没有详细信息,可以用 pod lib lint --verbose来看详细的信息。

本地测试配置好的podspec文件是否可用。

自己建一个demo,然后设置podfile

image.png

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目录下查看

image.png

至此,我们组件库就完成了。

在个人项目中的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,如何连调?

image.png

两个地方都要勾选,原因见这里

更新:

问题1: podspec文件验证时碰到这个错误。

image.png

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地址加上就好了。

参考链接:

  1. framework如何上传cocoaPod

  2. 使用Cocoapods创建私有podspec

  3. podfile的语法

  4. framework可以构建多个target:简版和标准版本

  5. podspec验证不通过