×

使用私有Cocoapods仓库 中高级用法

96
DreamTracer
2016.10.25 15:20* 字数 2021

上一篇文章《使用私有Cocoapods仓库》讲解了创建私有pod的初步教程,接下来我们提升一下难度。


需求如下:

  1. 使用私有spec仓库
  2. 创建私有pods
  3. 私有pods依赖第三方静态库(.a , .framework)
  4. 私有pods依赖第三方pods
  5. 私有pods依赖另外的私有pods

依赖关系如下:

  • NCKUIKit(私有pod)
    • SDWebImage(依赖的第三方pod)
    • BaiduMap.framework(手动引入的第三方framework)
    • NCKFoundation(依赖的私有pod)
      • AFNetworking(依赖的第三方pod)
      • libWechat.a(手动引入的第三方framework)

Github上的仓库列表如下:

  • NCKSpecs
  • NCKUIKit
  • NCKFoundation

为了方便读者的调试,此次的仓库都是基于github的。


创建3个仓库

1.创建/使用已有NCKSpecs仓库

如果没有在github上新建一个仓库,
如果有该仓库则直接在终端输入一下命令即可。

pod repo add NCKSpecs https://github.com/NicolasKim/NCKSpecs.git

以上命令会把github上的NCKSpecs仓库克隆到本地。执行一下命令查看本地的pods仓库:

pod repo

2.创建NCKFoundation仓库

在github创建NCKFoundation仓库

3.创建NCKUIKit仓库

在github创建NCKUIKit仓库


编写 NCKFoundation pods

1. 创建NCKFoundation pods以及DEMO工程

切换到需要的目录下执行一下命令:

pod lib create NCKFoundation

以上命令会在你指定的目录下,根据cocoapods的pods模板生成一个pods工程,包含pods以及demo工程,先不要着急打开工程。文件目录如下:


在终端进入到Example目录下

pod install

这时会看到Example目录下会生成一个workspace文件

双击打开工程,工程目录如下:

把replaceme删除掉,Classes下新建一个类NCKRootObject
编辑NCKFoundation.podspec文件,里面有一堆东西,先全部删除掉,并粘贴如下代码:

Pod::Spec.new do |spec|
  spec.name             = 'NCKFoundation'
  spec.version          = '1.0'
  spec.summary          = 'Guide for private pods :'
  spec.description      = <<-DESC
                       Guide for private pods
                       DESC
  spec.homepage         = 'https://github.com/NicolasKim/'
  spec.license          = { :type => 'MIT', :file => 'LICENSE' }
  spec.author           = { 'NicolasKim' => 'jinqiucheng1006@live.cn' }
  spec.source           = { :git => 'https://github.com/NicolasKim/NCKFoundation.git', :tag => spec.version.to_s }
  spec.ios.deployment_target = '8.0'
  spec.source_files = 'NCKFoundation/Classes/*.{h,m}'

end

到podfile的目录下执行命令

pod install

他会根据spec文件,将NCKRootObject跟demo工程进行链接

先做一下参数说明:

spec可以看做是一个对象实例,有很多属性如下:

name:顾名思义就是pod的名字,当我们使用pod search xxxx时,xxx就是name。

version : pod 的版本 也就是我们再podfile里指定的那个版本。

summary:概要说明

description:pod的描述。

source:远程仓库的地址以及tag版本

ios.deployment_target:ios部署版本
osx.deployment_target:osx部署版本

source_files: 需要编译文件的文件目录,注意是文件目录而不是工程目录

2.检查

在上传到git仓库之前,做一下检查:
在NCKViewcontroller中

#import "NCKRootObject.h"

不报错说明source_files指定的目录没有问题。

接下来用pod的命令检查一下。

后退到podspec文件存在的目录下,输入一下命令:

pod lib lint

如果因为有无关紧要的警告而未通过检查,则输入一下命令:

pod lib lint --allow-warnings

检查时pod会忽略警告。如果出现一下提示,你懂得,已经成功一大半了。

NCKFoundation passed validation.

接下来远程检查pods,这次cocoapods会根据podspec文件里的source 检查对应的仓库里有没有指定tag的仓库。显然我们还没有将NCKFoundation 上传到github的NCKFoundation仓库里,可定会报错,执行试一下。

