iOS Xcode9 封裝生成.framework
iOS中.a與.framework庫的區別
參考這篇文章http://www.cocoachina.com/ios/20161012/17730.html
從上面我們可以看出.a 和.framework的區別就是.a+.h+soureFile=.framework,這樣的話,我們還是直接封裝個.framework比較好。
封裝framework步驟
1、開啟xcode,新建工程
這裡我使用的是Xcode9,選擇Cocoa Touch Framework,然後點next。
2、建立功能類或者拖入已有的功能類
這裡我建立的是ShowResult類。
3、實現功能類的功能
.h檔案中
.m檔案中
4、更改Xcode專案配置
在TARGETS下選中工程>Build Setting>搜尋linking,然後幾個需要設定的選項都顯現出來。
1、首先是Dead Code Stripping設定為NO,網上對此項的解釋如下,大致意思是如果開啟此項就會對程式碼中的”dead”、”unreachable”的程式碼過濾,不過這個開關是否關閉,似乎沒有多大影響,不過為了完整還原framework中的程式碼,將此項關閉也未曾不可。
2、然後將Link With Standard Libraries關閉,我想可能是為了避免重複連結
3、最後將Mach-O Type設為Static Library,framework可以是動態庫也可以是靜態庫,對於系統的framework是動態庫,而使用者製作的framework只能是靜態庫。
5、增加armv7s
更改後:
設定Headers
將你要公開的標頭檔案拖至Public下,要隱藏的放在Private或者Project下,當然,隱藏的標頭檔案就無法再被引用。
然後需要在FrameworkTest.h(必須是公開的,否則無法引用)中將你所有要公開的.h引入。
打包
打包有兩種方式 一種是手動打包,另一種是用指令碼,這裡我用手動打包的方式。
-
1、選中模擬器,編譯程式command+B
-
2、選中測試機,編譯程式command+B
-
3、在finder中找到framework檔案
找到下圖中的FrameworkTest檔案,這裡有兩個同名檔案,一個是Debug-iphoneos(真機)下的,一個是Debug-iphonesimulator(模擬器)下的。
4、通過終端命令將兩個framework合為一個模擬器和真機都可使用的framework。
開啟終端,輸入lipo -create命令,將
Debug-iphoneos下FrameworkTest.framework目錄下的FrameworkTest檔案
拖拽到終端中,會自動有空格。然後將Debug-iphonesimulator下FrameworkTest.framework目錄下的FrameworkTest檔案
拖拽進來,也會自動有空格,然後輸入 -output,敲空格,在引入一個新的路徑。最後敲回車,這樣就合併了。
上面這段命令就是把真機和模擬器中的FrameworkTest合併成一個新的檔案放在和newTest同級的資料夾new下,這個新檔案字尾是.lipo,並不是我們要的FrameworkTest檔案,怎麼辦呢?我們的操作是按照人家說的把合成後的檔名字改成FrameworkTest替換原來的。而且,把字尾.lipo去掉!然後將新生成的這個FrameworkTest替換原來的FrameworkTest。進行下一步。
這裡終端會有一個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看看,發現只有Headers,裡面有兩個.h,其中一個是FrameworkTest.h另一個就是ShowResult.h檔案。
引入標頭檔案:
執行得到[ShowResult show];的結果
至此,完成framework的封裝和使用。
總結
1、在製作framework或者lib的時候,如果使用了category,則使用改FMWK的程式執行時會crash,此時需要在該工程中 other linker flags新增兩個引數 -ObjC -all_load。(這點沒有親測)
2、帶有圖片資源的需要把圖片打包成Bundle檔案,和framework一起拷貝到相應的專案中。
3、公開的類中如果引用的private的類,打包以後對外會報錯,找不到那個private的類,可以把那個private的.h放到(也沒親測)
4、namespace 衝突。靜態庫用了某第三方庫,專案也用了同樣的第三方庫,在編譯的時候就會有 duplicate symbol 錯誤,因為有兩份同樣的第三方庫。解決辦法就是把用到的第三方庫加上自定義字首,包括類名、delegate 協議、常量名,尤其需要注意 Category 的方法名要修改。
5、圖片等資原始檔用 bundle 方式打包。一個簡單製作 bundle 的方法:新建資料夾,重新命名為 YourSDK.bundle,然後 Show Package Contents 開啟,加入圖片。使用圖片的時候需要指明 bundle: [UIImage imageNamed:@"YourSDK.bundle/img.png"]。也可以用 Target 方式製作 bundle,比如 iOS Library With Resourceshttp://www.galloway.me.uk/tutorials/ios-library-with-resources/.