Swift項目中製作framework的方法和遇到的一些坑

關於Swift集成framework的方法也查了很多資料,但大同小異,主要有兩種
1.利用cocoaTouch Framework建立如圖
進入xcode之後,裏面就是製作framework的界面和正常的項目一樣,不過不能運行(ps:這裏只是一個SDK並不是一個工程),只能編譯,編譯過之後就是就可以拿到framework的包,包的位置在products這個目錄下如圖

這裏解釋一下,圖中products目錄下就是我拿到的framework,右邊有代碼的文件是TestVC這個控制器類的測試代碼,XRFramework02是隨工程建立之後產生的,Helloworld(繼承自NSObject)、TestVC、TestVC02這三個文件是我建立的測試文件,後面兩個繼承自UIViewController

注:補充一下swift的訪問控制的關鍵字
fileprivate :如名字一樣,只有這個文件才能訪問.
private: 只能在作用域訪問.
interal: 默認,在整個模塊可以訪問.
public: 在模塊裏面是可以繼承或者重寫,在模塊外可以訪問,但不可以重寫和繼承.
open:在所有模塊都可以訪問,重寫和繼承.
 
open> public > interal > fileprivate > private

framework這裏簡單解釋一下,這裏會有運行環境不同分爲Debug和Release,在兩種環境下都有模擬器測試和真機測試,根據自身情況可以選擇不同運行環境和測試環境,編譯就是Command+B,編譯完成就可以在Products目錄下找到framework包,從find中找到包,拖入自己的項目,在需要使用framework的文件中導入包名

上圖是另外一個測試項目,上面導入包,下面就可以調用framework的代碼,因爲我在TestVC 類的代碼是利用Alamofire調用的天氣接口(網上找的),代碼直接在TestVC 類viewDidLoad添加的,所以進入TestVC 類就會執行被封裝進framework的代碼,有不明白的地方請看文中的圖片。
前面說的framework是直接編譯之後 ,然後去framework所在文件夾中拖出來,拖到項目中的,因此可能會有運行環境和測試環境問題,其實這方面的問題也簡單:在什麼運行環境和測試環境中做的framework,就在什麼環境下調用framework,一般也不會有什麼問題。
通用版的framework自作:

注: 引入動態庫的時候,需要在工程配置嵌入動態庫,不然的話會報錯

644971-20161213110419714-1368172846.png
如果工程是oc工程的話,還需要在build Setting裏面配置一個選項爲YES,否則也是運行報錯
644971-20161213110438464-905838743.png
合併模擬器版framework和真機版framework
分別用真機和模擬器build,右鍵選擇打開framework的目錄,會發現有兩個release版本的framework.
644971-20161213110538636-1831625074.png
使用 lipo 命令合併兩個版本的framework.
lipo -create ./Release-iphonesimulator/myFramework.framework/myFramework ./Release-iphoneos/myFramework.framework/myFramework -output ./myFramework

通用版本framwork:
通用版本的framework即將Debug/Release模式下編譯生成的framework(有兩種模擬器和真機環境下的應用場景),通用版本即是將Debug/Release模式下生成的framework合併成一個新的文件,然後將新生成的文件貼到Debug/Release的framework中,現在再拿這個新的framework就是通用版本的framwork。

使用腳本自動化生成和合並framework.首先添加新的target.

644971-20161213110718526-371092549.png


644971-20161213110723104-1696528295.png
 
8.在紅框裏面輸入一段腳本,然後選擇這個target進行build即可生成.

644971-20161213110742761-1009831627.png
腳本代碼:
FMK_NAME=myFrameworkINSTALL_DIR=${SRCROOT}/Products/${FMK_NAME}.frameworkWRK_DIR=buildDEVICE_DIR=${WRK_DIR}/Release-iphoneos/${FMK_NAME}.frameworkSIMULATOR_DIR=${WRK_DIR}/Release-iphonesimulator/${FMK_NAME}.frameworkxcodebuild -configuration "Release" -target"${FMK_NAME}" -sdk iphoneos clean buildxcodebuild -configuration"Release" -target"${FMK_NAME}" -sdk iphonesimulator clean buildif [ -d"${INSTALL_DIR}" ]thenrm -rf"${INSTALL_DIR}"fimkdir -p"${INSTALL_DIR}"cp -R"${DEVICE_DIR}/""${INSTALL_DIR}/"cp -R"${SIMULATOR_DIR}/""${INSTALL_DIR}/"# Uses the Lipo Tool to merge both binary files (i386 + armv6/armv7) into one Universal final product.lipo -create"${DEVICE_DIR}/${FMK_NAME}""${SIMULATOR_DIR}/${FMK_NAME}" -output"${INSTALL_DIR}/${FMK_NAME}"rm -r"${WRK_DIR}"open “${INSTALL_DIR}"
在SDK開發的工程中如果單獨建立Cocoa Touch Framework的項目做framework的話,無法確定開發需要集成的功能,是否正常,有時候需要一邊做功能另外可以運行測試功能,這裏也補充一下這種情況的做法,新建項目 -> 選擇target -> 選擇Add Target ->Cocoa Touch Framework,流程就是這樣的流程,下面上圖說明:





在上圖中第二步箭頭位置點擊選擇Add Target,然後再出來的窗口中選擇Cocoa Touch Framework,建立玩Cocoa Touch Framework,剩下的做法就和上面的做法一樣了。
最近發現一個新的問題,當framework中封裝的文件包含xib/storyBoard 時,直接調用viewcontroller是不能呈現xib/storyboard上面的內容的,因此想要呈現xib/storyboard的內容可以採取以下的辦法

這裏分兩種情況第一種針對viewcontroller的xib文件具體做法如下所示:
let bundle = Bundle.init(for: TestViewController.self)
let testVC = TestViewController.init(nibName: "TestViewController", bundle: bundle)
self.present(testVC, animated: true, completion: nil)
這裏的TestViewController是測試viewcontroller,帶有xib,如果viewcontroller不帶有 xib 關聯文件,在調用framework的時候,就可以直接push或者present調用,可以正常顯示。

第二種情況是framework帶有storyboard,然後調用framework的storyboard中的viewcontroller,這裏介紹使用方法如下:
let path = Bundle.main.path(forResource: "XRFramework05", ofType: "framework")
print("查看路徑:\(path!)")
let bundle = Bundle.init(path: path!)

let storyBoard = UIStoryboard.init(name: "TestMyStoryboard", bundle: bundle)
let loginVC = storyBoard.instantiateViewController(withIdentifier: "TestViewController02")
self.present(loginVC, animated: true, completion: nil)
這裏有一點需要注意,調用framework的viewcontroller的時候,需要在項目的Build Phase ->copy bundle resources中添加framework,這裏還有一個點需要注意就是上面的let loginVC = storyBoard.instantiateViewController(withIdentifier: "TestViewController02")這一行代碼中的identifier是storyboard的xib文件的storyboard ID沒有添加需要自己添加上,這樣才能正常調用,否則會報錯。

另外再補充一條,我這裏用的Swift 3.2,這裏使用範圍也是在Swift 3.2的項目,理論說情況類似,但是在Swift 4.0 中會拋棄一些方法,可能會出現問題,這裏暫時先不說。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章