iOS靜態庫SDK製做(包含第三方靜態庫)

前言

如下所涉及的框架和庫只針對iOS而言,不確保在其餘平臺也適用。html

最近因爲公司業務須要,要求封裝一個支付SDK,須要用到微信支付和支付寶,以前作過的Framework沒有依賴其餘第三方的庫因此比較好作,此次有所不一樣;一開始我想把支付寶和微信支付的SDK所有融合進來,折騰一天才發現我以前的想法有不少誤區,這樣是根本行不通的,不過最後仍是封裝成功了,下面把個人經驗分享出來,供有須要的同窗少走彎路。 製做以前最好把功課作足,看看靜態庫和動態庫究竟是什麼東西。ios

轉載請註明出處:來自LeonLei的博客http://www.gaoshilei.com安全

一. 靜態庫和動態庫的詳細介紹

咱們平時的工程中或多或少都要引入第三方的SDK,就算你沒有引入第三方的,至少引用過系統的Framework吧?其實這些SDK和Framework都屬於庫,庫又分爲靜態庫和動態庫,咱們平時導入的第三方SDK有的是Framework,有的是.a,到底哪些是動態庫,哪些是靜態庫呢?下面分別介紹靜態庫、動態庫,Framework和.a以及.dylib/.tbd區別微信

一. 靜態庫與動態庫

首先要解釋一下什麼是庫,庫(Library)其實就是一段編譯好的二進制代碼,加上頭文件就能夠供別人使用,通常會有兩種狀況要用到庫:app

  • 某些代碼須要給別人使用,可是咱們不但願別人看到源碼,就須要以庫的形式進行封裝,只暴露出頭文件。
  • 對於某些不會進行大的改動的代碼,比方說不少大公司經常使用且不多變更的模塊都會編譯成庫,這樣作的好處一是能夠節省編譯時間,二來對於代碼的管理也很是方便。

由於庫是已經編譯好的二進制文件了,編譯的時候只須要link一下,既然提到了link那就有不一樣的形式了,靜態和動態,與之相對應的就是靜態庫和動態庫框架

1. 靜態庫

平時咱們用的第三方SDK基本上都是靜態庫,靜態庫的幾個特色:學習

  • 在App項目編譯的時候會被拷貝一份編譯到目標程序中,至關於將靜態庫嵌入了,因此獲得的App二進制文件會變大。
  • 在使用的時候,須要手動導入靜態庫所依賴的其餘類庫。(好比說某個SDK中使用到了CoreMotion.framework,在使用的時候須要手動導入。有的SDK須要link十幾個系統庫,這個時候很是噁心,只能一個一個手動加,這是靜態庫一個很大的不便之處。)
  • 導入靜態庫的應用能夠減小對外界的依賴,若是導入的是第三方動態庫,動態庫找不到的話應用就會崩掉,例如Linux上常常出現的lib not found。
  • 靜態庫很大的一個優勢是減小耦合性,由於靜態庫中是不能夠包含其餘靜態庫的,使用的時候要另外導入它的依賴庫,最大限度的保證了每個靜態庫都是獨立的,不會重複引用。

2. 動態庫

這個是咱們最經常使用的一類庫,使用頻率最高的UIKit.framework和Fundation.framework都屬於動態庫,全部.dylib和.tbd結尾的都屬於動態庫。動態庫的幾個特色:測試

  • 平時使用的系統庫都放在iOS系統中,在你打包應用程序的時候這些庫不會拷貝到你的程序中,當須要使用的時候會動態從iOS系統中加載它們,由於這個緣由,動態庫也被稱做共享庫。編譯時才載入的特性,也可讓咱們隨時對庫進行替換,而不須要從新編譯代碼。
  • 這些庫是全部應用公用的,換一種說法就是節省了應用安裝包的體積,這是區別靜態庫很重要的一個特色,由於靜態庫使用一次就要拷貝一次,很是浪費資源。
  • 動態庫在製做的時候能夠直接包含靜態庫,也能自動link所須要的依賴庫。
  • 使用動態庫的時候不須要再次link依賴庫,即導即用,這個就厲害了。惟一須要注意的是在導入本身製做的動態庫時,須要在Embedded Binaries中導入,否則會報錯:image not found。此時這個動態庫會跟靜態庫同樣被拷貝到目標程序中進行編譯,蘋果又把這種Framework叫作Embedded Framework

關於動態庫要搞清楚一點,咱們本身製做的動態庫與系統動態庫的區別,咱們本身製做的動態庫引入App項目的時候須要embed進項目,也就是要拷貝到目標程序中,這就有點不像動態庫的特性了,蘋果這麼作也是考慮安全問題吧!
至於能不能正常上架,我也不清楚,查了大量資料都是抄來抄去沒說清楚,我猜想是不能上架的,由於通常的第三方SDK也都是靜態庫的形式,我猜想一個重要緣由是iOS的應用原本就是運行在沙盒裏面的,不一樣應用之間不能共享代碼,同時動態下載代碼蘋果確定也是明令禁止的,因此動態庫也就失去意義了。固然可能還有其餘因素,歡迎交流學習!微信支付

