當前位置:名人名言大全網 - 短信平臺 - iOS SDK開發中的情形

iOS SDK開發中的情形

iOS SDK開發就是為某壹個應用場景、或領域、或需求,提供壹個已實現的、封裝好的、可供直接使用的模塊。

其主要由兩部分組成:用來為類型或常量聲明的頭文件列表、具體實現的二進制文件。

所以SDK開發中的主要問題點集中在:

1. 頭文件是否能被使用的工程索引到

2. 二進制文件是否能被使用的工程搜索到

本篇文章不寫制作SDK的具體步驟,僅僅討論制作SDK時的壹些情形。

SDK開發中關於頭文件設置:

凡是提供給外界使用的類、結構體、枚舉、常量等,定義它們的頭文件必須要在工程的Build Phases->Headers->public下面。並且這些頭文件都需要包含在與SDK工程同名的頭文件中(這條不是必須,只是這麽做會顯得更加規範。別人使用SDK的時候,只需要引入SDK同名的頭文件即可)

設置庫文件生成動態的還是靜態的:

Project Name->Target Name->Build Settings->搜索框搜“Mach”->修改“Mach-O Type”為動態或靜態,則相應可生成動態或靜態的庫文件。

先解釋說明以下圖片中出現的工程名字:

SDKDemo :制作的向外提供的SDK庫文件(與SDK工程名同名)

SDKApp :引用SDK庫文件(本文指的是SDKDemo)的App工程

SDKStatic :新建工程時,選擇iOS->Framework & Library->Cocoa Touch Static Library. 用來生成.a文件的工程

SDKFramework : ?是個Framework庫文件(可能是動態的,也可能是靜態的),用於模擬被SDK依賴的.framework文件

下面分幾種情況來討論SDK開發的註意事項:

1. 生成動態SDK庫文件。

創建工程的時候,根據默認配置編譯是生成動態庫的。

App工程中引入動態庫的時候,需要在

App工程:Project Name->Target Name->General->Embedded Binaries下添加引入的動態庫。否則運行時會報如下類型錯誤:

嵌入動態庫編譯後,生成的App文件中會多壹個Frameworks目錄(可右鍵.App文件查看包內容),裏面全是Embedded Binaries下添加的動態庫

2. 打包為靜態庫

SDK工程:Project Name->Target Name->Build Settings->搜索框搜“Mach”->修改“Mach-O Type”為靜態庫

App工程引入靜態庫很簡單,直接引入就行,不需要額外配置:

tips:

合並真機與模擬器版本時的命令格式為:

lipo -create?模擬器版本的路徑?真機版本的路徑 -output 合並後的版本存放路徑

1. 合並時lipo -create接收的模擬器版本和真機版本兩個參數的前後順序沒有關系,合並後的版本通過命令查看架構信息顯示結果是完全壹致的。模擬器架構信息顯示在前,真機架構信息在後。

2. 合並後的版本無論替換真機版本的Framework中的目標文件還是模擬器版本的Framework中的目標文件,App工程中引入被替換的Framework後在真機和模擬器上都能跑起來

首先創建SDKStatic工程,生成壹個.a文件。

該工程只是簡單繼承了UIButton,並重寫了initWithFrame方法。為每壹個MyButton對象默認生成標題和背景色:

生成的.a文件如下,可以看到裏面包含了MyButton.o文件:

在SDK工程中引入.a文件。下面分兩種情況來看生成的SDK庫文件:

1. SDK庫文件做成動態庫(設置方法看開頭部分)

.a文件內容被整合進了SDK動態庫文件中,引入App工程中時,只需要引入SDK動態庫就可以了

2. SDK庫文件做成靜態庫(設置方法看開頭部分)

包中的信息:

.a文件內容同樣被整合進了SDK靜態庫文件中,這個更好理解。引入App工程中時,只需要引入SDK靜態庫就可以了

總結下:

制作SDK庫時,如果有依賴的.a文件,則最終生成的SDK庫文件會合並.a文件的內容,而不論SDK庫文件是動態還是靜態的。

下面的SDKFramework是個Framework庫文件(可能是動態的,也可能是靜態的)

SDKFramework工程添加的內容和SDKStatic工程是壹樣的。也是自定義MyButton,默認生成標題和背景色(拷貝文件到工程):

SDKDemo工程自定義了MyView,默認生成的MyView對象添加了壹個MyButton按鈕和背景色:

1. 如果.framework文件是動態庫

a. SDK打包為靜態庫,如下:

靜態SDK包和動態SDKFramework.framework文件是彼此獨立的。引入靜態SDK包時,必須也導入SDKFramework.framework,否則編譯不過,因為靜態包有引入動態庫中的符號。

b. SDK打包為動態庫,如下:

兩者還是彼此獨立的。動態SDK包中會記錄依賴的動態.framework rpath,App運行時,dyld會根據這個信息去加載對應的.framework依賴文件。如果找不到App將會在啟動時奔潰...

2. 如果.framework文件是靜態庫

a. 首先SDK打包為動態庫看看:

經實踐,依賴的靜態庫會被整合進動態SDK包自身中。App中引入時,只需要導入SDK包就可以。我們在SDKApp中導入SDKDemo,運行可以看到如下效果:

b. 再看看SDK打包為靜態庫:

根據上面截圖中信息,App中導入SDK包時,也必須導入依賴的.framework了。否則編譯時將會出現如下圖所示找不到符號的錯誤:

追加導入依賴的.framework,再次編譯運行。OK!!!

總結:

1. 依賴的.framework為動態庫

制作的SDK庫文件不論動態還是靜態的。和依賴的.framework文件本身是彼此獨立的,不會發生符號整合的現象

2.?依賴的.framework為靜態庫

如果制作的SDK庫文件是動態的,則依賴的.framework靜態庫內容會被整合進SDK庫文件中

如果制作的SDK庫文件是靜態的,則彼此是獨立的

這裏又得分幾種情況討論:

1. Podfile中不使用use_frameworks! ?pods庫生成的是.a文件

a. 如果SDK制作成靜態庫:

? SDK靜態庫不會整合Pods裏三方庫中的符號,最終導入App工程時,需要SDK靜態庫、Pods中的三方庫文件壹起導入

b. 如果SDK制作成動態庫:

? Pods庫中的符號會被合並整合進入SDK庫中,導入工程時,只需要導入SDK包就OK了

2. Podfile中使用use_frameworks! ?pods庫生成的是.framework文件。其中Pods_工程名.framework文件是個靜態庫,管理的第三方庫生成的是framework動態庫

a.如果SDK制作成動態庫:

SDK中會包含引入三方庫的rpath,App中引入SDK包時,也必須引入三方庫,否則dyld加載不了指定庫導致App啟動時奔潰

b. 如果SDK制作成靜態庫:

靜態SDK中會忽略Pods中的庫中定義的符號(也即彼此是獨立的)。如果靜態SDK中引用了動態pods庫中定義的符號,只要在App工程中也導入pods中動態庫,並在embeded binaries中添加。壹樣是可以編譯運行的。

其實怎麽編譯,SDK工程中是個什麽情形都不重要。重要的是要明白庫文件的本質,及它是如何發揮作用的?在什麽階段發揮作用?然後學會查看編譯運行時的報錯信息,並配合使用otool、nm、lipo、ar、file等這些命令去查看庫文件的壹些信息,最終追蹤定位到問題。

原諒我最後都沒怎麽貼圖了,因為流程都和前面差不多。我也寫的手累了。如果妳還有什麽疑惑可以在下面評論,我會盡量及時回復。