CocoaPods使用总结

作者: Code_Ninja | 来源:发表于2018-08-22 23:45 被阅读13次

写在前面:最近闲暇时间搭建了我的
个人博客 以后最新文章会第一时间发布在个人博客里(简书也会同步),欢迎关注互相支持,Thanks♪(・ω・)ノ !

使用CocoaPods也有很长一段时间了,最近几个月的时间里也主导了公司私有Pods的创建和使用。在此期间踩过了不少坑,在踩坑的过程中也收获了不少经验,更加熟练地掌握了CocoaPods的一些指令的使用。本篇作为这段时间收获的备忘。

一、CocoaPods简介

CocoaPods是专门为iOS工程提供第三方依赖库的管理工具,通过CocoaPods,我们可以更方便地管理每个第三方库的版本,而且不需要我们做太多的配置,就可以直观、集中和自动化地管理我们项目的第三方库。

CocoaPods将所有依赖的库都放在一个名为Pods的项目下,然后让主项目依赖Pods项目。然后,我们编码工作都从主项目转移到Pods项目。Pods项目最终会编译为一个libPod-项目名.a静态库,主项目依赖于这个静态库。

对于资源文件,CocoaPods 提供了一个名为 Pods-resources.sh 的 bash 脚本,该脚本在每次项目编译的时候都会执行,将第三方库的各种资源文件复制到目标目录中。

CocoaPods 通过一个名为 Pods.xcconfig 的文件来在编译时设置所有的依赖和参数。

CocoaPods是用 Ruby 写的,并由若干个 Ruby 包 (gems) 构成的。在解析整合过程中,最重要的几个 gems 分别是: CocoaPods/CocoaPods, CocoaPods/Core, 和 CocoaPods/Xcodeproj

CocoaPod的核心组件

  • CocoaPods/CocoaPod
    这是是一个面向用户的组件,每当执行一个 pod 命令时,这个组件都将被激活。该组件包括了所有使用 CocoaPods 涉及到的功能,并且还能通过调用所有其它的 gems 来执行任务。

  • CocoaPods/Core
    Core 组件提供支持与 CocoaPods 相关文件的处理,文件主要是 Podfile 和 podspecs。

  • Podfile
    Podfile 是一个文件,用于定义项目所需要使用的第三方库。该文件支持高度定制,你可以根据个人喜好对其做出定制。更多相关信息,请查阅 Podfile 指南。

  • Podspec
    .podspec 也是一个文件,该文件描述了一个库是怎样被添加到工程中的。它支持的功能有:列出源文件、framework、编译选项和某个库所需要的依赖等。

  • CocoaPods/Xcodeproj
    这个 gem 组件负责所有工程文件的整合。它能够对创建并修改 .xcodeproj 和 .xcworkspace 文件。它也可以作为单独的一个 gem 包使用。如果你想要写一个脚本来方便的修改工程文件,那么可以使用这个 gem。

CocoaPod的安装和配置,以及Podfile中第三方库引用的语法规则(特别是版本号的语法格式)这里就不赘述了,下面挑重点讲一讲。

二、多target时Podfile该如何写?

我的建议是使用Ruby语法,定义不同的分组,然后不同的target可以自由选择依赖哪些分组,这种方式看起来更简洁,对于多target的项目来说也更友好:

platform :ios, '8.0'

def commonPods #通用pods集
    pod 'AFNetworking', '~> 2.0'
    pod 'Masonry'
end

def appOnlyPods #app专用pods集
    pod 'MBProgressHUD'
end

def extensionPods #扩展专用pods集
    pod 'GTSDKExtension'
end

target :TestCocoaPods do
    commonPods
    appOnlyPods

    target :TestCocoaPodsTests do
    inherit! :search_paths
    # Pods for testing
    end

    target :TestCocoaPodsUITests do
        inherit! :search_paths
        # Pods for testing
    end
end

target :SecondTarget do
    commonPods
end

三、如何忽略Pods警告?

有些第三方Pod集成进来会有一大堆警告信息,如果你看着比较难受想把它忽略的话,在Podfile中对应的target或分组下加上关键字inhibit_all_warnings即可。

四、如何直接引用第三方库中的头文件?

在用CocoaPods集成第三方库之后,默认情况下,我们需要使用类似#import <XXX/YYY.h>的方式引入第三方库的头文件。我们可以在Build Settings -> User Header Search Paths中添加${SRCROOT}并设置成recursive,这样我们就可以直接使用#impot "YYY.h"这种方式了。

五、pod install or pod update?

如官方文档所说,pod installpod update确实是大家最容易搞混的两条指令,很多人还没搞清楚这两条指令的区别,反正不管三七二十一上来就是一个pod update,大家一定要搞清楚这两条指令的区别。

