iOS之開發SDK(.framework和.bundle)(包括支援ATS和ssl雙向驗證及瘦身)
一,說明
我在開發在開發SDK之前,看了這2篇文章.1,http://blog.sina.com.cn/s/blog_87533a080102vzyg.html 2, http://www.jianshu.com/p/43d55ae49f59
現在總結一下我開發的過程:
我的SDK涉及到網路請求,圖片,介面的背景色,字型顏色等等;(接下來一個一個的說明);
分析:開發出來的SDK是給別人用的, 所以新建一個.plist檔案統一管理介面UI, 同時會將.plist檔案和圖片放到.bundle檔案中. 網路請求我用的是AFN,在匯入到SDK中時我將AFN的檔案的字首新增SH,為了避免重複(注:我將所有的檔案都添加了SH字首,不僅僅是AFN).
接下來是步驟:
1,新建專案:.framework建立選擇左邊的.命名為SHTestSDK.
建後這後是醬紫:
2,將SHTestSDK.h檔案刪除(為什麼刪除,因為用不到)
3,之後將你寫好的程式碼檔案匯入進入:(這步有個關於圖片.plist的讀取,還有其他的一些程式碼處理,在後面再說)
可以看到上面的所有檔案都加了SH字首,包括AFNetworking. Products下的SHTestSDK.framework為紅色字,因為還沒編譯,所以顯示不可用的狀態.
接下來是一些專案的設定:
4,雖然說支援了armv7和arm64.就不需要再新增armv7s,但是在在這裡我添加了.
5,Build Active Architecture Only 設定為NO的意思是當前打包的.framework支援所有的裝置.否則打包時只能用當前版本的模擬器或真機執行.
6,Build Setting 搜尋linking 設定Dead Code Stripping 為NO是編譯選項優化,包瘦身,(可不改) Mach-O Type 選中StaticLibrary (靜態庫) Xcode預設是動態庫.
7,如果.framework中有需要支援mrc檔案執行的:新增-fno-objc-arc
8,將需要呈現給來的標頭檔案,直接從Project拖到Public中. 不想呈現出來的.h檔案不建議拖到Private中. 這裡說明一點,如果你呈現出來的.h檔案中import其他的標頭檔案,那麼你import的其他標頭檔案也要呈現出來(即拖到Public中). 如果不想呈現出太多的.h檔案. 那麼在.h檔案中@class 宣告, 在.m檔案import.
9,編譯之前,要選擇release模式
10,選擇模擬器和真機各編譯一次Command+B . 此時.framework顯示為可用狀態. 如果想再次編譯,請先product-clean一次.
11,右鍵SHTestSDK.framework show in finder 一個用模擬器測試,一個用於ipa打包
以上就是.framework靜態庫的打包.
如果你開發出來的.framework很小,可以在終端用:lipo -create "真機版本路徑" "模擬器版本路徑" -output "合併後的檔案路徑" 合併成一個.framework. 如果太大,還是不要合併的好.
下面是.bundle的建立
在桌面新建資料夾SHTest 將圖片和.plist拷貝到裡面. 給SHTest新增字尾.bundle 就可以直接生成.bundle檔案.
然後就是講.framework和.bundle拖入到要整合的專案中,就可以了.
在.framework中讀取.bundle裡面的資源,用以下方法.
- (UIImage *)imagesNamesFromCustomBundle:(NSString *)imgName{
NSBundle *myBundle=[NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"這裡填寫bundle的名字" ofType:@"bundle"]];
NSString *img_path=[[myBundle resourcePath] stringByAppendingPathComponent:imgName];
return [UIImage imageWithContentsOfFile:img_path];
}
NSString *pathString1=[[NSBundle mainBundle]pathForResource:@"這裡填寫bundle的名字" ofType:@"bundle"];
NSBundle *resourceBundle=[NSBundle bundleWithPath:pathString1];
NSString *pathString=[resourceBundle pathForResource:@"這裡填寫.plist的名字" ofType:@"plist"];
NSDictionary *sources=[[NSDictionary alloc]initWithContentsOfFile:pathString];
這裡說明一點在iOS7系統下讀取bundle裡面的圖片顯示不出來.(原因沒找到).
注意,SDK包要支援ATS和SSL雙向驗證,請看我另外一篇部落格:iOS之支援ATS和ssl雙向驗證
這裡是將ca.cer,server.cer.client.p12證書都放在.bundle中.那麼在.framework的程式碼裡面獲取可以通過以下方法:
- (NSString *)trustCenyification:(NSString *)str{
NSBundle *myBundle=[NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"這裡填寫你的bundle名字" ofType:@"bundle"]];
NSString *path=[[myBundle resourcePath] stringByAppendingPathComponent:str];
return path;
}
//呼叫[self trustCenyification:@"server.cer"]
由於我.framework的UIWebView呼叫的是http頁面,所以我在info.plist設定了Allow Arbitrary Loads=YES.同時將info.plist拖到了.framework的Project中.那麼講這個SDK整合到其他的專案app中,也需要這麼設定.
下面是專案整合SDK(親測,是可以的)
注意跳轉到SDK中的控制器,用present跳轉.