美文网首页iOS developios开发进阶可能会用到
使用cocoapods打包静态库(依赖私有库,开源库,私有库又

使用cocoapods打包静态库(依赖私有库,开源库,私有库又

作者: 夜幕青雨 | 来源:发表于2017-08-01 16:47 被阅读1334次

之前整理过一种打包静态库的方法: 打包静态库(源码中包含其他静态库以及开源库)。不过这种方式的缺点很明显:1. 需要自己使用Xcode创建静态库工程;2. 需要手动处理代码中依赖的第三方开源库;3. 如果静态库工程依赖私有库,当这些私有库有更新时,就得把他们重新拷贝一份到静态库工程,不够灵活。

因为公司需要持续性向别人提供一套即时通讯SDK,按照之前的方式打包静态库真是太痛苦,SDK依赖的一些私有库会有频繁的更新,依赖的第三方库也是错综复杂。我迫切需要找到一种更方便的打包静态库的方式,既能随时更新私有库,也能解决开源库的冲突问题(比如你的SDK包含了AFNetworking,别人项目中本身也含有AFNetworking,就会产生冲),那就是使用cocoapods。

假设你已经有一堆写好的源码,并且它们依赖一堆私有库和第三方库,也许,这些依赖并非都是源码,可能也包含了静态库(.a或者.framework)。没关系,先放在那吧。

1. 创建你的 project

打开终端,cd 到你喜欢的某个文件路径,输入 pod lib create YOUR_POD_LIBARY_NAME创建并初始化一个工程。

创建并初始化命令

然后回答几个问题,就自动创建出一个project:


问题选项

我们新建的工程以及目录如下:

YJDemoSDK project

其中重要文件夹我都已经展开,可以看到里面包含的内容,其他没有展开的文件夹不用管它。

从上向下看,最重要的一个就是YJDemoSDK.podspec文件,*.podspec是关于pod库的描述文件,它详细说明了在这个pod library中源码应该从哪里取出、应用怎样的构建设置以及其他基本的信息,比如名称、版本、描述等。下面插播一段关于.podspec文件的植入性广告:

podspec文件的内容如下所示,每一项是什么意思都做了简要解释,不明白可以去看官方文档

Pod::Spec.new do |s|
s.name          = 'YJDemoSDK' #项目名
s.version       = '0.1.0' #相应的版本号
s.summary       = 'A short description of YJDemoSDK.' #简述
s.description   = <<‐ DESC #详细描述
TODO: Add long description of the pod here.
DESC
s.homepage      = 'https://github.com/yangjie2/YJDemoSDK' #项目主页
s.license       = { :type => 'MIT', :file => 'LICENSE' } #开源协议
s.author        = { 'yangjie2' => 'yangjie2@guahao.com' } #作者
s.platform      = :ios, '8.0' #支持的平台
s.requires_arc  = true #arc和mrc选项
s.libraries     = 'z', 'sqlite3' #表示依赖的系统类库,比如libz.dylib等
s.frameworks    = 'UIKit','AVFoundation' #表示依赖系统的框架
s.ios.vendored_frameworks = 'YJKit/YJKit.framework' # 依赖的第三方/自己的framework
s.vendored_libraries = 'Library/Classes/libWeChatSDK.a' #表示依赖第三方/自己的静态库(比如libWeChatSDK.a)
#依赖的第三方的或者自己的静态库文件必须以lib为前缀进行命名,否则会出现找不到的情况,这一点非常重要

#平台信息
s.platform      = :ios, '7.0' 
s.ios.deployment_target = '7.0'

#文件配置项
s.source        = { :git => 'https://github.com/yangjie2/YJDemoSDK.git', :tag => s.version.to_s }
 #配置项目的目标路径,如果不是本地开发,pod init/update会从这个路去拉去代码

s.source_files = 'YJDemoSDK/Classes/**/*.{h,m}' #你的源码位置
s.resources     = ['YJDemoSDK/Assets/*.png'] #资源,比如图片,音频文件等
s.public_header_files = 'YJDemoSDK/Classes/YJDemoSDK.h'   #需要对外开放的头文件

#依赖的项目内容 可以多个
s.dependency 'YYModel'
s.dependency 'AFNetworking' '2.3'

明白了.podspec文件是什么之后,继续往下看我们的工程目录,有个文件夹 Development Pods ,这里就是放置我们的源码和图片等资源文件的地方,要与YJDemoSDK.podspec文件中描述的一致。当你向YOUR_POD_LIBARY_NAME/ClassesYOUR_POD_LIBARY_NAME/Assets添加新的/已经存在的文件,或者更新你的.podspec时,需要运行pod install或者pod update

Development Pods
Development Pods are different from normal CocoaPods in that they are symlinked files, so making edits to them will change the original files, so you can work on your library from inside Xcode. Your demo & tests will need to include references to headers using the #import <MyLib/XYZ.h> format.

Note: Due to a Development Pods implementation detail, when you add new/existing files to Pod/Classes or Pod/Assets or update your podspec, you should run pod install or pod update.

2. 配置podspec文件,添加自己的代码

上面创建了一个pod library项目YJDemoSDK,可以看到项目的文件目录结构,并对几个重要的地方进行了单独说明。下面就开始设置它。

向Classes中添加源码替换掉ReplaceMe.m文件(为了简单,这里添加YJDemoSDK.hYJDemoSDK.m )。YJDemoSDK.podspec文件配置结果如下图:

YJDemoSDK.podspec

配置完之后,切到终端,使用 pod lib lint ***.podspec验证是否有效,必须没有错误,没有警告才可以通过验证。

由于YJDemoSDK依赖私有库YJHelloDog,并且这个私有库中包含静态库(.a)文件,所以在验证时,需要键入如下命令:

pod lib lint --sources=git@git.guahao-inc.com:yangjie2/snowRepo.git,https://github.com/CocoaPods/Specs.git --use-libraries --allow-warnings

其中,--sources=git@git.guahao-inc.com:yangjie2/snowRepo.git,https://github.com/CocoaPods/Specs.git指定了我们的私有Repo地址和cocoapods官方的Repo,并且是master分支。--use-libraries表示依赖了静态库,--allow-warnings忽略警告。这样就可以验证通过了。

验证结果

然后cd到YJDemoSDK的Example目录,执行

pod install。

幽怨的发现,出错了,找不到YJDemoSDK依赖的YJHelloDog这个仓库。

找不到YJDemoSDK依赖的YJHelloDog这个仓库

不过问题也很显然, YJHelloDog 是私有库。在podfile文件中,添加上我自己的Repo 地址就好。

podfile文件

再次执行 pod install,就没问题了。


执行 pod install

这时候再看下pod项目的目录,发现已经添加好了源码和依赖库:

YJDemoSDK 目录
3. 提交,打tag

YJDemoSDK 项目配置完成,添加了自己的源码,也添加了依赖的私有库、第三方开源库。提交所有的更新,打tag,push到托管服务器(比如gitHub等)。

打开终端,重新 cd 到 YJDemoSDK 路径,执行以下命令进行提交、打tag,推送tag到远端托管服务器。

git add .
git tag -a 0.1.0 -m 'version 0.1.0' 
git push origin 0.1.0
4. 打包静态库

前面的准备工作完成,最后一步就是打包静态库了。这里需要安装一个 CocoaPods 打包插件 cocoapods-packager。终端执行安装命令:sudo gem install cocoapods-packager,等待安装完成。

该插件通过对引用的三方库进行重命名很好的解决了类库命名冲突的问题。

终端cd到项目所在目录下,执行以下命令即开始打包静态库:

pod package YJDemoSDK.podspec --library --force --no-mangle --spec-sources=http://git.guahao-inc.com/yangjie2/snowRepo.git,https://github.com/CocoaPods/Specs.git
# --library 表示打包成.a文件。--force 表示强制覆盖之前存在的文件

pod package YJDemoSDK.podspec --force --no-mangle --spec-sources=http://git.guahao-inc.com/yangjie2/snowRepo.git,https://github.com/CocoaPods/Specs.git
# 没有--library,则打包成.framework文件

上面的命令中,有一个是--no-mangle,表示Do not mangle symbols of depedendant Pods,当你的项目依赖包含静态库时,不加上这句,就会打包失败:

打包失败 打包静态库成功

到此为止,.a 形式的静态库打包成功!刚才打包好的静态库就在我的项目路径下YJDemoSDK-0.1.0文件夹中,里面的文件如下图所示:

静态库目录

蓦然发现,没有头文件。。。我希望公开被
别人调用的头文件跑哪里去了?这样打出来静态库也没办法用。google了下,找到一种不是答案的答案,这是cocoapods package 的一个bug,不知道为啥没被修复。或者哪位老铁有了解决方法还请不吝分享下。

这样只能打包成framework了,它是有头文件的。目录如下图:

framework静态库

使用时,直接拖到项目中,然后 #import <YJDemoSDK/YJDemoSDK.h>,使用#import "YJDemoSDK/YJDemoSDK.h"形式是找不到文件的,要使用尖括号。拖到你的项目中,编译时会出错:

编译出错
原因是找不到 YJHelloDog.a 文件,这个文件是我们的静态库依赖的另一个静态库,它是不会被打包进framework的,需要你手动添加进项目,所以再把依赖的这个静态库 YJHelloDog.a 拖进项目就好了,运行成功,显示toast提示:hello dog. 说明方法调用成功。至此才算结束了。

使用这种方式打包静态库,在私有库或者开源库有更新时,只需 pod update ,再次执行打包命令就好了,是不是很方便?

相关文章

网友评论

  • 6129b93b59e2:宏报错 编译不过 #define GLOBALColor [UIColor colorFromHex:@"C00822"]
    提示colorFromHex 方法找不到 但是我又在pch 里面引用了 很难受哇
    6129b93b59e2:swift 没有复杂红
  • fengyuyxz:创建自己的私有库引用第三方私有库包含.a文件的时候使用--use-libraries不起效果啊
    夜幕青雨:@fengyuyxz 你的spec文件有配置 s.vendored_libraries 这一项吗。
  • 涨了翅膀的小绵羊:楼主有没有遇到packager打包静态库,开源第三方打库(如AF)不进去的情况,有没有解决方案?
  • 751f1e36e721:博主 打扰您了.
    我做了一个最简单的测试,没有依赖任何第三方库,只是打印,用packger打包出来的framework
    好比我的framework叫做xxx.framework
    我导入使用的时候 我期待的效果是#import <xxx/xxx,h>
    但是#import <xxx.framework/下面居然还要Header
    最后只能出现是#import "xxx.framework/Headers/xxx.h"我真的很崩溃啊
    zidaneno5:为什么import的时候要有.framework呢?直接#import <xxx【不要加.framework】/xxx,h>不行么?
    751f1e36e721:@夜幕青雨 博主 谢谢, 如果您这边有demo提供吗? 我的需求和你讲解的很像 465379032@qq.com 这是我的邮箱 或者您有什么联系方式 真的打扰了 不胜感谢
    夜幕青雨:@jasonPHD 确实比较奇怪,设置一下Header路径试试:

    设置BuildSetting中的 Header Search Paths ,新增     "$(PROJECT_DIR)/Frameworks/***.framework/Headers"  ,指明头文件路径。
  • 神魔狼:这样不好吧 应该吧.a也放进去才好 不然你提供给别人一个framework还要再加个.a文件?
    夜幕青雨:@天青Se等烟雨 看下你的私有pod是不是打了tag,是不是把这个tag下的podspec文件更新到了你的私有仓库。
    天青Se等烟雨:你好, 我这边按照你这个添加自己私有pod的source 地址,然后在pod install 还是提示找不到啊~因为我没有到打包的那一步,我没有去pod package
    夜幕青雨:@神魔狼 我不知道怎么把其他静态库也打进去,求指教:grin:

本文标题: 使用cocoapods打包静态库(依赖私有库,开源库,私有库又

本文链接:https://www.haomeiwen.com/subject/ixcklxtx.html