Cocoapods作為OS X和iOS開發平台的類庫管理工具,已經非常完善和強大。通常我們用pod來管理第三方開源類庫,但我們也極有可能會開發一個用pod管理依賴關系的靜態類庫給其他人使用,而又不願意公開源代碼,比如一些SDK,那麼就需要打包成.a文件。本文將以一個依賴於ASIHTTPRequest的靜態類庫,來演示如何創建使用了CocoaPods的靜態類庫以及打包的過程。
開發靜態庫(Static Library)
創建靜態庫,有2種方法。
不基於pod手動創建(deprecated)
過程比較繁瑣,純體力活不推薦,大體步驟說下
1. 在Xcode中創建一個Cocoa Touch Static Library;
2. 創建Podfile文件;
3. 執行pod install完成整個項目的搭建;
4. 如果需要demo,手動創建示例程序,使用pod添加對私有靜態庫的依賴,重復執行pod install完成示例項目的搭建。
基於pod自動創建
只需要輸入pod的lib命令即可完成初始項目的搭建,下面詳細說明具體步驟,以BZLib作為項目名演示。
1. 執行命令pod lib create BZLib。在此期間需要確認下面4個問題。
Would you like to provide a demo application with your library? [ Yes / No ] yes Which testing frameworks will you use? [ Specta / Kiwi / None ] Kiwi Would you like to do view based testing? [ Yes / No ] No What is your class prefix? BZ
第一個問題詢問是否提供一個demo項目,通常選擇Yes,其他的可以根據需要選擇。命令執行完後,就會創建好一個通過cocoapods管理依賴關系的基本類庫框架。
2.打開BZLib.podspec文件,修改類庫配置信息,結果像這樣。
Pod::Spec.new do |s| s.name = "BZLib" s.version = "0.1.0" s.summary = "A short description of BZLib." s.description = < "[email protected]" } s.source = { :git => "https://github.com//BZLib.git", :tag => s.version.to_s } # s.social_media_url = 'https://twitter.com/' s.platform = :ios, '6.0' s.requires_arc = true s.source_files = 'Pod/Classes/**/*.{h,m}' s.resource_bundles = { 'BZLib' => ['Pod/Assets/*.png'] } s.public_header_files = 'Pod/Classes/**/*.h' s.frameworks = 'MobileCoreServices', 'CFNetwork', 'CoreGraphics' s.libraries = 'z.1' s.dependency 'YSASIHTTPRequest', '~> 2.0.1' end
按照默認配置,類庫的源文件將位於Pod/Classes文件夾下,資源文件位於Pod/Assets文件夾下,可以修改s.source_files和s.resource_bundles來更換存放目錄。s.public_header_files用來指定頭文件的搜索位置。
s.frameworks和s.libraries指定依賴的SDK中的framework和類庫,需要注意,依賴項不僅要包含你自己類庫的依賴,還要包括所有第三方類庫的依賴,只有這樣當你的類庫打包成.a或.framework時才能讓其他項目正常使用。示例中s.frameworks和s.libraries都是ASIHTTPRequest的依賴項。
podspec文件的詳細說明可以看Podspec Syntax Reference。
3. 進入Example文件夾,執行pod install,讓demo項目安裝依賴項並更新配置。
localhost:Example bryce$ pod install --no-repo-update Analyzing dependencies Fetching podspec for `BZLib` from `../` Downloading dependencies Installing BZLib 0.1.0 (was 0.1.0) Using Kiwi (2.3.1) Installing Reachability (3.2) Installing YSASIHTTPRequest (2.0.1) Generating Pods project Integrating client project
4.添加代碼。因為是示例,只簡單封裝一下GET請求。
添加BZHttphelper類,注意文件存放的位置在Pod/Classes目錄下,跟podspec配置要一致。
運行Pod install,讓demo程序加載新建的類。也許你已經發現了,只要新增加類/資源文件或依賴的三方庫都需要重新運行Pod install來應用更新。
編寫代碼。示例代碼很簡單,創建了一個GET請求的包裝方法。
#import "BZHttphelper.h" #import @implementation BZHttphelper - (void)getWithUrl:(NSString *)url withCompletion:(void (^)(id responseObject))completion failed:(void (^)(NSError *error))failed { ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:url]]; __weak ASIHTTPRequest *weakrequest = request; [request setCompletionBlock:^{ NSString *responseString = [weakrequest responseString]; completion(responseString); }]; [request setFailedBlock:^{ NSError *error = [weakrequest error]; failed(error); }]; [request start]; } @end
demo項目中調用測試。
#import "BZViewController.h" #import @interface BZViewController () { BZHttphelper *_httpHelper; } @end @implementation BZViewController - (void)viewDidLoad { [super viewDidLoad]; _httpHelper = [BZHttphelper new]; [_httpHelper getWithUrl:@"http://wcf.open.cnblogs.com/blog/u/brycezhang/posts/1/5" withCompletion:^(id responseObject) { NSLog(@"[Completion]:%@", responseObject); } failed:^(NSError *error) { NSLog(@"[Failed]:%@", error); }]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
成功打印,調用成功!
2014-11-23 16:52:23.946 BZLib[6329:96133] [Completion]:cnblogs ...
提交本地代碼庫
1. 修改s.source。根據你的實際路徑修改。
s.source = { :git => "/Users/name/workspace/BZLib", :tag => '0.1.0' }
2.提交源碼,並打tag。
git add . git commit -a -m 'v0.1.0' git tag -a 0.1.0 -m 'v0.1.0'
驗證類庫
開發完成靜態類庫之後,需要運行pod lib lint驗證一下類庫是否符合pod的要求。可以通過添加--only-errors忽略一些警告。
pod lib lint BZLib.podspec --only-errors --verbose ... BZLib passed validation.
打包類庫
需要使用一個cocoapods的插件cocoapods-packager來完成類庫的打包。當然也可以手動編譯打包,但是過程會相當繁瑣。
安裝打包插件
終端執行以下命令
sudo gem install cocoapods-packager
打包
命令很簡單,執行
pod package BZLib.podspec --library --force
其中--library指定打包成.a文件,如果不帶上將會打包成.framework文件。--force是指強制覆蓋。最終的目錄結構如下
|____BZLib.podspec |____ios | |____libBZLib.a
需要特別強調的是,該插件通過對引用的三方庫進行重命名很好的解決了類庫命名沖突的問題。
文中的示例代碼下載
BZLib
本文是通過pod及其插件實現了創建和打包的功能,如果對具體實現細節感興趣可以查看相關源碼,或者查看文末的擴展閱讀進一步了解。
擴展閱讀
Developing private static library for iOS with CocoaPods
Automatic build of static library for iOS and many architectures
Avoiding dependency collisions in iOS static library managed by CocoaPods