SDK的製作詳解,SDK製作詳解
一個簡單的SDK製作是很容易的,複雜的sdk其實就和複雜化的應用一樣,都是從簡單開始的,這裡介紹一下sdk的簡單製作
步驟:
1.建立sdk,公開檔案
2.編譯、擷取sdk檔案
3.匯入工程,設定檔
4.解決錯誤,完成
1.建立sdk,公開檔案
然後起個需要的名字
建立出這樣的sdk,自動產生的檔案和普通工程的viewController一樣都是可以刪的,不喜歡的可以儘管刪
介紹使用sdk裡面的類和帶xib的控制器
先說類,用這個自動產生的,在類裡面添加一個列印的方法
.h檔案
#import <Foundation/Foundation.h>@interface SDK : NSObject-(void)sdkLog;@end
.m檔案
#import "SDK.h"@implementation SDK-(void)sdkLog{ NSLog(@"sdkAction");}@end
就是這樣普通,然後說下控制器
先建立一個控制器,名為:
SDKViewController 記得勾選添加xib,等下要說明一下暴露檔案的
然後在xib上隨便添加點什麼東西,等下跳轉
自己能確定跳轉來的是我們sdk裡的這個控制器就行了
接下來的比較重要,我們做一個sdk靜態庫就是為了保護和不讓人看見裡面的實現內容,但如果是需要被人調用的部分,還是需要暴露出來的,那怎麼做呢?
按圖操作就能把檔案暴露出來,暴露需要被調用的標頭檔,注意,如果暴露的標頭檔裡包括控制器,而且控制器是有xib檔案的,那麼xib一定也得暴露出來,否則等下在其他工程裡調用的時候,找不到xib的
到這裡sdk製作就告一段落,sdk包分三種:真機sdk包,虛擬機器sdk包,兩種包的合并,合并的就不說了,有興趣的百度下,一般真正在使用時是不用合并包的,用微博,qq什麼sdk的時候就知道,都是把兩種包分開的,因為合并的包比較大這樣會導致打包後的ipa包變大,引起使用者的不滿,浪費使用者流量。
2.編譯、擷取sdk檔案
接下去-> 編譯,選擇真機或者Geneic iOS Device編譯出來的就是真機sdk,選擇虛擬機器編譯出來的就是虛擬機器sdk
真機sdk:
選擇真機或者Geneic iOS Device編譯,原本紅色的libSDK.a就變成灰色,表示檔案存在
選中libSDK.a點擊右鍵選擇show in finder就能看到內容了,
注意這裡檔案夾的名字,Debug-iphoneos檔案夾是真機sdk檔案夾,等下看看虛擬機器sdk檔案夾的名字
這裡include檔案夾裡面的檔案就是暴露的檔案,在把libsdk.a加進工程時也要把裡面的檔案一起加進去的,真機和虛擬機器sdk使用是一樣的,先看虛擬機器的問題
虛擬機器sdk:
這裡先clear一下,把剛才編程的真機sdk包清理掉才能看到xcode7虛擬機器帶來的問題,清理完後libSDK.a就是紅色的了,不存在
然後選擇虛擬機器編譯,如果你用的是xcode7,你會發現怎麼編譯,libSDK.a都是紅色的,這個是xcode7的bug,之前有人說xcode7沒法編譯虛擬機器的sdk,這是錯的,不用著急,照樣可以產生,如果編譯提示success其實虛擬機器sdk還是成功產生的,只是在xcode上看不到,這時不用clear,把真機sdk包也一起編譯了,產生了真機的sdk,這裡點擊libsdk.a檔案show in finder,這裡就看到的是上面那種情況
注意
之前提過檔案夾的名字,現在看到的檔案夾還是真機sdk的檔案夾,就是你再點虛擬機器的編譯多一次進來,也會發現是真機的檔案夾,這時候按 command+️,返回上層檔案夾
現在就看到兩個檔案夾了,左邊的是真機sdk檔案夾,右邊的是虛擬機器sdk檔案夾,點擊虛擬機器檔案夾進去就能看到和真機sdk一樣的內容,xcode7可以通過這種方式來找虛擬機器sdk檔案夾的
3.匯入工程,設定檔
用虛擬機器示範下
建立一個新工程,例如命名test
把include裡面的檔案夾還有.a檔案拉到工程裡面如果沒勾選要記得勾選add to targets
然後配置一下,選擇在配置裡搜尋search,如果裡面的library search paths為空白,那麼雙擊空處箭頭的地方給它添加一個庫的尋找路徑,給.a檔案路徑如 $(PROJECT_DIR)/text/libSDK.a
或者自己加可以找到.a檔案的其他路徑也可以
不然會找不到.a檔案
再搜尋other linker,給other linker flags加上 -Objc 和 -all_load,-all_load視情況加,可不加下面有說明
Other Linker Flags:其他連結標籤
設為"-ObjC"
當匯入的靜態庫使用了類別,需要設為-ObjC,就算沒有使用也給配上,預防以後使用其他的sdk裡面有
補充:Other Linker Flags設定的值介紹
-ObjC:加了這個參數後,連結器就會把靜態庫中所有的Objective-C類和分類都載入到最後的可執行檔中
-all_load:會讓連結器把所有找到的目標檔案都載入到可執行檔中,但是千萬不要隨便使用這個參數!假如你使用了不止一個靜態庫檔案,然後又使用了這個參數,那麼你很有可能會遇到ld: duplicate symbol錯誤,因為不同的庫檔案裡面可能會有相同的目標檔案,所以建議在遇到-ObjC失效的情況下使用-force_load參數。
-force_load:所做的事情跟-all_load其實是一樣的,但是-force_load需要指定要進行全部載入的庫檔案的路徑,這樣的話,你就只是完全載入了一個庫檔案,不影響其餘庫檔案的按需載入
這樣就配置完了
最後是校正是否能使用sdk了
可以在appdelegate裡面這樣寫
AppDelegate.m檔案裡先匯入工程使用的控制器
#import "ViewController.h"
在下面這個方法裡添加導航控制器,因為要跳轉到sdk裡面的控制器需要
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; ViewController *rootViewController = [[ViewController alloc] init]; UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:rootViewController]; self.window.rootViewController = nav; [self.window makeKeyAndVisible]; return YES;}
然後在viewController.m裡面
或者你如果想看得更明顯一點自己加button,加跳轉事件才去跳轉到sdk裡,這裡我就偷懶一下了
1 #import "ViewController.h" 2 #import "SDK.h" 3 #import "SDKViewController.h" 4 5 @interface ViewController () 6 7 @end 8 9 @implementation ViewController10 11 - (void)viewDidLoad {12 [super viewDidLoad];13 14 15 SDK *sdk = [[SDK alloc]init];16 [sdk sdkLog];17 18 SDKViewController *sdkCtl = [[SDKViewController alloc]init];19 [self.navigationController pushViewController:sdkCtl animated:YES];20 }21 22 @end
完成編譯運行
4.解決錯誤,完成
寫完編譯工程,如果出現類似這樣的情況
那是因為虛擬機器sdk的編譯包也有不同的像i386,x86_64,arm,arm64等,這是我們所需要包的Charts.framework不對,這裡不細說了,想瞭解的可以百度i386,x86_64,arm,arm64的區別,這裡最簡單直接的解決辦法是在編譯sdk時選擇什麼虛擬機器,那運行時也用什麼虛擬機器,但如果sdk編譯時間用5s、6、6 plus、6s、6s plus編譯,那麼這些的sdk在這些虛擬機器上都能通用,這樣也不用考慮那麼多了。
framework製作靜態庫可以和.a是一樣的
想製作全部通用的虛擬機器sdk包可以參考http://blog.csdn.net/lizhongfu2013/article/details/12648633
最後運行列印出了
sdkAction
介面上顯示了sdk裡控制器裡的介面,恭喜你完成了。
看上面似乎很多內容,其實做多幾次瞭解之後就知道是很簡單的,frameword製作靜態庫時也是這樣,動態庫就不一樣了,也不推薦工程裡用自己做的動態庫,app store會審核不通過的,然後是debug和release模式,製作真正的sdk時應該在product->scheme->edit scheme的Build Configuration裡面把Debug切換為release然後再編譯使用,和工程裡面是一樣的道理,如果都完成了應該換。