大家好,我是考100分的小小码 ,祝大家学习进步,加薪顺利呀。今天说一说最全CocoaPods使用教程[亲测有效],希望您对编程的造诣更进一步.
CocoaPods 常⽤用法
1.下载升级 CocoaPods 。
sudo gem install cocoapods
查看当前 cocoapods 版本
pod --version
升级 cocoapods
sudo gem install -n /usr/local/bin cocoapods --pre
查看当前 gem 源
gem sources -l
删除 gem 源 ruby.taobao.org/
gem sources --remove https://ruby.taobao.org/
修改 gem 源为 gems.ruby-china.org
gem sources -a https://gems.ruby-china.org
/usr/local/bin : gem 安装路路径。
2.使⽤用 CocoaPods 。
初始化 Podfile
pod init
搜索库 AFNetworking
pod search AFNetworking
根据 Podfile,安装 pod,创建 workspace
pod install
根据 Podfile,更更新安装
pod update
更更新索引库。存放 spec ⽂文件的仓库。
pod repo udpate
列出本地所有 spec 仓库
pod repo list
3.配置 CocoaPods 的 Podfile 。
指定本地下载源
pod 'MCFramwork', :path => '../'
指定库 git 源
pod 'AFNetworking', :git => 'https://github.com/AFNetworking/AFNetworking.git'
指定索引库
pod 'AFNetworking', :source => 'https://github.com/CocoaPods/Specs.git'
指定索引库
source 'https://github.com/CocoaPods/Specs.git'
source 'https://github.com/Artsy/Specs.git'
4.CocoaPods 常⽤用路路径。
~/.cocoapods :本地 spec 库(索引库)。
( ~/.cocoapods/repos/master 是 origin https://github.com/CocoaPods/Specs.git )
~/Library/Caches/CocoaPods :本地库缓存。
CocoaPods 私有库
1.CocoaPods 私有库创建
需要创建的仓库分为两个: spec repository 和 code repository (这⾥里里创建的 仓库都是 git 仓库)。
spec repository 是索引库(配置仓库),这个仓库只⽤用来存放 spec ⽂文件,不不 存放代码。 spec ⽂文件是按照版本存放,每⼀一个 spec ⽂文件对应⼀一个版本的代码。 版本号就是代码库的 tag 号。每⼀一个 spec ⽂文件包含对应版本代码库的信息(包 括:仓库名、代码库的远程地址、版本号、依赖库、库⽂文件等等)。 repos 下⾯面⽂文 件⽬目录: repos/<repos_name>/<sdk_name>/<version_num>/<name.podspec> 。
code repository 是代码仓库,把包代码或包⼆二进制⽂文件上传到这个仓库。
~/.cocoapods 索引库存放在本地的⽬目录。 ~/.cocoapods/repos/master 的 origin 是 github.com/CocoaPods/S… ,就是 CocoaPods 官⽅方 的索引库。
执⾏行行 pod setup 时,会从 github 上拉取 master 源。
执⾏行行 pod install 时,会把 Podfile 中所有的私有库索引源对应的索引库
拉取下来。
执⾏行行 pod update 时,会更更新本地所有的索引库。
执⾏行行 pod repo udpate 时,更更新本地所有索引库。
创建私有库:
在 git 远端创建索引仓库。
在 git 远端创建代码仓库。所有代码仓库共⽤用⼀一个索引库。
clone 代码库到本地,创建⼯工程。⼀一般包含: LICENSE (开源许可 证)、 README.md 、 name.podspec (CocoaPods 的索引描述⽂文件)、代 码(代码 & ⼆二进制⽂文件 & 资源⽂文件)、 Example (Demo⼯工程)。
第⼀一次搜索库的时候或者删除电脑缓存,会出现:
pod search AFN
Creating search index for spec repo 'master'..
是在创建 search_index.json ⽂文件。所以 pod search 搜索是通过⼀一个 search_index.json 缓存⽂文件搜索的,这个缓存⽂文件路路径是 ~/Library/Caches/CocoaPods/search_index.json 。
- spec ⽂文件
创建 spec ⽂文件。
创建 spec ⽂文件,名字为 spec_name
pod spec create spec_name
spec ⽂文件字段含义。
Pod::Spec.new do |s|
s.name = 'MYFramwork' # 项⽬目名称
s.version = '1.0.0' # 版本号 与 你仓库的 标签号 对应
s.license = 'MIT' # 开源证书
s.summary = '项⽬目简介'
s.homepage = '代码仓库地址'
s.author ={"MC"=>"作者邮箱"}
s.social_media_url = "个⼈人主⻚页地址"
# 仓库地址,不不能⽤用 SSH 地址
s.source = { :git => '代码仓库地址', ::tag => '#{s.version}' } '#{s.version}' }
s.requires_arc = true # 是否启⽤用 ARC
s.platform = :ios, '8.0' # 平台及⽀支持的最低版本
# 代码的位置, MCLib/*.{h,m} 表示 MCLib ⽂文件夹下所有的 .h 和 .m ⽂文件
s.source_files = "MCLib/*.{h,m}"
# s.resource = "pod/classes/TestViewController.xib" s.resources = ['*.bundle', '*.strings', '*.xib']
# ⽀支持的框架
s.frameworks = 'UIKit', 'Foundation'
# 依赖库
s.dependency = 'AFNetworking'
s.dependency 'SDWebImage'
# 配置 Xcode Build Setting s.xcconfig = {
'HEADER_SEARCH_PATHS' => '$(PODS_ROOT)/',
# 配置 Header 搜索 # 配置 Framwork
'FRAMEWORK_SEARCH_PATHS' => '$(PODS_ROOT)/', 搜索路路径
'GCC_PREPROCESSOR_DEFINITIONS' => 'RELEASE COCOAPODS=1' # 配置预 编译宏
}
# 配置 pch
s.prefix_header_file = 'MCLib/MCLib.pch'
end
可以把创建好的 spec ⽂文件添加到本地索引库中。
# 添加 spec 到本地指定的索引库。
# pod repo add [Private Repo Name 本地私有库名字] [GitHub HTTPS clone URL 私有库远程地址]
pod repo add MCRepoLib https://gitee.com/mengcoder/MCSpeclib.git
- push 私有库索引
推送私有库索引到私有索引仓库。⼀一般推送之前会进⾏行行验证,验证通过之后,再推送。
验证:
# 验证
pod lib lint
pod lib lint --verbose --use-libraries --allow-warnings -- sources='私有仓库repo地址,https://github.com/CocoaPods/Specs'
pod spec lint
pod spec lint --verbose --use-libraries --allow-warnings -- sources='私有仓库repo地址,https://github.com/CocoaPods/Specs'
CocoaPods 强制要求所有的 Pods 依赖库都必须有 license ⽂文件,否则验证不不会 通过。
推送:
# 先验证 .podspec ⽂文件,验证通过,再把 .podspec ⽂文件推送到 spec 源。
# push 到远程仓库
# pod repo push 本地repo名 本地podspec名
pod repo push MCLib MCAppKit.podspec --verbose --use-libraries -- allow-warnings
# spec ⽂文件转换成 .json
pod ipc spec <filename.podspec>
常⻅见问题
-
安装 Podfile
[!] Unable to find a specification for MCLib
本地没有 MCLib 的索引 spec 。更更新 MCLib 对应的本地 repos ,本地 repos 仓库缓存⽬目录: ~/.cocoapods/repos/ 。
更更新本地 repo pod repo udpate [!] Unable to find a specification for FMDB depended upon by MCLib # podfile 在私有库后⾯面配置了了 source ,导致私有库 QMAppUIKit 依赖的库 QMAppFoundation(QMAppFoundation依赖FMDB) 在设置的source中找不不到 FMDB。 pod 'QMAppUIKit' , '0.0.1' , :source => 'git@10.2.250.21:QMApp/specRepo_iOS.git' # QMAppUIKit
-
推送 spec ⽂文件
# CocoaPods 私有库,静态 Framework 验证失败: The following build commands failed: CompileC /Users/mengyueping/Library/Developer/Xcode/DerivedData/App- fbdglhmiocesdxeuqlwfuuhbmtht/Build/Intermediates.noindex/Pods.build /Release-iphonesimulator/MCLib.build/Objects- normal/i386/openssl_wrapper.o MCLib/MCLib/Lib/Util/openssl_wrapper.m normal i386 objective-c com.apple.compilers.llvm.clang.1_0.compiler (1 failure) Testing with `xcodebuild`. -> MCLib (0.0.1) - ERROR | [iOS] xcodebuild: Returned an unsuccessful exit code.
指定私有库的源,验证 .podspec ⽂文件时,出现私有库找不不到。
推送 spec 到 Cocoapods 官⽅方库
开源 Pod 库,要注册⼀一个 CocoaPods 账号。使⽤用终端注册。
pod trunk register 447497298@qq.com 'qiaoming' --verbose
opening connection to trunk.cocoapods.org:443... opened
starting SSL for trunk.cocoapods.org:443...
SSL established
<- "POST /api/v1/sessions HTTP/1.1\r\nContent-Type: application/json; charset=utf-8\r\nAccept: application/json; charset=utf-8\r\nUser-Agent: CocoaPods/1.3.1\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nHost: trunk.cocoapods.org\r\nContent-Length: 67\r\n\r\n"
<- " {\"email\":\"1134471523@qq.com\",\"name\":\"CoderMeng\",\"descripti on\":null}"
-> "HTTP/1.1 201 Created\r\n"
-> "Date: Thu, 03 May 2018 03:03:11 GMT\r\n"
-> "Connection: keep-alive\r\n"
-> "Strict-Transport-Security: max-age=31536000\r\n"
-> "Content-Type: application/json\r\n"
-> "Content-Length: 193\r\n"
-> "X-Content-Type-Options: nosniff\r\n"
-> "Server: thin 1.6.2 codename Doc Brown\r\n"
-> "Via: 1.1 vegur\r\n"
-> "\r\n"
reading 193 bytes...
-> "{\"created_at\":\"2018-05-03 03:03:11 UTC\",\"valid_until\":\"2018-09-08 03:03:11 UTC\",\"verified\":false,\"created_from_ip\":\"210.12.48.132\",\"de scription\":null,\"token\":\"682a8eca7a76ff7e1b1b8334b6d566f6\"}"
read 193 bytes
Conn keep-alive
[!] Please verify the session by clicking the link in the verification email that has been sent to 1134471523@qq.com
# 看到上⾯面提示,去邮箱验证确认。
# pod trunk register < you_email > 'user_name' --verbose
# 终端确认 pod trunk me
- Name:qiaoming
- Email:447497298@qq.com
- Since:
- Pods:
- Sessions:
- May 2nd, 21:03 - September 7th, 21:26. IP: 210.12.48.132
Cocoapods 使⽤用 pod trunk 发布程序
pod trunk push xxx.podspec
pod repo add --help
Usage:
$ pod repo add NAME URL [BRANCH]
Clones `URL` in the local spec-repos directory at `~/.cocoapods/repos/`. The
remote can later be referred to by `NAME`.
Options:
CoderMeng
1134471523@qq.com
May 2nd, 21:03
None
--progress
--silent
--verbose
--no-ansi
--help
Show the progress of cloning the spec repository
Show nothing
Show more debugging information
Show output without ANSI codes
Show help banner of specified command
Include of non-modular header inside framework module 或者:fatal error: could not build module ‘xxxxx’
# 私有库的 .h ⽂文件中引⼊入了了依赖的源码库的 .h ⽂文件,导致根据的私有库的 module.modulemap 找不不到该头⽂文件,导致错误。
# 解决:设置 BuildSetting -》 Allow Non-modular Includes In Framework Modules YES
spec.user_target_xcconfig = { 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES' }。
# lint 命令只剩下 warning。
# user_target_xcconfig 和 pod_target_xcconfig 的区别:
# user_target_xcconfig 是对于编译⼯工程中所有 pod 的设置,
# ⽽而 pod_target_xcconfig 只是针对当前 pod 的。
# 所以如果多个 pod 的 podspec 中对 user_target_xcconfig 同⼀一个值进⾏行行了了设 置,那么就可能存在冲突问题。
# 但因为 CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES 在 pod_target_xcconfig 不不起作⽤用,只能按现在的配置来处理理。
Cloning into ‘/var/folders/rg/f1ycrs553dq2z2dq7mt0mbh80000gn/T/d20160921-12602- 1bx4f8v’… remote: Not Found fatal: repository ‘http://192.168.110.114/xxxxxx.git/’ not found
pod spec lint 命令,校验 pod 的代码和配置时是从 git 上拉取的代码进⾏行行编 译;没有创建git,报错。
Cloning into ‘/var/folders/rg/f1ycrs553dq2z2dq7mt0mbh80000gn/T/d20160921-12686- 1o6vj1q’… fatal: Remote branch 0.1.0 not found in upstream origin
没有在 git 上增加对应的 tag 值,报错。
[!] Found multiple specifications
将私有仓库拉到本地时可能会存在两个。
因为 git 存在两个地址,分别是 git 和 http/https,所以有时候可能会在本地 repos 下出现两个基于同⼀一个 git 的仓库,仓库名字不不同。
因为⼀一开始 Lint 的时候是指定了了仓库名的,所以能通过,但 pod repo push 的 时候虽然指定了了 push 的仓库名,但因为没有指定校验的仓库名,⼀一旦你的 pod 依 赖了了私有仓库中的某个 pod ,校验时会出现类似 [!] Found multiple specifications xxxxLibrary :的错误。此时需要删除掉⼀一个私有仓库,然后重
新 push 才⾏行行。
pod Libraries should not include the extension
⼯工程中导⼊入了了第三⽅方 SDK ,包含有⼆二进制⽂文件,没有在 spec ⽂文件中配置。 需要
配置⼀一下路路径,保证 push repo 的时候,不不丢失⼆二进制⽂文件:
s.vendored_libraries = ['Class/SobotSDK/SobotLib/libSobotLib.a']
# :execution_position 选项有 [:before_compile, :after_compile, :any]
s.script_phase = { :name => "Script Name", :script => "echo 'Hello World'", :execution_position => :any , :shell_path => "/bin/sh"}
#ifdef DEBUG #define kAppKey @“123456789” #endif #ifdef RELEASE #define kAppKey @“987654321” #endif
编译时,找不不到宏定义 kAppKey ,需要设置查看: Project -> Build Settings -> Preprocessor Macros -> Debug DEBUG=1 Release RELEASE
对应 Spec ⽂文件设置: s.xcconfig = { "GCC_PREPROCESSOR_DEFINITIONS" => "RELEASE COCOAPODS=1" }
Shell Script Invocation Error Group sent 31754831 bytes received 54674 bytes 21206336.67 bytes/sec total size is 36763600 speedup is 1.16 /* com.apple.actool.errors / : error: There are multiple stickers icon set or app icon set instances named “AppIcon”. / com.apple.actool.compilation-results */ /Users/mengyueping/Library/Developer/Xcode/DerivedData/Example- fdeuhzzwrdwyjrfsdeusamwbippd/Build/Products/Debug- iphonesimulator/Example.app/Assets.car /Users/mengyueping/Library/Developer/Xcode/DerivedData/Example- fdeuhzzwrdwyjrfsdeusamwbippd/Build/Intermediates.noindex/Example.build/De bug- iphonesimulator/Example.build/assetcatalog_generated_info_cocoapods.plist Command /bin/sh failed with exit code 1
Pod 资源拷⻉贝脚本运⾏行行错误,⼤大致可能是不不同 Bundle 有同名资源或其他,在⾃自⼰己 ⼯工程 Build Phases -> Copy Pods Resources
去除 shell 脚本。
资源拷⻉贝脚本: "${SRCROOT}/Pods/Target Support Files/Pods-Example/Pods- Example-resources.sh"
duplicate symbol OBJC_IVAR$_ViewController._lastIndex in: /Users/mengyueping/Library/Developer/Xcode/DerivedData/Example- fdeuhzzwrdwyjrfsdeusamwbippd/Build/Products/Debug- iphonesimulator/libMain.a(ViewController.o)
duplicate symbol 重复符号,有可能是重复类,也有可能是在某个⽂文件中引⼊入了了 .m ⽂文件。 #import "ViewController.m"
Unable to run command ‘StripNIB TableViewListCell.nib’ – this target might include its own product.
xib⽂文件没有指定路路径,pod 的时候不不会下载 xib,xib⽂文件算是资源⽂文件的,需要另 外添加 s.resource 引⼊入。
s.source_files = "pod/classes/*/.{h,m}" s.resource = "pod/classes/TestViewController.xib"
或者把 xib 拷⻉贝到 bundle 中,直接指定资源⽂文件路路径为 bundle 。
s.resources = ['.bundle', '.strings']
Analyzing dependencies Fetching podspec for MyProject from ../ [!] Unable to find a specification for BaseSDK (= 1.0.2) depended upon by MyProject source ‘git@10.2.24.2oMengCode/Specs.git’ source
'https://github.com/CocoaPods/Specs.git' 没有配置私有库的索引库地址。
ld: ‘/Users/mengyueping/XesAppModule/XesAppUIKit/XesAppUIKitCode/Example/P ods/UMengUShare/UShareSDK/SocialLibraries/LaiWang/libLWApiSDK.a(LWApiRe quest.o)’ does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. file ‘/Users/mengyueping/XesAppModule/XesAppUIKit/XesAppUIKitCode/Example/P ods/UMengUShare/UShareSDK/SocialLibraries/LaiWang/libLWApiSDK.a’ for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
Build Settings -> Enable Bitcode -> NO
在头⽂文件中,引⼊入了了第三⽅方pod管理理的库的头⽂文件
Could not build module ‘XesAppFoundation’
-
ERROR | xcodebuild: XesAppFoundationLib/XesAppFoundation/XesAppFoundation.framework/Hea ders/XesAppRefreshBackNormalFooter.h:9:9: error: include of non- modular header inside framework module ‘XesAppFoundation.XesAppRefreshBackNormalFooter’: ‘Headers/Public/MJRefresh/MJRefreshBackNormalFooter.h’ [-Werror,- Wnon-modular-include-in-framework-module]
-
NOTE | xcodebuild: Headers/Public/XesAppKit/XesAppSavaDataManager.h:11o9: fatal error: could not build module ‘XesAppFoundation’
s.user_target_xcconfig = { "CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES" => "YES" }
为了了让⾃自⼰己的Pod被导⼊入时显示出良好的⽂文件层划分,subspec是必须的。 若subspec要依赖其它的subspec,则subspec的dependency后⾯面接的不不是⽬目录路路径,⽽而是specA/specB这种spec关系
在私有库引⽤用了了私有库的情况下,在验证和推送私有库的情况都要加上所有的资 源地址,不不然pod会默认从官⽅方repo查询。pod spec lint –sources=’私有仓库repo地址,github.com/CocoaPods/S…‘ pod repo push 本地repo名 podspec名 –sources=’私有仓库repo地址,github.com/CocoaPods/S…‘
引⽤用⾃自⼰己或第三⽅方的framework或.a⽂文件时在podsepc中应该这样写: s.ios.vendored_frameworks = “xxx//.framework”s.ios.vendored_libraries = “xxx//.a”
就是讲Podfile中的pod ‘库名’, :path =>’本地路路径’即可。这样在通常的修改代码中是不不需要执⾏行行pod update的,但是对于如果修改了了⽬目录结构(添加、删除或者移动 ⽂文件⽂文件)或者是修改了了Podspec⽂文件的配置的话,最好是运⾏行行⼀一下pod update的命令。普通修改代码的情况下就不不需要运⾏行行pod update命令和打tag了了。 pod ‘iOS- Test’, :path =>’../iOS-Test’
spec.resources = [“Images/.png”, “Sounds/”] 但是这些资源会在打包的时候直接拷 ⻉贝的app的Bundle中,这样说不不定会和其它资源产⽣生命名冲突
spec.resource = “Resources/MYLibrary.bundle” 把资源都放在bundle中,然后打包时候这个bundle会直接拷⻉贝进app的mainBundle中。使⽤用的时候在mainBundle中查找这个bundle然后再搜索具体资源 NSURL *bundleURL = [[NSBundle mainBundle] URLForResource:@”JZShare” withExtension:@”bundle”]; NSBundle *bundle = [NSBundle bundleWithURL:bundleURL]; UIImage *img = [UIImage imageNamed:icon inBundle:bundle compatibleWithTraitCollection:nil];
spec.resource_bundles = { ‘MyLibrary’ => [‘Resources/.png’], ‘OtherResources’ => [‘OtherResources/.png’] } 这种⽅方法利利⽤用 framework 的命名空间,有效防⽌止了了资 源冲突。 使⽤用⽅方法是先拿到最外⾯面的bundle,然后再去找下⾯面指定名字 的 bundle 对象,再搜索具体资源NSBundle *bundle = [NSBundle bundleForClass:[MYSomeClass class]]; NSURL *bundleURL = [bundle URLForResource:@”MyLibrary” withExtension:@”bundle”]; NSBundle *resourceBundle = [NSBundle bundleWithURL: bundleURL]; UIImage *img = [UIImage imageNamed:icon inBundle:bundle compatibleWithTraitCollection:nil];
如果私有库添加了了静态库或者dependency⽤用了了静态库 那么执⾏行行pod lib lint还有pod spec lint时候需要加上—user-libraries选项 否则会出现’The ‘Pods’ target has transitive dependencies错误
http://blog.xianqu.org/2015/08/pod-resources/
包含有 MRC ⽂文件类 方法⼀:
s.requires_arc = false s.source_files = "XesAppFoundation//.{h,m}" s.requires_arc = "XesAppFoundation/CommonComponent//.{h,m}"
方法二: 子 subspec
Pod::Spec.new do |s|
s.name = "AppFoundation"
s.version ="0.1.3.3"
s.summary = "App基础 源码仓库."
s.description = <<-DESC App项⽬目组封装了了⼀一些基础的⼯工具,仅限 App项⽬目组内使⽤用 DESC
s.homepage = "http://10.2.250.21/App"
s.license = { :type => "MIT", :file => "LICENSE" } s.author = { "raomeng" => "XXXX.com" } s.ios.deployment_target = "8.0"
s.source = { :git => 'git@10.2.250.21AppModuleiOS/AppFoundationCode.git', :tag => s.version}
s.default_subspec = 'AppFoundationARC'
non_arc_files = 'AppFoundation/MRC/*.{h,m}'
s.subspec 'AppFoundationARC' do |arc| arc.requires_arc = true
arc.source_files ="AppFoundation/CommonComponent/*/.{h,m}"
arc.exclude_files = non_arc_files
end
s.subspec 'AppFoundationNonARC' do |non_arc| non_arc.requires_arc = false
non_arc.source_files = non_arc_files
non_arc.dependency 'AppFoundation/AppFoundationARC'
end
s.dependency 'FMDB'
s.dependency 'MJRefresh'
end
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/13267.html