按照官方文档所说,pod install在第一次检索集成第三方以及每一次在Podfile中新增、更改或删除pod的时候使用。每一次执行pod install命令,它都会下载安装新的pod,并且会把每一个安装的pod的版本信息写入Podfile.lock文件。Podfile.lock文件跟踪每一个安装的pod的版本并且上锁。每一次执行pod install命令,只解决还没有在Podfile.lock中列出的依赖:对于已在Podfile.lock中列出的pod,会下载指定的版本,不会检查是否有新版本。对于没有在Podfile.lock中列出的pod,它会搜索并安装Podfile中指定的版本。

直接执行pod update命令会检查安装Podfile中列出的所有pod的新版本(往往比较慢)。

执行pod update PODNAME命令会检查PODNAME的新版本(不考虑Podfile.lock中记录的版本信息),它会把PODNAME更新为最新版本,只要跟Podfile中指定的版本匹配。也就是说,pod update PODNAME将PODNAME更新到Podfile中指定的版本,可以是更新到老版本也可以是更新到新版本,取决于Podfile。(比如:如果此时Podfile中指定了pod 'AFNetworking', '~> 2.0',此时执行pod update AFNetworking并不会把AFNetworking更新到最新版本(因为此时的版本满足大于等于2.0版),必须先修改Podfile中的版本信息才会更新到指定版本)。

两者的区别:

  • pod install命令来安装新的pod,每次在Podfile中新增和删除pod都使用pod install命令。

  • 在Podfile中添加新的pod后应该用pod install命令,而不是pod update命令。通过pod install命令安装新的pod而不用担心在同一进程中修改已有的pod。

  • pod update命令仅用在更新指定pod到指定版本或者更新所有pod。

我的建议是:该用pod install的时候不要用pod update PODNAME。另外,尽量不要用pod update,因为它是全部检查一遍,不仅慢有时候还会出现坑。比如有一个依赖的第三方库本来是2.0版本的用的好好的,因为它是国外的资源,下载起来非常慢,我们在没有bug的情况下是不希望轻易去更新它的,那么如果你上来就是一个pod update指令,OK, 如果你Podfile中指定了每次使用最新版本(不指定版本号),那么CocoaPods就会去下载最新的这个第三方库,那在下载完成之前你还要不要做其他事情了?这还是情况好的,如果这个最新的版本一直下载失败,所以一直集成失败怎么办?

六、如何创建私有Pod?

要创建私有Pod,首先我们需要两个私有仓库,一个放私有Pod源码,一个放私有Pod的说明书(类似公有Pod的CocoaPods/Specs)。

1、添加私有Spec仓库到本地

pod repo add privateSpecs your_privateSpecs.git

如果执行成功,之后便可以通过pod repo list命令查看本地Spec仓库列表,正常情况下会有一个公有的CocoaPod官方的master repo 和你的 privateSpecs repo,并可以看到它们在本地的存放路径(其实在~/.cocoapods/repos目录下)。

2、创建私有Pod

在私有Pod代码所在文件夹下执行pod spec create your_podName在该目录下创建一个your_podName.podspec说明书文件。之后的工作就是编辑这个说明书文件了,这里简单注明一下规则:

Pod::Spec.new do |s|

  s.name         = "ATCategory"
  s.version      = "0.0.1"
  s.summary      = "共用扩展类集合"
  s.description  = <<-DESC
  大家如果需要用到扩展,都使用这里已有的扩展啦。
                   DESC
  s.homepage     = "your_privatePodGit_address/ATCategory"
  s.author       = { "ApesTalk" => "lqcjdx@163.com" }
  s.platform     = :ios
  s.platform     = :ios, "8.0"
  s.source       = { :git => "your_privatePodGit_address", :tag => "#{s.version}"
  # 如果你有多个私有Pod放在一个仓库里,你可以修改tag像下面这样,对应打tag的时候的规则就对应需要变成PodName-v0.0.1这样子了
  # s.source       = { :git => "your_privatePodGit_address", :tag => s.name + "-v"+"#{s.version}"
}
  s.source_files  = 'ATCategory/**/*'
  s.public_header_files = 'ATCategory/Category/*.h'
  s.requires_arc = true
  s.frameworks = 'UIKit','Foundation'

# 依赖的系统library,这里是指系统的类似libz.tbd、libxml2.tbd这类的系统库
# s.library = 'z' // 单个
# s.libraries = 'z','xml2' // 多个

# 第三方.a
# s.vendored_libraries =
# 第三方frameworks文件
# s.vendored_frameworks =
# 依赖关系,该项目所依赖的其他库,如果有多个需要填写多个s.dependency
# s.dependency 'AFNetworking', '~> 2.3'
# 资源文件地址
# s.resource_bundles = {
#   'ATCategory' => ['ATCategory/Images/*.png']
# }
end

3、提交源代码并打tag

