1. 程式人生 > >iOS之開發SDK(.framework和.bundle)(包括支援ATS和ssl雙向驗證及瘦身)

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跳轉.

二,結束語

補充: 如果靜態庫中有category類, 則要在靜態庫的專案中[Other Linker Flags]新增引數[-ObjC]或[-all_load]. 如果靜態庫中新增.tbd或.dylib, 則在你需要整合的專案中也要新增.並且在[Build Setting]中將 [AllowNo-modular Includes inFramework ...]設定為YES. 關於打包靜態庫的填坑記錄可以看這篇:http://www.jianshu.com/p/43d55ae49f59 關於編譯優化,包瘦身,這有2篇文章,有興趣可以看看: 1,http://blog.csdn.net/bravegogo/article/details/52699698 2,http://www.jianshu.com/p/11710e7ab661