pod spec lint
-> NCKFoundation (1.0)
    - WARN  | description: The description is shorter than the summary.
    - ERROR | [iOS] unknown: Encountered an unknown error ([!] /Applications/Xcode.app/Contents/Developer/usr/bin/git clone https://github.com/NicolasKim/NCKFoundation.git /var/folders/6x/8pyfnj_n4573cq4206yjz41c0000gn/T/d20161017-14130-148x77b --template= --single-branch --depth 1 --branch 1.0

Cloning into '/var/folders/6x/8pyfnj_n4573cq4206yjz41c0000gn/T/d20161017-14130-148x77b'...
fatal: Remote branch 1.0 not found in upstream origin
) during validation.

Analyzed 1 podspec.

[!] The spec did not pass validation, due to 1 error and 1 warning.

根据错误得出,对应的仓库里没有1.0的分支。

3.上传NCKFoundation

那我们就将工程上传的github上,并创建1.0的tag。
上传方式自行解决,网上有很多可视化工具,比如sourcetree。

上传结束后再检查一下:

pod spec lint --allow-warnings

这次应该没有问题了吧?

好,还没完,接下来我们把podspec文件上传的我们自己的spec仓库里,而不是cocoapods的仓库。

pod repo push NCKSpecs NCKFoundation.podspec --allow-warnings

cocoapods会把podspec文件上传到NCKSpecs仓库中。
好现在去你的github看看spec仓库。

4.使用私有pods

新建一个工程,TestNCKFoundationPod
终端进入该目录,新建Podfile。
在第一行加入如下代码:

source 'https://github.com/NicolasKim/NCKSpecs.git'

意思就是当搜索或者下载pods的时候默认从NCKSpecs.git中获得信息。
也就是说,我们从Cocoapods的spec仓库移到我们自有的spec仓库。之后就是正常的pods使用方法。

target 'TestNCKFoundationPod' do
  pod 'NCKFoundation', '~> 1.0'
end
pod install

试图引入NCKRootObject.h并运行测试工程。

5. 添加afnetworking 和 微信的依赖

先从微信开放平台下载微信sdk
在NCKFoundation/NCKFoundation/Classes 目录下创建ThirdParty文件夹,并将.a和.h文件拖到ThirdParty文件夹下。(注意不要拖到工程目录下,而是文件目录)
在podspec文件里修改source_file 为

spec.source_files = 'NCKFoundation/Classes/*.{h,m}', 'NCKFoundation/Classes/ThirdParty/*.{h}'

添加.a静态库的依赖,.a依赖的系统framework以及library

spec.vendored_libraries  = 'NCKFoundation/Classes/ThirdParty/*.{a}'
spec.frameworks = 'SystemConfiguration','CoreGraphics','CoreTelephony','Security','CoreLocation','JavaScriptCore'
spec.libraries  = 'iconv','sqlite3','stdc++','z'

参数说明

vendored_libraries: 第三方.a文件

frameworks: 该pod依赖的系统framework

libraries: 该pod依赖的系统library

添加AFNetworking的依赖

spec.dependency   'AFNetworking', '~> 3.1.0'

参数说明

dependency : 该pod依赖的pod

pod install

之后看一下工程目录

在Example里的NCKViewController里#import "WXApi.h"
运行工程看看报不报错。

6.制作subspec

先说一下subspec是什么
在终端搜索一下sdwebimage,结果如下

也就是说我们再使用sdwebimage时不用下载全部的组件,喜欢用哪个就下哪个,由此得出subspec可以生成一个子模块儿,当然这需要我们再编码的过程中减少模块儿之间的依赖,使各个模块儿可以独立运行。

好!接下来我们试着做一个子模块儿
在工程目录下 新建文件夹NCKSub(并生成对应的文件目录) 新建一个类NCKChild,并在podspec文件里添加如下代码:

spec.subspec 'NCKSub' do |cs|
       cs.source_files = 'NCKFoundation/Classes/NCKSub/*.{h,m}'
  end

参数说明:

NCKSub : subspec的名字 可以随意起名

cs : 为变量名 与spec类似 拥有spec用的所有属性 可以随意起名

执行

pod install

观察一下工程目录,并运行。还顺利吗?

接下来我们准备升级pods的版本

