iOS 創(chuàng)建含有 cocoapods 依賴的 framework

之前一直用的 framework 實(shí)現(xiàn)了 OC 和 Swift 互調(diào),現(xiàn)在需要添加依賴,即 framework 也需要 cocoapods 引入庫(kù),建立的方式稍有不同,這里記錄一下。

建立新項(xiàng)目,選擇 framework,命名,這里我命名為 HKYKit。

支持版本調(diào)低,和項(xiàng)目一樣就可以了。這里比項(xiàng)目支持版本高的話會(huì)在引入 framework 時(shí)報(bào)錯(cuò)。如果有多個(gè)項(xiàng)目需要引這個(gè) framework,選最低的版本。

引入 cocoapods 庫(kù)

framwork 可能依賴別的庫(kù)(比如我創(chuàng)建的 framework 就依賴 SwiftJSON),這時(shí)候和普通項(xiàng)目一樣建立 Podfile,注意使用 use_frameworks!

pod install,從 .xcworkspace 打開(kāi),創(chuàng)建代碼。

接口

這里創(chuàng)建一個(gè) Experiment.swift 作為示例,根據(jù)需要把一切需要調(diào)用的都標(biāo)上 publicopen

import Foundation
import SwiftyJSON

public struct Experiment {
   
   public init() { }
   
   public func anyJSON() -> JSON {
       var json = JSON()
       json["title"].string = "實(shí)驗(yàn)"
       return json
   }
}

將 Experiment.swift 作為暴露給 framework 外部的文件

TARGETS->Build Phases->Headers,添加到 Public


生成 .framework

先設(shè)置,TARGETS->Build Settings->Mach-O Type,設(shè)為 Static Library。這里如果需要設(shè)為 Dynamic Library ,在引入 .framework 的項(xiàng)目還需設(shè)置一下,文末有設(shè)置方法。

構(gòu)建框架

選到模擬器和真機(jī),分別 build 一遍

項(xiàng)目目錄->Products->XXX.framework->Show in Finder


看到 XXX.framework 文件夾及 Pods 文件夾。 Products 文件夾包含 Debug-iphoneos 和 Debug-iphonesimulator,對(duì)應(yīng)真機(jī)和模擬器。

生成通用框架

TARGETS 左下角加號(hào),添加一個(gè) Aggregate,命名為 Maker

Build Phases->左上角加號(hào)->New Run Script Phase


注意 UNIVERSAL_OUTPUTFOLDER 路徑,xxx 改為用戶名。這里先測(cè)試一下,生成到桌面,實(shí)際生成到項(xiàng)目目錄里比較方便。

if [ "true" == ${ALREADYINVOKED:-false} ]
then
echo "RECURSION: Detected, stopping"
else
export ALREADYINVOKED="true"

UNIVERSAL_OUTPUTFOLDER=/Users/xxx/Desktop
# 輸出文件夾
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"

xcodebuild -target "${TARGET_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos  BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" build
xcodebuild -target "${TARGET_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" build

cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"

SIMULATOR_SWIFT_MODULES_DIR="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/."
if [ -d "${SIMULATOR_SWIFT_MODULES_DIR}" ]; then
cp -R "${SIMULATOR_SWIFT_MODULES_DIR}" "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"
fi

lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"

fi

Maker 的 Build Setting->Excluded Architectures 添加 arm64

選到 Maker,Build, 生成 .framework

引入 framework

新建一個(gè)項(xiàng)目,測(cè)試 framework 是否能用。如果 framework 使用了 cocoapods,項(xiàng)目也要使用 cocoapods,引入需要的庫(kù)。建立一個(gè)測(cè)試項(xiàng)目取名為 SwiftDemo,生成 SwiftDemo.xcworkspace

直接將生成的 .framework 拖入項(xiàng)目目錄,確保 TARGETS->Build Phases 中有 .framework

測(cè)試代碼

import UIKit
import HKYKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let e = Experiment()
        let json = e.anyJSON()
        print("\(json["title"].stringValue)")
    }
}

Run 一下,如果 framework 的 Mach-O Type 選的是 Dynamic Library ,則會(huì)報(bào)錯(cuò)

dyld: Library not loaded: @rpath/HKYKit.framework/HKYKit
  Referenced from: /private/var/containers/Bundle/Application/02734D3C-F7CC-4DD1-BDDB-971CC2597F54/SwiftDemo.app/SwiftDemo
  Reason: image not found

將 TARGETS->General->Frameworks,Libraries,and Embeded Content 中 framework 的 Do Not Embed 改為 Embed & Sign。

建議使用 Static Library,Do Not Embed。

如果報(bào)錯(cuò)

Building for iOS, but the linked and embedded framework  was built for iOS + iOS Simulator.

在 stackoverflow 找到解決方法:TARGETS->Build Settings->Validate Workspace 改為 YES,Run 一次,再改回 NO 就可以了。

正常運(yùn)行,輸出“實(shí)驗(yàn)”


在項(xiàng)目中的 .framework 上右鍵,Show in Finder,拷貝其 目錄地址,復(fù)制到上面的 UNIVERSAL_OUTPUTFOLDER,之后生成就可以直接在項(xiàng)目里用了。

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

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

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