CocoaPods开发静态库并建立Podspec

96
wo不懂
16.8 2018.03.27 10:16* 字数 2766

1.Github 

     创建自己的Repository,我创建了SDKLib,然后从本地上传到github上, 这些步骤就不在这里赘述了,经常跑github的同学应该都会。

2 基于pod命令创建SDK 

 具体的pod命令如下:

pod lib create  SDKLib

调用以后terminal中会需要填写以下问题,一般选择创建Demo,其他选项根据需求填写:

What languagedoyou want to use??[ Swift / ObjC ] 

> ObjC

Would you like toincludea demo application with your library? [ Yes / No ]

 > YES

Which testing frameworks will you use? [ Specta / Kiwi / None ] 

> None

Would you like todoview based testing? [ Yes / No ] 

> Yes

What is yourclassprefix?

>SDK

第二种:(使用xcode手动创建静态库,网上比较多的版本,需要做一些配置,这里个人觉得太不方便,如果喜欢xcode自己创建的可以参考这篇https://www.jianshu.com/p/e588bb0411d8)费力不讨好的工程

3.建tag

 打开终端,cd 到项目SDKLib目录下,

 git tag '1.0.0'//这个命令是本地创建tag,1.0.0版本

git push --tags // 这个命令是把tag推送到远端。

4.创建项目的podspec文件

现在终端还是在项目QShare的目录下,执行以下命令

$ pod spec createSDKLib

在本地目录下同时也生成了SDKLib.podspec文件

打开项目可以开到工程里都给你配置好了 画的地方就是你开发自己静态库文件编码的地方(怎么打包成静态库,请往下看)这里因为特殊原因,一些文件不能展开

$ vim SDKLib.podspec

编辑podspec文件,会发现这个文件已经生成了部分的字段

以下是编辑好的podspec 文件 做一些解释

Pod::Spec.new do |s|

s.name = 'SDKLib'

s.version = '0.4.9'

s.summary = 'A short description of SDKLib.'

s.platform = :ios

s.homepage = 'https://github.com/wangxiaokui'# 

s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2's.license = { :type => 'MIT', :file => 'LICENSE' }

s.author = { 'xiaokui' => 'm18736056517@163.com' }

s.source = { :git => 'https://github.com/xiaokui/SDKLib.git', :tag => s.version}

#s.source = { :git => '/Users/fan/SDKLib' }   #加载本地自己的库的引用

# s.social_media_url = 'https://twitter.com/'

s.ios.deployment_target = '8.0'

s.source_files = 'SDKLib/Classes/**/*'

s.resource_bundles = {

'SDKLib' => ['SDKLib/Assets/*.png']

}

#s.public_header_files = 'Pod/Classes/**/*.h'

#s.frameworks = 'SystemConfiguration','MobileCoreServices','CoreGraphics','UIKit','AVFoundation','Photos','AdSupport','GLKit','MediaPlayer','MessageUI','CoreMotion','CoreTelephony'

s.dependency 'MBProgressHUD'

s.dependency 'MJExtension'

s.dependency 'SDWebImage'

s.dependency 'Masonry'

s.dependency 'MJRefresh'

s.dependency 'SVProgressHUD'

s.dependency 'Google-Mobile-Ads-SDK'

end

podspec中重要的几个内容解释如下:

s.source中是表示使用pod package打包时候pod去寻找的打包的路径,podspec默认使用git commit tag作为路径,也可以修改成本地路径/Users/pp/Desktop/MyCustomLib,如果当前没有设置:tag,打包时候默认使用当前git commit的head节点(如果部分修改内容没有commit,那么使用git package不会将未commit的内容进行打包).

s.source_files表示具体的源码的路径,这里注意源码一般放到Classes文件夹目录下,而且实体文件中不要有非源码内容放到Classes文件夹.Classes文件夹的所有内容都要Add Targets To: MyCustomLib.不要Classes文件夹或子文件夹中部分内容被remove referrence.

s.resource_bundles中的资源.系统会自动将MyCustomLib/Assets文件夹下的内容,cocoapod会将我们把Assets中的内容自动打包成MyCustomLib.bundle.这里也可以使用简单的方式

1 在Assets文件夹中放入我们自己写好的MyCustomLib.bundle,bundle中是我们使用的资源.

2 使用s.resource = 'MyCustomLib/Assets/*'.最后会将这些资源打入framework中.

3 在Example中手动引用我们自己创建的*.bundle资源文件.

s.public_header_files用来指定需要对外部暴露的头文件的位置

s.frameworks和s.libraries,表示当前sdk依赖的系统的framework和类库

s.dependency表示当前podspec类库对外部第三方库的依赖.如果使用pod package打包sdk时候,这里的dependency会被自动添加前缀,防止重复引用冲突.而且这里的依赖只能是pod库(公有或者私有)的内容.

s.subspec用来引入我们sdk依赖的自己的framework或者.a等静态库

特别注意在.podspec 操作了s.dependency依赖了一些库了后,就不需要再同一工程里使用podfile文件再次pod这些库了,它们会冲突,同时需要理解.podspec 里一些配置的意思相信会解决你不少问题

编辑好podspec文件后,需要验证一下这个文件是否能通过编译。

$ pod spec lint SDKLib.podspec --verbose

然而并没有通过

- ERROR | [iOS] Encountered an unknown error (The'Pods'target has transitive dependencies that include static binaries: 

找了一些相关的,这个错误是因为依赖库(s.dependency)包含了.a静态库造成的。虽然这并不影响Pod的使用,但是验证是无法通过的。可以通过 --use-libraries 来让验证通过。使用以下的命令:

$ pod spec lint QShare.podspec --verbose --use-libraries

这种情况下使用 --use-libraries 虽然不会出现错误(error),但是有时候会带来一些警告(waring),警告同样是无法通过验证的。这时可以用 --allow-warnings 来允许警告。

$ pod spec lint QShare.podspec --verbose --use-libraries --allow-warnings

这里针对自己的项目情况判断添加那些命令通过了。

5、提交到pod (使用git命令,打上tag再次提交,版本号每次需要更新哦)这里不多说了

发布时也会验证 Pod 的有效性,如果你在手动验证 Pod 时使用了 --use-libraries 或 --allow-warnings 等修饰符,那么发布的时候也应该使用相同的字段修饰,否则出现相同的报错。

发布成功后,

终于可以使用 pod search 搜索到自己的 Pod 了。

➜fan pod search SDKLib

-> SDKLib (1.0.0)

Gather Some Auth Share Pay.

pod 'SDKLib', '~> 1.0.0'

- Homepage: https://github.com/xiaokui/SDKLib

- Source:https://github.com/xiaokui/SDKLib.git

- Versions: 1.0.0 [master repo]

6、版本升级

当需要更新 Pod 版本的时候,修改 .podspec 中的 s.version 为更高的版本号,并修改 s.source 中对应的 Git 版本。提交到Git,并打上对应tag。然后再次执行pod trunk push SDKLib.podspec将新的 .podspec 发布到 CocoaPods。更新完成!

为了更方便的修改版本号,用了以下的语句:

s.source       = { :git => "https://github.com/xiaokui/SDKLib.git", :tag => "v#{s.version}" }

这样与 s.version进行了绑定,每次提交新的版本只需要修改s.version  = "xxxx"。

7:将源码打包成静态库.a或者.framework

需要安装cocoapods-packager.(安装命令:sudo gem install cocoapods-packager)

然后执行pod package SDKLib.podspec --force --verbose.通过这个命令打包时候会自动将podspec中dependency的第三方库进行重命名.这样打出来的是SDKLib.framework.

(打release 的包默认打包成framework,如果在后面加上参数“--library”则打包成.a文件,--force是指强制覆盖)前面资源文件都在SDKLib.framework/Reources/SDKLib.bundle里面可以手动把这个bundle拖出去.

前面提到过使用pod package打包时候需要注意.pod会根据当前podspec中的s.source的地址去查找当前sdk源文件的地址.如果使用的s.source = { :git => 'https://github.com/xiaokui/SDKLib.git', :tag => s.version.to_s },那么就会去git中拉取最后一个tag对应commit的源码.如果使用的s.source = { :git => '/Users/fan/Desktop/SDKLib'},那么会使用当前sdk中git 的HEAD位置的commit的源码进行打包编译.(如果源码有修改,一定要先git commit,然后再打包)

 注意问题

1、 重点问题一: Example中依赖某些类库

举例说明,如果SDKLib.podspec中依赖s.dependency 'AFNetworking', '~> 2.3',此时在Example中也需要使用AFNetworking,那么这里千万不要在Example中引入AFNetworking的源码,请在podfile中添加pod AFNetworking.

2、 重点问题二: SDK中依赖的第三方库无法使用BITCODE

在Example的podfile底部添加以下语句:

post_install do |installer|

    installer.pods_project.targets.each do |target|

        target.build_configurations.each do |config|

            config.build_settings['ENABLE_BITCODE'] = 'NO'

        end

    end

3 、重点问题三: SDK中调用资源的问题

对于podfile,常见的库的地址引用写法如下:

pod'库名', :podspec =>'podspec文件路径'#指定导入库的podspec文件路径pod'库名', :git =>'源码git地址'#指定导入库的源码git地址pod'库名', :tag =>'tag名'#指定导入库的Tag分支pod'库名', :path =>'~/Documents/AFNetworking'#指定本地的某个库,文件夹中要有podspec文件

用AFNetworking举例:

// 使用仓库中的master分支:pod'AFNetworking', :git=>'https://github.com/gowalla/AFNetworking.git'//使用仓库的其他分支:pod'AFNetworking', :git=>'https://github.com/gowalla/AFNetworking.git', :branch=>'dev'//使用仓库的某个tag:pod'AFNetworking', :git=>'https://github.com/gowalla/AFNetworking.git', :tag=>'0.7.0'//指定一个提交记录:pod'AFNetworking', :git=>'https://github.com/gowalla/AFNetworking.git', :commit=>'082f8319af'//指定本地路径的最近一次提交commitpod'库名', :path=>'~/Documents/AFNetworking'

打包成功后会在SDKLib.podspec文件路径下面生成一个打包文件,在iOS文件夹里面会看到生成的静态库包

8:可以验证自己的pod地址了(这样pod下来的是静态库源码,你会发现自己开发的静态库文件,到pod文件下面了,具体需要你自己验证一篇)

    再次创建一个项目,在配置podfile文件在里面添加自己的git地址,pod install 试试 ,一路有坑,根据特定的情况解决问题 

特别注意:

   7和8是不一样,7是打包看不到源码,8是在git上pod的下来的源码,如果想在git上pod下来是打包好的静态库不是开源的源码,可以把静态库配置好..podspec上传上git,你需要在git上重新建一个仓库。

总结:

这篇技术文档是我开发SDK总结下来的,一路看网上文档遇到很多坑,这是正确的一套流程,当然你可能按照这个步骤,也会遇到问题,只要理解这一套的原理和一些概念,我相信会很容易解决的,注意要理解定义和原理

下一篇 私有库的创建,有时间整理下(原理差不多,只是需要关联私有的库而已)

iOS项目问题笔记