将podspec的version 改为2.0

然后执行

pod lib lint --allow-warnings

将NCKFoudation push至远程仓库并新建2.0的tag
将podspec push至私有的spec仓库中

pod repo push NCKSpecs NCKFoundation.podspec --allow-warnings

搜索一下

pod search NCKFoundation

结果如下:

我们去TestNCKFoundationPod 这个工程中修改一下Podfile为

source 'https://github.com/NicolasKim/NCKSpecs.git'
source 'https://github.com/CocoaPods/Specs.git'
target 'TestNCKFoundationPod' do
  pod 'NCKFoundation', '~> 2.0'
end

因为在私有的pod中依赖了另外的pod(afnetworking)afnetworking的spec文件是在cocoapods的仓库里 所以要添加一个cocoapods的spec仓库地址。

pod install

看一下工程目录:

NCKFoundation pods制作完毕!


编写 NCKUIKit pods

新建NCKUIKit pods 步骤与NCKFoundation一样 进入指定目录
直接在终端里输入

pod lib create NCKUIKit

到Example目录下pod install
打开工程编辑podspec文件

Pod::Spec.new do |spec|
  spec.name             = 'NCKUIKit'
  spec.version          = '1.0'
  spec.summary          = 'A short description of NCKUIKit.'

  spec.description      = <<-DESC
                       Add long description of the pod here.
                       DESC

  spec.homepage         = 'https://github.com/NicolasKim/NCKUIKit'
  spec.license          = { :type => 'MIT', :file => 'LICENSE' }
  spec.author           = { 'NicolasKim' => 'jinqiucheng1006@live.cn' }
  spec.source           = { :git => 'https://github.com/NicolasKim/NCKUIKit.git', :tag => spec.version.to_s }
  spec.ios.deployment_target = '8.0'
  spec.source_files = 'NCKUIKit/Classes/*.{h,m}'
  spec.dependency 'SDWebImage', '~> 3.8.2'
end

关联Baidumap.framework

去百度地图官网下载framework
目录如下

将整个文件夹拖到Classes目录下

然后编辑podspec如下

Pod::Spec.new do |spec|
  spec.name             = 'NCKUIKit'
  spec.version          = '1.0'
  spec.summary          = 'A short description of NCKUIKit.'

  spec.description      = <<-DESC
                       Add long description of the pod here.
                       DESC

  spec.homepage         = 'https://github.com/NicolasKim/NCKUIKit'
  spec.license          = { :type => 'MIT', :file => 'LICENSE' }
  spec.author           = { 'NicolasKim' => 'jinqiucheng1006@live.cn' }
  spec.source           = { :git => 'https://github.com/NicolasKim/NCKUIKit.git', :tag => spec.version.to_s }
  spec.ios.deployment_target = '8.0'
  spec.source_files = 'NCKUIKit/Classes/*.{h,m,mm}'
  spec.dependency 'SDWebImage', '~> 3.8.2'
  spec.vendored_frameworks = ['NCKUIKit/Classes/BaiduMap_IOSSDK_v3.0.0_Lib/BaiduMapAPI_Base.framework',
                              'NCKUIKit/Classes/BaiduMap_IOSSDK_v3.0.0_Lib/BaiduMapAPI_Location.framework',
                              'NCKUIKit/Classes/BaiduMap_IOSSDK_v3.0.0_Lib/BaiduMapAPI_Map.framework',
                              'NCKUIKit/Classes/BaiduMap_IOSSDK_v3.0.0_Lib/BaiduMapAPI_Search.framework',
                              'NCKUIKit/Classes/BaiduMap_IOSSDK_v3.0.0_Lib/BaiduMapAPI_Utils.framework']
  spec.resource_bundles = {'Resources' => 'NCKUIKit/Classes/BaiduMap_IOSSDK_v3.0.0_Lib/BaiduMapAPI_Map.framework/Resources/mapapi.bundle'}
  spec.frameworks = 'CoreLocation','QuartzCore','OpenGLES','SystemConfiguration','CoreGraphics','Security','CoreTelephony'
  spec.libraries = 'sqlite3.0', 'stdc++.6.0.9'
#spec.user_target_xcconfig =   {'OTHER_LDFLAGS' => ['-lObjC','-all_load']}

end

参数说明:

