iOS 封裝成Framework

本文參考文章:iOS Xcode9 封裝生成.framework - CocoaChina_讓移動開發(fā)更簡單


1.什么是庫?

庫是共享代碼的方式分成靜態(tài)庫和動態(tài)庫

靜態(tài)庫(.a和framework):鏈接時(shí)完整的拷貝到可執(zhí)行文件,被多次使用就有多份冗余拷貝(我們自己建的framework是靜態(tài)庫 )

動態(tài)庫(.dylib和framework):鏈接時(shí)不拷貝,程序運(yùn)行時(shí)由系統(tǒng)直接加載到內(nèi)存,供程序調(diào)用,系統(tǒng)只加載一次,多個程序共用,節(jié)省內(nèi)存。(系統(tǒng)的framework是動態(tài)庫?)

2. Framework與.a文件的區(qū)別?

.a文件是一個純二進(jìn)制的文件, 不能直接使用,至少要跟.h文件配合使用

framework除了二進(jìn)制文件還有資源文件,可以直接使用,.a+.h+sourceFile=framework

建議使用framework

3.為什么要使用靜態(tài)庫?

1 方便共享代碼,便于合理使用。

2 實(shí)現(xiàn)iOS程序的模塊化??梢园压潭ǖ臉I(yè)務(wù)模塊化成靜態(tài)庫。

3 和別人分享你的代碼庫,但不想讓別人看到你代碼的實(shí)現(xiàn)。

4 開發(fā)第三方sdk的需要。

4.制作靜態(tài)庫時(shí)的幾點(diǎn)注意:

1 注意理解:無論是.a靜態(tài)庫還.framework靜態(tài)庫,我們需要的都是二進(jìn)制文件+.h+其它資源文件的形式,不同的是,.a本身就是二進(jìn)制文件,需要我們自己配上.h和其它文件才能使用,而.framework本身已經(jīng)包含了.h和其它文件,可以直接使用。

2 圖片資源的處理:兩種靜態(tài)庫,一般都是把圖片文件單獨(dú)的放在一個.bundle文件中,一般.bundle的名字和.a或.framework的名字相同。.bundle文件很好弄,新建一個文件夾,把它改名為.bundle就可以了,右鍵,顯示包內(nèi)容可以向其中添加圖片資源。

3 category是我們實(shí)際開發(fā)項(xiàng)目中經(jīng)常用到的,把category打成靜態(tài)庫是沒有問題的,但是在用這個靜態(tài)庫的工程中,調(diào)用category中的方法時(shí)會有找不到該方法的運(yùn)行時(shí)錯誤(selector not recognized),解決辦法是:在使用靜態(tài)庫的工程中配置other linker flags的值為-ObjC。

4 如果一個靜態(tài)庫很復(fù)雜,需要暴露的.h比較多的話,就可以在靜態(tài)庫的內(nèi)部創(chuàng)建一個.h文件(一般這個.h文件的名字和靜態(tài)庫的名字相同),然后把所有需要暴露出來的.h文件都集中放在這個.h文件中,而那些原本需要暴露的.h都不需要再暴露了,只需要把.h暴露出來就可以了

從上面我們可以看出.a 和.framework的區(qū)別就是.a+.h+soureFile=.framework,這樣的話,我們還是直接封裝個.framework比較好


封裝framework步驟

1、打開xcode,新建工程

這里我使用的是Xcode9,選擇Cocoa Touch Framework,然后點(diǎn)next

2、創(chuàng)建功能類或者拖入已有的功能類

這里我創(chuàng)建的是ShowResult類。

3、實(shí)現(xiàn)功能類的功能

.h文件中

.m文件中

4、更改Xcode項(xiàng)目配置

在TARGETS下選中工程>Build Setting>搜索linking,然后幾個需要設(shè)置的選項(xiàng)都顯現(xiàn)出來。

1、首先是Dead Code Stripping設(shè)置為NO,網(wǎng)上對此項(xiàng)的解釋如下,大致意思是如果開啟此項(xiàng)就會對代碼中的”dead”、”unreachable”的代碼過濾,不過這個開關(guān)是否關(guān)閉,似乎沒有多大影響,不過為了完整還原framework中的代碼,將此項(xiàng)關(guān)閉也未曾不可。

