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複製程式碼