首先我們通過新建菜單的 Framework & Library 創(chuàng)建一個 Cocoa Touch Framework 項目QJWiFi
1涨共、內(nèi)容:
創(chuàng)建需要打包的代碼测暗,將需要公開調(diào)用的接口方法聲明為public(供其他 module 調(diào)用)
2、framework 生成:
將運行設(shè)備選擇為任一 iOS 模擬器蚂踊,然后使用 Shift + Cmd + I
進行 Profiling 編譯(同時生成 debug 與 release 版本约谈,如果是 Cmd + B
,則只生成 debug 版本)犁钟。我們可以在項目的生成的數(shù)據(jù)文件夾 中找到QJWiFi.framework
(對應(yīng)項目的 ~/Build/Products/Release-iphonesimulator)
3棱诱、版本兼容:
將運行設(shè)備選擇為真機,使用 Shift + Cmd + I
進行 Profiling 編譯涝动,此時我們的生成文件目錄下有(Debug-iphonesimulator迈勋、Release-iphoneos、Release-iphonesimulator)三個文件醋粟,我們需要將其中的一些內(nèi)容合并
合并A:合并 Release-iphoneos 與Release-iphonesimulator 文件下的二進制文件
終端命令:
cd /Users/xxx/Library/Developer/Xcode/DerivedData/QJWiFi-fejnkmidkzkbocbjnkbgoclwbobz/Build/Products
lipo -create Release-iphoneos/QJWiFi.framework/QJWiFi Release-iphonesimulator/QJWiFi.framework/QJWiFi -output Release-iphoneos/QJWiFi.framework/QJWiFi
lipo -info QJWiFi // 查詢framework 支持的 cpu 架構(gòu)
Architectures in the fat file: QJWiFi are: i386 x86_64 armv7 arm64
合并B:拷貝Release-iphonesimulator/QJWiFi.framework/Modules/QJWiFi.swiftmodule 文件夾下的所有文件到 Release-iphoneos 相應(yīng)的文件夾中靡菇,現(xiàn)在 Release-iphoneos 文件中的 QJWiFi.framework 就是我們需要的架包重归。
4、測試:
新建一個 Swift 項目, 將 QJWiFi.framework 拖拽添加到項目中厦凤。我們最好勾選上 Copy items if needed鼻吮,這樣原來的框架的改動就不會影響到我們的項目了。然后较鼓,在需要使用這個框架的地方導(dǎo)入框架的 module(import QJWiFi)椎木,這樣我們就可以使用使用框架中的公開類與方法。
但是博烂。香椎。。運行項目禽篱,success 之后編譯器會報以下錯誤
dyld: Library not loaded: @rpath/QJWiFi.framework/QJWiFi
Referenced from: /Users/laichunhui/Library/Developer/CoreSimulator/Devices/CBBB7623-1930-4A1F-A094-6A2AC27A8E29/data/Containers/Bundle/Application/AB2EAE28-C094-4047-9379-815980E8A214/QJWiFiDemo.app/QJWiFiDemo
Reason: image not found
這是因為我們還未將框架復(fù)制到項目包中畜伐。在 Build Phases 選項卡里添加一個 Copy File 的階段 ,然后將目標(biāo)設(shè)定為 Frameworks躺率,將我們的 QJWiFi.framework 添加到新建的階段里烤礁,來指定 IDE 在編譯時進行復(fù)制。
常見問題:
-
Objective-C 項目集成 Swift framework 注意點
如果要將框架導(dǎo)入到 OC 項目中(#import "QJWiFi/QJWiFi.h" 或 #import "QJWiFi/QJWiFi-Swift.h")肥照,還需要將 Build setting 中的 ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES 設(shè)置為 YES,否則項目會報 image not found 的錯誤勤众。
資源加載
- framework 自身對應(yīng)的 bundle: Bundle(for: QJWiFi.self)
- framework 內(nèi)部 image 訪問: UIImage(named: imageName, in: bundle, compatibleWith: nil)
- 報錯: Include of non-modular header inside framework module
如果我們項目中調(diào)用了比如 CommonCrypto 等底層框架舆绎,由于這些框架并未打包成 module,我們無法直接導(dǎo)入到 Swift 項目中们颜,如果在 framework 的頭文件中直接導(dǎo)入 (#import <CommonCrypto/CommonCrypto.h>)就會報以上錯誤吕朵。在framework 中,橋接是不被允許的窥突,有興趣的可以不妨一試努溃。所以我們只能為這個底層框架創(chuàng)建 module。
- 首先在你的 Framework/Target 下建一個文件夾阻问,可以叫做 CommonCrypto 梧税,并創(chuàng)建兩個子文件夾,可以分別命名為 iphoneos 称近、iphonesimulator第队,并分別新建一個 module.modulemap的文件,內(nèi)容分別為:
module CommonCrypto [system] {
header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/CommonCrypto/CommonCrypto.h"
export *
}
module CommonCrypto [system] {
header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/CommonCrypto/CommonCrypto.h"
export *
}
- 然后在你的 Target 的 Build Setting 中找到 Swift ComCompiler - Search Paths 的 Import Paths 刨秆,設(shè)置鍵值:
Any iOS Simulator SDK
${SRCROOT}/QJWiFi/CommonCrypto/iphonesimulator-
Any iOS SDK
${SRCROOT}/QJWiFi/CommonCrypto/iphoneos
這樣在 framework 中就可以直接導(dǎo)入 module (import CommonCrypto)