注意这里tag必须跟podspec文件中的tag保持一致,因为CocoaPod是通过podspec文件中的tag去找源文件的,如果tag对应不起来就会验证失败。打好tag提交到远端。

4、验证podspec文件合法性和可选参数

有两种验证方式,一种是本地验证pod lib lint your_podName.podspec和联网验证od spec lint your_podName.podspec。建议大家都用联网验证。

这里可选参数有:

  • --allow-warnings:允许警告
  • --sources=‘master,privateSpecs:指定源,比如你的私有pod同时依赖了公有库和私有库,你必须指定源才行,因为默认只会去在公有源中查找对应的依赖
  • --use-libraries:如果使用了静态库,记得加上它

5、提交说明书文件到私有说明书库

pod repo push privateSpecs your_podName.podspec,同样的加上上面验证时使用到的可选参数。

6、如果使用素材?

官方建议pod中的素材用bundle的形式避免和主项目中的文件名发生冲突,那么集成后我们如何使用bundle中的素材呢?

NSBundle *bundle = [NSBundle mainBundle];
//NSBundle *bundle = [NSBundle bundleForClass:[ClassFromPodspec class]];//对于静态库,拿到的是mainBundle,如果是动态库,拿到的是类所在的bundle。使用动态库需要在Podfile中开启use_frameworks!
NSURL *wttpodBundleURL = [bundle URLForResource:@"WTTPod" withExtension:@"bundle"];
NSBundle *wttpodBundle = [NSBundle bundleWithURL: wttpodBundleURL];
UIImage *img = [UIImage imageNamed:@"Chat_checkin_empty_stu" inBundle:wttpodBundle compatibleWithTraitCollection:nil];

7、关于subspec

如果我们的pod中文件比较多,而我们又希望能像AFNetworking那样集成后分几个物理文件夹(默认会把所有文件都放在一个物理文件夹下,文件太多会显得很乱),那么就要用到subspec来把我们的pod分成几个独立的子模块。


s.subspec '子模块名称' do |别名,不能和子模块名称相同,比如ss|

ss.source_files = ''

end

具体怎么用,大家可以参考AFNetworking.podspec文件中的写法。

七、如何使用私有库

如果我们同时使用了公有库和私有库,我们只需要在Podfile的头部同时把公有库和私有库的source加上即可。

八、pod search搜不到私有库?或者搜得到pod install失败?

在提交私有库说明书之后,先执行一下pod repo update privateSpecs,然后再集成。

九、集成某一个pod速度过慢,比如MobileVLCKit总是下载失败

把对应版本的MobileVLCKit下载下来放在访问速度更快的地方(比如内网服务器或者本机用Python开启一个FTP服务)在本机master repo源中搜索找到对应版本的MobileVLCKit.podspec.json文件,把其中的source改成我们存放MobileVLCKit.tar.xz文件地址,之后再执行相关指令集成。

如何利用Python开启一个本地FTP服务:

cd到要共享的目录下,执行python -m SimpleHTTPServer 8000,之后同一个局域网内就可以通过本机ip:8000访问到该共享文件夹了。


"http":"http://192.168.210.111:8000/MobileVLCKit-3.1.2-bf58e19-37855b857a.tar.xz"

十、验证podspec时,报错 symbol(s) not found for architecture i386

检查一下是否私有Pod中使用到的什么文件不支持i386架构,比如什么.a文件。

解决办法:在podspec文件中指定支持的架构

valid_archs = ['armv7s','arm64',]
s.xcconfig = {
  'VALID_ARCHS' =>  valid_archs.join(' '),
}
s.pod_target_xcconfig = {
    'ARCHS[sdk=iphonesimulator*]' => '$(ARCHS_STANDARD_64_BIT)'
}

