使用CocoaPods開發lib庫
一、前言
上篇文章主要介紹瞭如何在App中使用CocoaPods
引入第三方庫,本篇文章將介紹怎樣使用CocoaPods
進行lib
庫的開發(lib
庫指靜態庫或動態庫)。
二、CocoaPods lib 建立
如果還未進行開發,需要利用CocoaPods
從零開始建立,那麼恭喜你,CocoaPods
會為你搭建好整個開發環境。利用pod lib create MyLibrary
命令,通過一些嚮導後,會自動幫你生成lib工程及demo工程。
生成的工程目錄如下:
MyLibrary.xcworkspace中的結構如下:
通過一個小小的命令,我們的工程框架就搭好了,可以在Pods工程裡新增程式碼和檔案,來實現我們的功能,然後在MyLibrary工程裡可以新增對lib庫的測試程式碼。
三、利用已有工程搭建CocoaPods lib工程
有時候,我們的lib
庫已經開發很久了,也有相應的demo
,只不過想升級一下逼格或xxx的原因,想通過CocoaPods
來管理,而不是傳統的.xcodeproj
或.xcworkspace
。
這種情況下,我們可以直接模仿上面的工程目錄,通過編寫Podfile
和podspec
,就可以了。
四、podspec
-
podspec簡介
podspec
是pod specification
的縮寫。通過上面的展示,已經可以知道podspec
是對lib
庫的配置檔案,Podfile
會根據該檔案進行檔案的載入,所以,podspec
的編寫也是非常重要的。
-
podspec建立
podspec的建立跟Podfile一樣,可以自己手動新建一個檔案,然後字尾改為.podspec
。也可以命令列執行pod spec create MyLibrary
。
-
podspec編寫
像Podfile
一樣,podspec
也有一套自己的語法(官網介紹)。
#一個podspec檔案包含一個Spec和若干個subspec,podfile可以引入整個podspec或subspec
Pod::Spec.new do |s|
#Pod的名稱,必填,如Podfile中pod 'AFNetworking',AFNetworking就是name
s.name = "MyLibrary" s.version = "0.0.1" #版本,必填
#簡介,必填
s.summary = "A short description of library."
#詳細的描述,支援多行字串,必填
s.description = <<-DESC
Add long description of the pod here.
DESC
#主頁,必填
s.homepage = "http://EXAMPLE/MyLibrary"
#遵守的開源協議,必填。注意GPL可能給公司帶來很大風險,不要輕易使用
s.license = "MIT"
#pod庫作者,必填
s.author = { "wangbingwf" => "wangbingwf@163.com" }
#平臺版本資訊,這裡表示支援iOS,7.0及以上系統
s.platform = :ios, "7.0"
#當支援多平臺時,使用deployment_target替代platform
#s.osx.deployment_target = '8.0'
#程式碼路徑,這裡雖然填寫的是git倉庫的路徑,但Podfile中使用path方式引入podspec時,並不會再從git上下載程式碼,而是使用本地的程式碼,所以就可以在這種方式下開發lib庫。
#這裡支援git,svn,http等。並且可以設定tag或version等資訊
s.source = { :git => "https://git.coding.net/yourgit/MyLibrary.git", :tag => s.version.to_s}
# ———— Subspecs ————————————————————————————————————#
# ———— MyLibraryCFiles ———————————————————————————————#
#建立一個subspec
s.subspec 'MyLibraryCFiles' do |subcfiles|
#subspec包含的程式碼檔案,上面source是路徑,這裡source_files是具體要包含哪些檔案
#其中**表示包含子目錄,*表示當前目錄下的所有檔案
#下面表示當前subspec包含MyLibrary/cfiles目錄及其子目錄中的所有.h和.c檔案;以及MyLibrary/log目錄下的所有.h和.c檔案
subcfiles.source_files = ["MyLibrary/cfiles/**/*.{h,c}",
"MyLibrary/log/*.{h,c}"]
#不包含的檔案
subcfiles.exclude_files = ["MyLibrary/jni/**/*",
"MyLibrary/profile/unit_test/*"]
#加入到pod庫中,被一起編譯
#這裡通常使用私有第三方庫時,需要依賴某個lib或framework時使用。
#新增如下選項後,會將.a新增到工程中,並且新增LIBRARY_SEARCH_PATHS路徑
#但是需要注意的是,如果使用pod package對該pod庫進行打包,這個.a並不會打進去。
#比如說使用pod package對MyLibrary打包成MyLibrary.a,inner.a並不會被編譯進MyLibrary.a。
#此時,如果如果對外提供MyLibrary.a,inner.a也同樣需要提供出去
subcfiles.vendored_libraries = "MyLibrary/lib/ios/inner.a"
#pod工程的配置
#對於HEADER_SEARCH_PATHS,對將設定的字串直接拷貝到xcode中,不會像上面source_files這樣使用相對路徑。
#所以,我在這裡先獲取當前路徑,再設定進去。最後加**表示recursive,即迴圈查詢子目錄的意思
$dir = File.dirname(__FILE__)
$dir = $dir + "/MyLibrary/cfiles/**" #$dir:/Users/wangbing/TempCode/MyLibrary/cfiles/**
subcfiles.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => $dir}
#demo工程的配置,上面是對pod工程的設定,當需要對demo工程設定時,使用user_target_xcconfig,這裡就不做介紹了
#相對於public_headers,這些檔案不會被公開給Demo
subcfiles.private_header_files = "MyLibrary/cfiles/**/*.h"
#保護目錄結構不變,如果不設定,所有標頭檔案都將被放到同一個目錄下
subcfiles.header_mappings_dir = "MyLibrary/cfiles/**"
end
# ———— MyLibraryMain ———————————————————————————————#
#建立一個subspec
s.subspec 'MyLibraryMain' do |submain|
#引入程式碼檔案
submain.source_files = "MyLibrary/main/**/*.{h,m}"
#設定公開標頭檔案
submain.public_header_files = "MyLibrary/main/public.h"
#設定資原始檔
submain.resource = "MyLibrary/resources/configFiles.bundle"
#設定MyLibraryMain模組依賴的系統庫,注意,這裡加的是系統庫
submain.frameworks = "SystemConfiguration"
#設定依賴,這裡可以依賴當前spec中的subspec,也可以依賴github上公開的開源庫,如'AFNetworking'。
submain.dependency "MyLibrary/MyLibraryCFiles"
end
end
-
podspec坑
-
坑——HEADER_SEARCH_PATHS
在我實際專案使用過程中,C
檔案的存在給我編寫spec
帶來了很大問題。
故事是這樣的,我們專案中要引用另一個團隊編寫的.a
庫,暫且稱為inner.a
。這個庫是C
寫的,同時,標頭檔案中存在多層巢狀。
這要求在使用該靜態庫時,要在HEADER_SEARCH_PATHS
中新增標頭檔案的路徑。
於是我一開始在podspec中是這麼寫的
subcfiles.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" =>"MyLibrary/cfiles/**"}
於是,編譯出錯了,找不到標頭檔案,因為這個設定在xcode中是這樣的:
Shit!為什麼不像上面似的,給加相對路徑呢,畢竟是路徑的設定嘛。但是也可以解決的,解決方案有三:
- 如果知道Demo工程和lib庫之間的路徑關係,可以通過
${PODS_ROOT}/../../MyLibrary/cfiles/**
來解決。 - 通過設定絕對路徑來解決:
在podspec
中使用ruby
指令碼,獲取當前路徑,而podspec
和lib
庫的位置一般不會變,所以最終使用了這種方式來設定HEADER_SEARCH_PATHS
。
$dir = File.dirname(__FILE__)
$dir = $dir + "/MyLibrary/cfiles/**" #$dir:/Users/wangbing/TempCode/MyLibrary/cfiles/**
subcfiles.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => $dir}
- 利用
CocoaPods
總會新增的兩個預設路徑,設定header_mappings_dir保護目錄結構不發生變化。
#設定cfiles及子目錄結構保持不變
subcfiles.header_mappings_dir = "MyLibrary/cfiles/**"
#將這些檔案設定為private_file或public_file
subcfiles.private_header_files = "MyLibrary/cfiles/**/*.h"
#因為我的C標頭檔案有巢狀,需要查詢子目錄,所以需要將non-recursive改為recursive
subcfiles.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "${PODS_ROOT}/Headers/Private/**"}
通過方法3同樣使用了${PODS_ROOT}
,與方法1有什麼區別呢?區別就是,如果按照方法3,可以忽略Demo工程與lib庫的路徑關係。因為在執行pod install
後,系統會在Pods
工程目錄下生成Private
和Public
目錄,就不用考慮原來cfiles
的路徑了,如下圖。
五、CocoaPods打包靜態庫
如果你開發的SDK並不想開源,那麼在通過CocoaPods管理並開發之後,還可以通過CocoaPods進行打包。生成framework
或.a
。打包命令是pod package
。
像上面的例子中,我的打包命令為:pod package MyLibrary.podspec --force --no-mangle --embedded --subspecs= MyLibraryMain
。然後將生成的framework和inner.a共同交給使用者使用即可。
這裡需要注意:
- 打包命令會根據
podspec
檔案下載程式碼到一個臨時檔案中進行打包,並不是使用的本地檔案,所以記得要提交併打tag。 - 上面的
HEADER_SEARCH_PATHS
問題,使用方法1和方法2同樣會導致pod package
失敗。因為你不知道cfiles
的路徑,無法新增到HEADER_SEARCH_PATHS
。但卻可以使用方法3! -
podspec
檔案中使用vendor
標識的framework
或libraries
,並不會真正編譯到最終的framework
中。這真的很讓我受傷,我查了好久。。。好久。。。好久。。。也正因為這個問題,我決定放棄pod package
方式。準備嘗試自己寫個指令碼進行打包,還在準備中。。。
六、總結
研究CocoaPods
的初衷是為了元件化開發,目前算是有了一點初步的認識。
我們把不同的功能模組放在不同的資料夾中,通過podspec
進行配置,通過podfile
進行引用,通過pod package
進行打包。一切是很方便的。
不過在我的實際應用中,目前在打包和public_headers
方面還有一些問題,I'm working on it!
最後,大家有疑惑的可以留言,寫的有問題的歡迎糾正!
相關文章
- ios開發分析:CocoaPods私有庫建立與使用iOS
- 玩轉iOS開發《建立CocoaPods開發庫》iOS
- iOS開發: 配置CocoaPods遠端私有倉庫iOS
- cocoaPods私有庫的建立與使用
- 使用CocoaPods打造元件私有倉庫元件
- iOS開發: CocoaPods遠端私有倉庫的維護-新增子庫iOS
- iOS開發: CocoaPods遠端私有倉庫的維護-新增依賴庫iOS
- iOS開發 Mac升級10.13.1 cocoapods 不能使用iOSMac
- CocoaPods私有庫
- 使用bundle管理多版本Cocoapods之間的協助開發
- CocoaPods 系列之一 製作公開庫
- pdf417lib庫封裝和使用封裝
- 製作 Cocoapods 庫
- iOS CocoaPods公有庫iOS
- iOS CocoaPods私有庫iOS
- 我的CocoaPods庫
- 自定義 Cocoapods 庫
- iOS CocoaPods使用iOS
- cocoapods使用教程
- CocoaPods公有庫的建立
- CocoaPods私有庫的建立
- iOS開發: CocoaPods遠端私有倉庫的維護-新增圖片資源iOS
- 最全CocoaPods使用教程
- CocoaPods使用總結
- 製作CocoaPods公有庫和私有庫
- 手把手教你釋出自己的 cocoapods 開源庫
- 手把手教你釋出自己的cocoapods開源庫
- CocoaPods 建立私有倉庫(ObjC)OBJ
- 給iOS庫新增Cocoapods支援iOS
- 使用js開發資料庫JS資料庫
- cocoapods安裝與使用
- 在 Swift 中使用 CocoaPodsSwift
- CocoaPods 安裝與使用
- 利用公司SVN伺服器使用CocoaPods管理自己的私有庫伺服器
- cocoapods 私有庫實踐筆記筆記
- iOS開發-AFNetWorking 3.0在CocoaPods上的坑iOS
- MongoDB JVM 開發庫使用簡介MongoDBJVM
- CocoaPods安裝和使用(SDWebImage)Web