二. Framework、.a、.dylib/.tbd

1. Framework

Framework的英文釋意是框架,主要由Headers、binary文件、.bundle這三部分構成,除此以外還有Info.plist和Modules,後二者主要記錄Framework的版本之類的信息,通常都會刪掉,不作討論code

  • Headers
    包含咱們在製做Framework的時候暴露的頭文件,全部被暴露的.h都放在這裏。
  • binary文件
    整個Framework的核心,全部代碼都被編譯成了這樣一坨二進制文件,這裏要注意的是添加的依賴庫不會被編譯進來,用的時候還須要從新link其餘依賴庫。
  • .bundle
    資源文件都打包放在這裏。在製做Framework的時候不能夠把圖片直接放在項目中,不然製做好以後圖片是一張一張的出如今項目中很是亂,須要新建一個bundle將圖片放進去,這裏的bundle提供整個SDK的圖片資源。
    **注意:**圖片放進bundle以後不能夠用[UIImage ImageWithName:]讀取圖片。要先找到bundle包再拿圖片。

這裏要糾正一個誤區

不少人認爲系統的Framework就是動態庫,咱們本身製做的Framework就是靜態庫。

其實Framework既能夠是靜態庫也能夠是動態庫,這取決於編譯成的Mach-O(就是那個二進制文件)是動態庫仍是靜態庫,Framework本質上並非一個庫,它是蘋果爲了方便開發者提供了一種庫的打包方式,Framework會將Mach-O文件、頭文件和資源包全都包含進來,不須要你再手動整理,咱們也能夠經過Xcode來製做framework動態庫使用。 因此總結: Framework是庫的打包形式,既能夠是動態庫也是靜態庫。

2. .a靜態庫

這類靜態庫與Framework基本相似,不一樣的是在打包成.a文件的同時,還須要提供頭文件,使用時相較於Framework比較麻煩,(例如微信支付SDK使用的是.a,不一樣的是支付寶SDK是以framework的形式打包的)。.a這樣打包不夠方便,而Framework編譯完成暴露的頭文件都已經放好了。

3. .dylib/.tbd 動態庫

這類動態庫咱們也常常用,基本上都是系統提供的,通常不能本身製做,就算你經過其餘方式製做使用,也確定不能上架的,這裏沒什麼好講的。

二. Framework的製做

動態庫與靜態庫的製做流程基本同樣,包括頭文件的暴露等,惟一不一樣的是Mach-O文件的編譯形式。本節將介紹Xcode製做Framework的過程,本次製做的Framework靜態庫依賴其餘第三方靜態庫(Framework和.a)。

1> 新建工程

新建Framework工程

這裏要選Framework,若是選擇右邊的Static Library製做出來的是.a靜態庫。

2> 導入全部要打包的文件和其餘第三方靜態庫
正常導入要打包的文件就能夠了,在導入第三方靜態庫的時候要注意,不要選擇添加到target中,若是添加進去要去target裏面把第三方靜態庫刪掉(只需導入,不要添加進target)

導入第三方靜態庫

導入第三方靜態庫以後再link依賴的系統庫,像這樣
link依賴庫

注意上面的運行目標,由於我用的是Xcode8,最低支持到iOS8。
要打包的文件和第三方靜態庫所有導入完成
全部文件導入狀況

3> 項目性質修改
把項目的membership需改成public,不然頭文件暴露將會不正常

修改項目的membership

4> 暴露頭文件
將頭文件暴露出去,供外界使用,全部的編譯文件都在Project中,須要右擊添加到public裏面

暴露頭文件

5> 選擇Mach-O的編譯方式
這是最重要的一步,這一步決定咱們製做出來的是靜態庫仍是動態庫,默認選擇的是Dynamic Library,要手動選擇Static Library

Mach-O 形式

6> 編譯
若是你的依賴庫裏面有lib開頭的dylib動態庫,此時應該會報錯

動態庫連接報錯

什麼意思呢?大概就是沒找到對應的庫文件,由於tbd是蘋果提供的新的動態庫格式,以前都是dylib,不知道這裏又抽什麼風,下面解決問題。

7> tbd動態庫報錯修改
先把原來的.tbd刪掉,而後再次添加,這個時候選擇add other,在彈出的窗口中按快捷鍵shift + command + G 調出finder的前往窗口,輸入/usr/lib,而後添加相應的dylib動態庫

修改的動態庫

替換完成以後從新編譯項目,生成Framework(可在Product文件中右擊在finder中顯示找到)

8> 使用
新建一個文件夾,將製做好的靜態庫拷貝出來放進去,再將第三方靜態庫拷貝到相同的文件夾中,此時只要將這個文件夾提供給外界使用就能夠了,這是我寫的測試demo驗證打包好的SDK是否能夠正常使用

製做完成使用

至此咱們已經完成了Framework中包含其餘第三方靜態庫的製做。
若是須要製做動態庫,只須要在第5步中將Mach-O的形式改成Dynamic Library就能夠了,其餘步驟同樣

若是有問題請在留言區留言,或者郵件給我,互相交流學習!

相關文章
相關標籤/搜索