十一、`pod init``失败?

用Xcode9.4.1新建一个项目,然后执行pod init(Cocoapods1.4.0版本)时提示失败,错误提示如下:


――― MARKDOWN TEMPLATE ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――

### Command

/usr/local/Cellar/cocoapods/1.4.0/libexec/bin/pod init


### Report

* What did you do?

* What did you expect to happen?

* What happened instead?


### Stack

CocoaPods : 1.4.0
Ruby : ruby 2.3.3p222 (2016-11-21 revision 56859) [universal.x86_64-darwin17]
RubyGems : 2.5.2
Host : Mac OS X 10.13.3 (17D47)
Xcode : 9.4.1 (9F2000)
Git : git version 2.15.2 (Apple Git-101.1)
Ruby lib dir : /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib
Repositories : ios-cocoapodsSpecs - http://git.zhihuishu.com/coder/ios-cocoapodsSpecs.git @ 4c4f38416c28d58d4dda2a706879956c5861a55e
master - https://github.com/CocoaPods/Specs.git @ 1eab292c36f39ecb104af54e474b00f142e57d0f


### Plugins

cocoapods-deintegrate : 1.0.2
cocoapods-plugins : 1.0.0
cocoapods-search : 1.0.0
cocoapods-stats : 1.0.0
cocoapods-trunk : 1.3.0
cocoapods-try : 1.1.0


### Error

RuntimeError - [Xcodeproj] Unknown object version.
/usr/local/Cellar/cocoapods/1.4.0/libexec/gems/xcodeproj-1.5.4/lib/xcodeproj/project.rb:217:in initialize_from_file' /usr/local/Cellar/cocoapods/1.4.0/libexec/gems/xcodeproj-1.5.4/lib/xcodeproj/project.rb:102:inopen'
/usr/local/Cellar/cocoapods/1.4.0/libexec/gems/cocoapods-1.4.0/lib/cocoapods/command/init.rb:41:in validate!' /Library/Ruby/Gems/2.3.0/gems/claide-1.0.2/lib/claide/command.rb:333:inrun'
/usr/local/Cellar/cocoapods/1.4.0/libexec/gems/cocoapods-1.4.0/lib/cocoapods/command.rb:52:in run' /usr/local/Cellar/cocoapods/1.4.0/libexec/gems/cocoapods-1.4.0/bin/pod:55:in<top (required)>'
/usr/local/Cellar/cocoapods/1.4.0/libexec/bin/pod:22:in load' /usr/local/Cellar/cocoapods/1.4.0/libexec/bin/pod:22:in<main>'


――― TEMPLATE END ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――

[!] Oh no, an error occurred.

Search for existing GitHub issues similar to yours:
https://github.com/CocoaPods/CocoaPods/search?q=%5BXcodeproj%5D+Unknown+object+version.&type=Issues

If none exists, create a ticket, with the template displayed above, on:
https://github.com/CocoaPods/CocoaPods/issues/new

Be sure to first read the contributing guide for details on how to properly submit a ticket:
https://github.com/CocoaPods/CocoaPods/blob/master/CONTRIBUTING.md

Don't forget to anonymize any private data!

Looking for related issues on cocoapods/cocoapods...
 - Pod Update: RuntimeError - [Xcodeproj] Unknown object version. Xcode Beta 5
   https://github.com/CocoaPods/CocoaPods/issues/8003 [closed] [17 comments]
   a day ago

 - RuntimeError - [Xcodeproj] Unknown object version.
   https://github.com/CocoaPods/CocoaPods/issues/7697 [closed] [28 comments]
   3 weeks ago

 - Pod init. Unknown object version
   https://github.com/CocoaPods/CocoaPods/issues/7907 [closed] [2 comments]
   03 Jul 2018

and 42 more at:
https://github.com/cocoapods/cocoapods/search?q=[Xcodeproj]%20Unknown%20object%20version.&type=Issues&utf8=✓

这种失败原因是Cocoapods和xcodeproj版本兼容问题。

尝试了网上的解决办法Run gem install xcodeproj:1.4.1,依然失败。

解决办法:打开项目,在Project Document下将Project Format从Xcode 9.3-compatible修改为Xcode 8.0-compatible即可。

Xocde_project_format

相关文章

  • 关于Cocopods安装的那些事

    一.安装Cocoapods 安装和使用cocoapods 教程总结>>>>>>>>>>>>>>> gem sour...

  • cocoaPods 命令行总结

    安装 cocoaPods 就不多说了 安装 cocoapods 步骤 我这里总结了安装好 cocoapods 使用...

  • CocoaPods使用总结

    pod install 时出现 Unable to find a specification for `xxxxx...

  • CocoaPods使用总结

    写在前面:最近闲暇时间搭建了我的个人博客 以后最新文章会第一时间发布在个人博客里(简书也会同步),欢迎关注互相支持...

  • Cocoapods使用总结

    Mac系统升级到macOS High Sierra之后,运行pod显示:"pod: command not fou...

  • CocoaPods使用总结

    CocoaPods 公共库的创建CocoaPods 本地私有库的创建(模板创建方式)CocoaPods 本地私有库...

  • CocoaPods使用总结

    cd +空格 +工程路径vim podfile输入i下一步platform :ios, '8.0'use_fram...

  • Cocoapods使用总结

    CocoaPods应该是iOS最常用最有名的类库管理工具,并且绝大部分有名的开源类库都支持CocoaPods,使用...

  • CocoaPods使用总结

    安装: 1.移除现有Ruby默认源 gem sources --remove https://rubygems.o...

  • CocoaPods使用总结

    安装准备: 在终端中操作,首先通过3和4检查ruby源和版本 移除现有Ruby默认源gem sources --r...

网友评论

  • 675583164fad:最后一个报错,修改了Project Document下将Project Format 没起作用
    Code_Ninja:我这边当时是这么解决的,你的可能是其他问题。

本文标题:CocoaPods使用总结

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