原文地址:
http://www.reibang.com/p/1d6cd04ff1e3
iOS SDK開發(fā)系列:
...
待更新..
參考鏈接
一、關(guān)系
文中提到的目標程序和庫文件的關(guān)系
關(guān)系.png
iOS SDK類型.png
靜態(tài)庫和動態(tài)庫都屬于通過封裝代碼開放接口從而達到保護核心代碼的目的耸黑。諸如AFNetworking或SDWebImage我們稱之為開源庫否副,是可以看到源代碼的。
靜態(tài)庫和動態(tài)庫各自的特點:
靜態(tài)庫
.a稱為庫崎坊,.framework稱為框架备禀,二者可以統(tǒng)稱為庫。
.a庫文件和頭文件分離奈揍,.a是一個純二進制文件曲尸,不包含資源文件和頭文件;
.framework的庫文件和頭文件打包在一起男翰,可以包含資源文件另患,在使用上會更便于管理。
之所以稱為靜態(tài)蛾绎,是因為在編譯時候昆箕,會直接拷貝一份,復制到目標程序中租冠,目標程序中的這份靜態(tài)庫代碼就不再發(fā)生改變了鹏倘。靜態(tài)庫中的類名和目標工程中的類名如果重復,會發(fā)生編譯錯誤顽爹。因此纤泵,如果靜態(tài)庫中用到第三方開源庫,最好對其類名镜粤、全局變量進行修改(加前綴)捏题,靜態(tài)庫的自身類名和全局變量也要加上特別前綴玻褪,以避免目標程序使用時,重復的原因造成無法編譯通過公荧。
動態(tài)庫
系統(tǒng)動態(tài)庫格式:.tbd带射、.dylib、.framework循狰,自己創(chuàng)建的默認為格式為.framework窟社。
對于iOS系統(tǒng)動態(tài)庫,如UIKit.Framework來說晤揣,編譯時不會被拷貝到目標程序中,目標程序只會儲存指向動態(tài)庫的引用朱灿,等到程序運行時昧识,動態(tài)庫才會按需加載。優(yōu)點就是盗扒,不影目標程序的體積跪楞,同一份庫多個程序使用,因此也稱之為共享庫侣灶。這是系統(tǒng)動態(tài)庫與靜態(tài)庫的根本區(qū)別甸祭。
蘋果公司在iOS8開始,開放了動態(tài)庫創(chuàng)建褥影。有人說是開放APP Extension的緣故池户,Extension和App是兩個分開的可執(zhí)行文件,同時需要共享代碼凡怎,這種情況下動態(tài)庫的支持就是必不可少的了校焦。
但是對于我們自己創(chuàng)建的iOS動態(tài)庫,確卻的說是Embedded Framework统倒,因為它最終會被拷貝到目標程序中寨典。因此目標程序中,還是有一個拷貝房匆,跟靜態(tài)庫無差別耸成。在目標程序中的文件,都在打包時候經(jīng)過蘋果證書簽名浴鸿,因此井氢,這個打包在目標程序中的Embedded Framework如果被替換,是需要重簽?zāi)繕顺绦虻脑懒础6姨O果現(xiàn)在已經(jīng)不允許從沙盒加載Embedded Framework毙沾,也就是以前通過程序運行時動態(tài)下發(fā)動態(tài)庫到沙盒中,加載新的動態(tài)庫從而達到熱更的目的宠页,已經(jīng)行不通了左胞。在模擬器下寇仓,這種方式是被允許的。
還有一個問題烤宙,包體提交App Store遍烦,如果包含動態(tài)庫,動態(tài)庫中不允許包含模擬器的架構(gòu)x86_64和i386躺枕。這個未經(jīng)驗證
對于iOS使用動態(tài)庫服猪,好處在于:動態(tài)庫和目標程序,可以包含同樣名字的類名拐云、全局變量罢猪。因此在開發(fā)動態(tài)庫時,無需擔心動態(tài)庫中的類名叉瘩、全局變量與目標程序的類名膳帕、全局變量重復的問題,也不需要對第三方開源庫進行任何處理薇缅。這是測試demo動態(tài)庫中和目標程序都存在ViewController危彩,編譯是通過的。
下面介紹下如何開始SDK開發(fā)泳桦。
二汤徽、創(chuàng)建工程步驟
1、創(chuàng)建workspace灸撰,用于關(guān)聯(lián)Demo工程和SDK工程谒府;
2、創(chuàng)建SDK工程浮毯,工程配置修改狱掂;
3、創(chuàng)建Demo工程亲轨;
4趋惨、將SDK工程和Demo工程的xcodeproj文件拖入workspace,實現(xiàn)編譯聯(lián)動惦蚊。
工程之間的關(guān)系
庫和目標程序的關(guān)系.png
bundle 文件不是必須的器虾,除非SDK的功能需要用到圖中的文件。
創(chuàng)建 workspace
輸入workspace名字 蹦锋,選擇存放目錄:
創(chuàng)建workspace.png
完成后生成這個文件:
創(chuàng)建workspace完成.png
打開是一個空目錄:
空目錄.png
創(chuàng)建 SDK 工程兆沙,工程配置修改
.framework格式 靜態(tài)庫 / 動態(tài)庫
1、選擇Cocoa Touch Framework的選項
創(chuàng)建framework格式靜態(tài)庫1.png
2莉掂、填寫工程名葛圃,包名之類的
創(chuàng)建framework格式靜態(tài)庫2.png
3、這個地方可以修改類型
Build Settings->Mach-O Type->Dynamic Library動態(tài)庫 /Static Library靜態(tài)庫
創(chuàng)建framework格式靜態(tài)庫3.png
.a格式 靜態(tài)庫
1、選擇Cocoa Touch Static Library的選項
創(chuàng)建a格式靜態(tài)庫工程1.png
2库正、填寫工程名曲楚,包名之類的
創(chuàng)建a格式靜態(tài)庫工程2.png
工程創(chuàng)建完畢,可以看到二者的區(qū)別:
區(qū)別.png
如果是.a格式的靜態(tài)庫褥符,對外的.h是獨立于.a之外的龙誊;
如果是.framework格式的靜態(tài)庫,對外的.h是包含在.framework中的喷楣。
編譯涉及到平臺架構(gòu)的區(qū)別趟大,不清楚的可以點這里
此處可以選擇編譯的是編譯類型:
模擬器任選一個即可
真機選擇Generic iOS Device
編譯類型.png
工程創(chuàng)建完畢,默認有對外頭文件铣焊,對外頭文件設(shè)置的位置有所區(qū)別:
.a工程逊朽,處于Copy Files模塊中:
a頭文件添加.png
.framework工程,處于Headers模塊中:
framework頭文件添加.png
后續(xù)如果有新增對外頭文件曲伊,可以在這兩個地方添加叽讳。
Build Phases中如果沒有Headers一欄,可以通過如下方式添加:
添加Header模塊1.png
添加Header模塊2.png
庫工程配置修改
iOS Deployment Target
Build Settings->iOS Deployment Target->SDK支持最低系統(tǒng)版本
支持的最低iOS系統(tǒng)版本.png
Other? Linker Flags
Build Settings->Other Linker Flags--ObjC
庫工程中使用Category需要添加這個標志熊昌。
發(fā)現(xiàn)Xcode(10.3)绽榛,Cocoa Touch Static Library進行創(chuàng)建.a格式靜態(tài)庫湿酸,會自動添加-ObjC婿屹。
Other? Linker Flags.png
Enable Bitcode
Build Settings->Enable Bitcode-NO
bitcode.png
創(chuàng)建 Demo 工程
就是創(chuàng)建普通的iOS工程,用于測試SDK工程的接口推溃。
關(guān)聯(lián) SDK 工程和 Demo 工程
先打開步驟1創(chuàng)建的workspace昂利,拖動SDK工程文件和Demo工程文件到workspace中。
工程拖入workspace1.png
工程拖入workspace2.png
此時兩個工程已經(jīng)可以聯(lián)動編譯了铁坎。
三蜂奸、接口測試
SDK工程中,新增如下接口:
SDK.h
#import@interfaceSDK:NSObject+(instancetype)shareInstance;-(void)initSDKWithHandler:(void(^)(NSString*message))handle;@end
SDK.m
#import"SDK.h"@implementationSDK+(instancetype)shareInstance{staticSDK*_instance;staticdispatch_once_t onceToken;dispatch_once(&onceToken,^{_instance=[[SDK alloc]init];});return_instance;}-(void)initSDKWithHandler:(void(^)(NSString*message))handle{NSString*msg=@"init sdk success";if(handle){handle(msg);}}@end
導入Demo工程中調(diào)用該接口
#import"ViewController.h"#import@interfaceViewController()@end@implementationViewController-(void)viewDidLoad{[superviewDidLoad];// Do any additional setup after loading the view.[[SDK shareInstance]initSDKWithHandler:^(NSString*message){NSLog(@"%@",message);}];}@end
總的工程workspace結(jié)構(gòu)如下:
項目結(jié)構(gòu).png
只要不是修改SDK名稱或者SDK新增頭文件硬萍,Demo工程中的SDK文件不需要每次都更新扩所,因為編譯Demo時會自動幫你聯(lián)系SDK工程,也就是我們所說的聯(lián)調(diào)朴乖。
控制臺打幼嫫痢:
2019-08-21 15:51:02.475403+0800 Demo[4316:160026] init sdk success
測試成功。
總結(jié)
iOS靜態(tài)庫的基本概念买羞;
iOS靜態(tài)庫的兩種創(chuàng)建方式(.a袁勺、.framework)。
關(guān)于靜態(tài)庫和動態(tài)庫的區(qū)別可以自己去了解畜普。一般我們開發(fā)的都是靜態(tài)庫期丰。