vendored_frameworks: 第三方framework

pod_target_xcconfig: build setting的配置

关联私有pod NCKFoundation

继续编辑podspec文件,如下:

Pod::Spec.new do |spec|
  spec.name             = 'NCKUIKit'
  spec.version          = '1.0'
  spec.summary          = 'A short description of NCKUIKit.'

  spec.description      = <<-DESC
                       Add long description of the pod here.
                       DESC

  spec.homepage         = 'https://github.com/NicolasKim/NCKUIKit'
  spec.license          = { :type => 'MIT', :file => 'LICENSE' }
  spec.author           = { 'NicolasKim' => 'jinqiucheng1006@live.cn' }
  spec.source           = { :git => 'https://github.com/NicolasKim/NCKUIKit.git', :tag => spec.version.to_s }
  spec.ios.deployment_target = '8.0'
  spec.source_files = 'NCKUIKit/Classes/*.{h,m,mm}'
  spec.dependency 'SDWebImage', '~> 3.8.2'
  spec.vendored_frameworks = ['NCKUIKit/Classes/BaiduMap_IOSSDK_v3.0.0_Lib/BaiduMapAPI_Base.framework',
                              'NCKUIKit/Classes/BaiduMap_IOSSDK_v3.0.0_Lib/BaiduMapAPI_Location.framework',
                              'NCKUIKit/Classes/BaiduMap_IOSSDK_v3.0.0_Lib/BaiduMapAPI_Map.framework',
                              'NCKUIKit/Classes/BaiduMap_IOSSDK_v3.0.0_Lib/BaiduMapAPI_Search.framework',
                              'NCKUIKit/Classes/BaiduMap_IOSSDK_v3.0.0_Lib/BaiduMapAPI_Utils.framework']
  spec.resource_bundles = {'Resources' => 'NCKUIKit/Classes/BaiduMap_IOSSDK_v3.0.0_Lib/BaiduMapAPI_Map.framework/Resources/mapapi.bundle'}
  spec.frameworks = 'CoreLocation','QuartzCore','OpenGLES','SystemConfiguration','CoreGraphics','Security','CoreTelephony'
  spec.libraries = 'sqlite3.0', 'stdc++.6.0.9'
#spec.user_target_xcconfig =   {'OTHER_LDFLAGS' => ['-lObjC','-all_load']}
  spec.dependency 'NCKFoundation'
end

podspec文件编辑完毕,先不要着急 pod install
现在pod install 肯定找不到 NCKFoundation 所以我们需要在里Podfile一下 source
编辑Podfile如下:

use_frameworks!

source 'https://github.com/NicolasKim/NCKSpecs.git'
source 'https://github.com/CocoaPods/Specs.git'


target 'NCKUIKit_Example' do
  pod 'NCKUIKit', :path => '../'

  target 'NCKUIKit_Tests' do
    inherit! :search_paths

    pod 'FBSnapshotTestCase'
  end
end
pod install

这是会从私有仓库https://github.com/NicolasKim/NCKSpecs.git 下载NCKFoundation 并配置到工程。

把NCKUIKit push到私有仓库里。(请自行解决)

接下来检查一下podspec文件

注意 : NCKUIKit的检查与NCKFoundation的检查稍微有点儿区别,因为NCKUIKit 依赖了NCKFoundation,同时NCKFoundation 是私有仓库里的pod ,所以我们检查是需要指定source。一个为cocoapods的source 另一个为私有spec仓库的source

pod lib lint --sources=https://github.com/NicolasKim/NCKSpecs.git,https://github.com/CocoaPods/Specs.git --allow-warnings

检查通过后直接把spec文件push到私有spec仓库里。

注意:push时默认会检查 spec文件 所以同样需要提供source

pod repo push NCKSpecs NCKUIKit.podspec --sources=https://github.com/NicolasKim/NCKSpecs.git,https://github.com/CocoaPods/Specs.git --allow-warnings

将 TestNCKFoundationPod 的podfile改成如下:

target 'TestNCKFoundationPod' do
  pod 'NCKUIKit'
end
pod install

NCKFoundation pods制作完毕!

感谢您的耐心观看,如果您觉得这篇文章有帮助,请您高台贵指点一下喜欢就可以了。

技术分享
Web note ad 1