2、然后將Link With Standard Libraries關(guān)閉,我想可能是為了避免重復(fù)鏈接

3、最后將Mach-O Type設(shè)為Static Library,framework可以是動態(tài)庫也可以是靜態(tài)庫,對于系統(tǒng)的framework是動態(tài)庫,而用戶制作的framework只能是靜態(tài)庫。

5、增加armv7s

更改后:

設(shè)置Headers

將你要公開的頭文件拖至Public下,要隱藏的放在Private或者Project下,當(dāng)然,隱藏的頭文件就無法再被引用。

然后需要在FrameworkTest.h(必須是公開的,否則無法引用)中將你所有要公開的.h引入。

打包

打包有兩種方式 一種是手動打包,另一種是用腳本,這里我用手動打包的方式。

1、選中模擬器,編譯程序command+B

2、選中測試機(jī),編譯程序command+B

3、在finder中找到framework文件

找到下圖中的FrameworkTest文件,這里有兩個同名文件,一個是Debug-iphoneos(真機(jī))下的,一個是Debug-iphonesimulator(模擬器)下的。

4、通過終端命令將兩個framework合為一個模擬器和真機(jī)都可使用的framework。

打開終端,輸入lipo -create命令,將

Debug-iphoneos下FrameworkTest.framework目錄下的FrameworkTest文件

拖拽到終端中,會自動有空格。然后將Debug-iphonesimulator下FrameworkTest.framework目錄下的FrameworkTest文件

拖拽進(jìn)來,也會自動有空格,然后輸入 -output,敲空格,在引入一個新的路徑。最后敲回車,這樣就合并了。

上面這段命令就是把真機(jī)和模擬器中的FrameworkTest合并成一個新的文件放在和newTest同級的文件夾new下,這個新文件后綴是.lipo,并不是我們要的FrameworkTest文件,怎么辦呢?我們的操作是按照人家說的把合成后的文件名字改成FrameworkTest替換原來的。而且,把后綴.lipo去掉!然后將新生成的這個FrameworkTest替換?原來的FrameworkTest(是指同時(shí)替換掉模擬器跟真機(jī)里面的FrameworkTest文件)。進(jìn)行下一步。

這里終端會有一個error

error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: can't move temporary file: /Users/lgj/Desktop/new/newTest to file: /Users/lgj/Desktop/new/newTest.lipo (Is a directory)

5、將修改后的framework拷貝出來就是我們最終制作的framework了。

使用

將我們封裝的framework拖拽到新的工程里面。

我們打開這個framework看看,發(fā)現(xiàn)只有Headers,里面有兩個.h,其中一個是FrameworkTest.h另一個就是ShowResult.h文件。

引入頭文件:

運(yùn)行得到[ShowResult show];的結(jié)果

至此,完成framework的封裝和使用。

總結(jié)

1、在制作framework或者lib的時(shí)候,如果使用了category,則使用改FMWK的程序運(yùn)行時(shí)會crash,此時(shí)需要在該工程中 other linker flags添加兩個參數(shù) -ObjC -all_load。(這點(diǎn)沒有親測)

2、帶有圖片資源的需要把圖片打包成Bundle文件,和framework一起拷貝到相應(yīng)的項(xiàng)目中。

3、公開的類中如果引用的private的類,打包以后對外會報(bào)錯,找不到那個private的類,可以把那個private的.h放到(也沒親測)

4、namespace 沖突。靜態(tài)庫用了某第三方庫,項(xiàng)目也用了同樣的第三方庫,在編譯的時(shí)候就會有 duplicate symbol 錯誤,因?yàn)橛袃煞萃瑯拥牡谌綆?。解決辦法就是把用到的第三方庫加上自定義前綴,包括類名、delegate 協(xié)議、常量名,尤其需要注意 Category 的方法名要修改。

5、圖片等資源文件用 bundle 方式打包。一個簡單制作 bundle 的方法:新建文件夾,重命名為 YourSDK.bundle,然后 Show Package Contents 打開,加入圖片。使用圖片的時(shí)候需要指明 bundle: [UIImage imageNamed:@"YourSDK.bundle/img.png"]。也可以用 Target 方式制作 bundle,比如 iOS Library With Resourceshttp://www.galloway.me.uk/tutorials/ios-library-with-resources/.

源自:http://www.itdecent.cn/p/87dbf57cfe4a

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容