平时我们项目开发会抽离一些公共模块,那么这些公共模块如何管理呢,呵呵,搭建CocoaPods私有库来去管理是最好不过了. 由于之前工作忙没时间整理,最近正好有些闲暇时间,我就抛砖引玉,搭建一个简单示例,顺便梳理一下流程.
首先是环境搭建,我采用docker里面部署一个gitlab来作为私有库仓库,然后拿一个示例项目拆分出公共模块,接着我会把公共模块打包成pod,最后到项目中引用
一 Docker安装
二 部署gitlab
三 创建CocoaPods私有库
四 更新私有库
五 问题总结
一 Docker安装
Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker,就不用担心环境问题。
总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。总之类似于我们使用的虚拟机,只能说很行,但是它不是,就是一个环境隔离工具,类似于iOS的沙盒, 关于Docker的使用我不到赘述,感兴趣的可以找相关资料,我这里只用了很少一部分,很简单.
步骤1 Docker下载地址https://www.docker.com/get-started
步骤2 我的是Mac环境,我下载的是.dmg,双击下载好的xx.dmg安装,安装好后是下面的界面
右上角的小鲸鱼就正在运行的Docker,下面我们来验证一下Docker是否安装好
步骤3 验证Docker环境
OK Docker环境搭建就是如此简单,接下来我们来部署gitlab
二 部署gitlab
步骤 1 在电脑机器上找一个目录新建一个文件夹
步骤 2 在新建的目录内新建一个文件docker-compose.yml,名字不要改,这是一个docker编排文件,我们将要用docker-compose工具来部署它
步骤 3 编辑docker-compose.yml文件内容,并保存,下面是文件内容
version: '3'
services:
web:
image: 'twang2218/gitlab-ce-zh'
restart: always
hostname: '127.0.0.1'
environment:
TZ: 'Asia/Shanghai'
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://127.0.0.1'
gitlab_rails['gitlab_shell_ssh_port'] = 2222
unicorn['port'] = 8888
nginx['listen_port'] = 80
ports:
- '8088:80'
- '2443:443'
- '2222:22'
volumes:
- ./config:/etc/gitlab
- ./data:/var/opt/gitlab
- ./logs:/var/log/gitlab
步骤 4 终端切换到这个文件所在目录下,执行如下命令
docker-compose up -d
文件大会下载一会,如果你网速不好失败了,那就在重新执行这个命令,当运行完成后,我们载查看下是否部署好了
步骤 5 执行命令查看容器是否创建运行
docker ps | grep twang
步骤 6 访问gitlab: http://127.0.0.1:8088/
OK出现这个页面我们gitlab就搭建好了,我们可以注册账号(自行操作吧)登陆进去了,接下来就开始我们的私有库创建了
三 创建CocoaPods私有库
在操作之前,我们先看一下我们即将要改造的项目大致结构
演示项目本身就是用CocoaPods管理的,因为我引用了一些第三方库,下面我就要把红框圈出来的公共模块拿出来,放到私有pod里面,接下来我们按步骤一步一步来操作
首先要先区分俩概念:
Code Repository:比如我开发了一个功能模块Tools,源码文件是保存到Code Respository的,就是我们平时用的git仓库。
Specs Repository:针对Tools会有一个Tools.podspec文件用来配置Tools的发布的,保存podspec文件的仓库就是Specs Repository。它保存了所有要发布的组件的podspec文件,仅用来配置,叫配置仓库。
总结一下,我们就需要创建两个仓库,一个方pod代码,一个来放podspec配置
步骤 1:创建代码仓库Code Repository
登陆上gitlab,我们点击新建项目,然后输入项目名称,勾选README,不勾选不会自动创建master分支,最后点create project创建项目
步骤 2:checkout Code Repository仓库到本地~/swifttoolspod中,然后往该文件夹中添加如下内容:
拉取代码仓库
本地文件夹要添加的内容
说明:
①其中Classes为文件夹,用来存储组件的源码,这里我示例项目Tools目录下的文件拷贝了过来如图。
②SwiftTools.podspect为当前这个组件的pod描述我们可以通过
pod spec create SwiftTools
命令来生成.podspect模版文件
我们这里的文件内容如下
Pod::Spec.new do |spec|
spec.name = "SwiftTools"
spec.version = "1.0.3"
spec.summary = "SwiftTools 项目常用的工具库"
spec.description = <<-DESC
swift 项目常用工具库
DESC
spec.homepage = "http://lerpo.github.io"
spec.license = { :type => "MIT", :file => "LICENSE" }
spec.author = { "xml" => "" }
spec.platform = :ios
spec.ios.deployment_target = "10.0"
spec.source = { :git => "http://127.0.0.1:8088/xml/tools.git", :tag => "#{spec.version}" }
spec.source_files = "Classes", "Classes/**/*.{swift}"
spec.exclude_files = "Classes/Exclude"
spec.dependency 'HandyJSON', '~> 5.0.1'
spec.dependency 'SwiftyJSON'
spec.dependency 'Alamofire', '~> 5.1'
spec.dependency 'MJRefresh'
spec.dependency 'MBProgressHUD', '~> 1.2.0'
end
3 LICENSE 文件,我们在代码仓库主页,点击添加许可证,然后选择MIT,最后保存提交,LICENSE文件就生成了,最后我们把这个文件更新到本地仓库
步骤 3:验证SwiftTools.podspec,终端进入到SwiftTools.podspec所在目录执行如下命令
pod lib lint --allow-warnings
如果出现SwiftTools passed validation,就代表验证通过,如果出现[!] SwiftTools did not pass validation, due to 3 errors.,就代表没通过验证,你要根据错误❌提示来修改,但所有验证通过后,我们就可以进行下一步了
步骤 4:将~/swifttoolspod内添加的四样内容推送到gitlab上
我这是推送过的,如果是第一次也是一样,代码推送到仓库里后,我们接下来要打标签tag
步骤 5:给代码仓库创建tag , tag名要和上面podspec文件中spec.version的值一致。
这种操作很简单,就是给仓库打tag,唯一要注意⚠️的是tag名要和上面podspec文件中spec.version的值一致 OK代码仓库这边我们已经配置完了,接下来我们配置Specs Repository仓库
步骤 6: 创建配置仓库Specs Repository
跟创建代码仓库一样,在gitlab上创建一个仓库命名为Specs,这个仓库用来保存.podspec文件。空仓库需要创建一个README文件,因为gitlab在空仓库中是没有分支的,加个README让其自动创建master分支
步骤 7: 配置仓库checkout到本地~/podspec,注意⚠️使用的是pod的命令,不是git clone
pod repo add SwiftTools http://127.0.0.1:8088/mengliang/Specs.git
步骤 8:将SwiftTools.podspec添加到配置仓库
在代码仓库checkout的路径~/podspec下面打开Terminal,执行push命令
pod repo push Specs ../swifttoolspod/SwiftTools.podspec --allow-warnings
上面命令是将当前目录(/podspec)下的SwiftTools.podspec文件推送到/.cocoapods/repos目录下SwiftTools文件夹对应的远程仓库中
就像下面出现绿色提示就代表推送成功
macbookdeMacBook-Pro:podspec mac$ pod repo push Specs ../swifttoolspod/SwiftTools.podspec --allow-warnings
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin19/rbconfig.rb:229: warning: Insecure world writable dir /usr/local/sbin in PATH, mode 040777
Validating spec
-> SwiftTools (1.0.3)
- WARN | description: The description is shorter than the summary.
- WARN | url: There was a problem validating the URL http://lerpo.github.io.
- WARN | [iOS] swift: The validator used Swift `4.0` by default because no Swift version was specified. To specify a Swift version during validation, add the `swift_versions` attribute in your podspec. Note that usage of a `.swift-version` file is now deprecated.
- NOTE | xcodebuild: note: Using new build system
- NOTE | [iOS] xcodebuild: note: Planning build
- NOTE | [iOS] xcodebuild: note: Constructing build description
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'MJRefresh' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'SwiftyJSON' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'MBProgressHUD' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'HandyJSON' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'Alamofire' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'SwiftTools' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'Pods-App' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'App' from project 'App')
- NOTE | [iOS] xcodebuild: warning: Skipping code signing because the target does not have an Info.plist file and one is not being generated automatically. (in target 'App' from project 'App')
Updating the `Specs' repo
Adding the spec to the `Specs' repo
- [Fix] SwiftTools (1.0.3)
Pushing the `Specs' repo
[!] 'SwiftTools' uses the unencrypted 'http' protocol to transfer the Pod. Please be sure you're in a safe network with only trusted hosts. Otherwise, please reach out to the library author to notify them of this security issue.
OK 万事具备了,我们开始在项目中使用了
步骤 9:使用私有库,项目配置profile文件
总共三步操作,仔细看我图上的标示,接下来更新库
步骤 10:进入到项目的根目录执行命令
pod install
更新完依赖库,我们就可以运行项目了, 接下来我们看一下我们更新了私有库我们该如何操作
四 更新私有库
步骤 1 修改私有库Code Repository源码后,我们要修改.podspec描述文件,尤其要改版本号
步骤 2验证文件有效性
步骤 3验证通过后推送到gitlab代码仓库
步骤 4给仓库打个标签,注意⚠️tag要跟.podspec描述文件里面的版本号一致
步骤 5 更新podspec Specs Repository仓库,切换到本地Specs Repository仓库执行下面的命令
macbookdeMacBook-Pro:podspec mac$ pod repo push Specs ../swifttoolspod/SwiftTools.podspec --allow-warnings
macbookdeMacBook-Pro:podspec mac$ pod repo push Specs ../swifttoolspod/SwiftTools.podspec --allow-warnings
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin19/rbconfig.rb:229: warning: Insecure world writable dir /usr/local/sbin in PATH, mode 040777
Validating spec
-> SwiftTools (1.0.3)
- WARN | description: The description is shorter than the summary.
- WARN | url: There was a problem validating the URL http://lerpo.github.io.
- WARN | [iOS] swift: The validator used Swift `4.0` by default because no Swift version was specified. To specify a Swift version during validation, add the `swift_versions` attribute in your podspec. Note that usage of a `.swift-version` file is now deprecated.
- NOTE | xcodebuild: note: Using new build system
- NOTE | [iOS] xcodebuild: note: Planning build
- NOTE | [iOS] xcodebuild: note: Constructing build description
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'MJRefresh' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'SwiftyJSON' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'MBProgressHUD' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'HandyJSON' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'Alamofire' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'SwiftTools' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'Pods-App' from project 'Pods')
- NOTE | [iOS] xcodebuild: note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'App' from project 'App')
- NOTE | [iOS] xcodebuild: warning: Skipping code signing because the target does not have an Info.plist file and one is not being generated automatically. (in target 'App' from project 'App')
Updating the `Specs' repo
Adding the spec to the `Specs' repo
- [Fix] SwiftTools (1.0.3)
Pushing the `Specs' repo
[!] 'SwiftTools' uses the unencrypted 'http' protocol to transfer the Pod. Please be sure you're in a safe network with only trusted hosts. Otherwise, please reach out to the library author to notify them of this security issue.
成功后进入下一步操作
步骤 6 修改项目profile文件
步骤 7 在项目根目录执行
pod install
步骤 8 运行项目
总结:如果项目再更新,那就循环往复这8个步骤,我们可以看到这些步骤很多很繁琐,借助CI/CD这些都可以自动化操作(这个有时间再搞,大致就是docker部署jenkins,然后写python脚本执行上面的步骤操作,最后建个job构建)
五 问题总结
1 pod代码问题
我们从项目抽离出来的代码放到私有pod仓库,由于swift文件权限问题,并不能什么都不改就能直接引入到项目中使用. 我们需要修改文件权限. 这可是工作量很大的工作,做过你就知道了. 所以项目模块化是很耗费精力的
遇到的权限问题,主要是你的方法要不要公开,允不允许别人重写
open:公开的,内部外部模块都可访问,这个开放性最大;public:也是公开的,但还是与open有所区别。
open与public区别:public在只能限制在定义所在模块内部进行继承与方法的重写,而open则是只要模块有被import,在可在此模块中继承或者重写被import进来的模块中的类或方法。
2 项目引用问题
引入私有库,在用法到私有库的地方别忘了导入头文件
最后我们再扩展一下,如果我有好多个公共库我们该如何管理, 这些公共库如果有项目依赖怎么办??? 欢迎大家一起讨论
最后的最后我把示例代码贴出来:
项目代码:https://github.com/lerpo/swiftproject/branches/all
项目运行起来的示例图给大家来一张,都是美女噢😯