Swift?Package?技巧及混編兼容問(wèn)題詳解
創(chuàng)建 Package
mkdir somePath cd somePath swift package init (--type library/executable/empty/system module)
其中,type 的四種類型分別對(duì)應(yīng):
- library: 庫(kù)(默認(rèn))
- executable: 可執(zhí)行文件
- empty: 空項(xiàng)目
- system module: 系統(tǒng)模板項(xiàng)目
一般情況下默認(rèn)即可
創(chuàng)建 package 之后,還可以使用 swift package generate-xcodeproj
創(chuàng)建一個(gè)Xcode項(xiàng)目來(lái)編譯和調(diào)試代碼
使用 Package
在 Xcode 菜單欄中,選擇 file -> add packages
可以指定 package 的版本規(guī)則
維護(hù) Package
版本控制
在 package 路徑下,使用 git init
來(lái)創(chuàng)建一個(gè)倉(cāng)庫(kù)。之后上傳至遠(yuǎn)端即可
本地調(diào)試修改
對(duì)于通過(guò) cocoapods 引入的庫(kù),如果想在本地修改該庫(kù)并提交的話,需要在 PodFile 里面把路徑改成本地的,然后再 pod install
一下,比較麻煩
但是修改 swift package 引入的庫(kù)就很方便了,直接把 package 的文件目錄拖到工程目錄下即可。修改好提交到遠(yuǎn)端之后,右鍵 delete -> remove reference (move to trash 會(huì)刪掉本地文件)
然后 file -> packages -> update to latest,即可更新到最新的版本
Package 之間的依賴
在每個(gè) swift package 的目錄下都有個(gè) Package.swift
文件。內(nèi)容如下:
// swift-tools-version:5.5 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( name: "some name", products: [ // Products define the executables and libraries a package produces, and make them visible to other packages. .library( name: "some name", targets: ["some name"]), ], dependencies: [ // Dependencies declare other packages that this package depends on. // .package(url: /* package url */, from: "1.0.0"), ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. // Targets can depend on other targets in this package, and on products in packages this package depends on. .target( name: "some name", dependencies: []), .testTarget( name: "some name", dependencies: ["some name"]), ] )
其中的字段分別表示:
- name: 庫(kù)/項(xiàng)目名字
- products: 庫(kù)/項(xiàng)目生成的東西,可以是 library 或者 executable. 同一個(gè)庫(kù)/項(xiàng)目可以生成多個(gè) library 或者 executable
- dependencies: 此庫(kù)/項(xiàng)目所依賴的庫(kù),及依賴庫(kù)的 URL 和版本等信息。如果依賴本地庫(kù)的話,可以添加
.package(path:"local path")
- targets: 庫(kù)/項(xiàng)目生成的目標(biāo)
相較于 cocoapods,swift package 還是更加方便點(diǎn)的,而且是蘋果自家的產(chǎn)品。但是目前很多三方庫(kù)都在 cocoapods 上,swift package 的大面積普及還需要一段時(shí)間
混編問(wèn)題
target 拆分
Apple 官方文檔里說(shuō):
Targets can contain Swift, Objective-C/C++, or C/C++ code, but an individual target can’t mix Swift with C-family languages. For example, a Swift package can have two targets, one that contains Objective-C, Objective-C++, and C code, and a second one that contains Swift code.
也就是說(shuō),SPM 是支持 objc 以及 C 系代碼的。但是同一個(gè) target 里面只能有一種語(yǔ)言,Swift 文件不能和 objc 文件放到一個(gè) target 里。
如果我們想要在一個(gè) SPM 倉(cāng)庫(kù)里面同時(shí)放置兩種語(yǔ)言的代碼的話,就需要將倉(cāng)庫(kù)拆分為兩個(gè) target:
let package = Package( name: "MyModule", platforms: [.iOS(.v11), .macOS(.v11)], products: [ // Products define the executables and libraries a package produces, and make them visible to other packages. .library( name: "MyModule", targets: ["MyModule", "MyModule_Objc"]) ], dependencies: [ // Dependencies declare other packages that this package depends on. // .package(url: /* package url */, from: "1.0.0"), ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. // Targets can depend on other targets in this package, and on products in packages this package depends on. .target( name: "MyModule_Objc", dependencies: [], publicHeadersPath: "include", cSettings: [.headerSearchPath(".")], cxxSettings: [.headerSearchPath(".")] ), .target( name: "MyModule", dependencies: ["MyModule_Objc"], path: "Sources/MyModule", swiftSettings: [.define("SPM_MODE")] ), .testTarget( name: "MyModuleTests", dependencies: ["MyModule"]), ] )
其中,倉(cāng)庫(kù)文件結(jié)構(gòu)應(yīng)該為:
- MyModule | |-README.md | |-Package.swift | |-Sources | |-MyModule | | | |- MyPackage.swift | |-MyModule_Objc | |-Include | | | |- MyObjCClass.h | |- MyObjCClass.m
Sources 文件夾拆分為兩個(gè)子文件夾,分別是兩個(gè) target 的路徑。Swift target 依賴 objc 的 target, objc 的 target 可以設(shè)置公開(kāi) header 的路徑。
這樣,objc 以及 C/C++ 這些 C 系的文件都放在 MyModule_Objc
文件夾下,Swift 文件放到 MyModule
文件夾下,就可以在同一個(gè) SPM 倉(cāng)庫(kù)下實(shí)現(xiàn)混編了。
引用以及和 cocoapods 的兼容問(wèn)題
在上面的 package 設(shè)置里面可以看到一行預(yù)處理宏的定義:
swiftSettings: [.define("SPM_MODE")]
這個(gè)設(shè)置是用來(lái)標(biāo)識(shí)當(dāng)前庫(kù)是通過(guò) SPM 方式引入的。根據(jù)上文,SPM 模式下,當(dāng)前庫(kù)的 Swift 和 objc 是兩個(gè) target。因此,同一個(gè)庫(kù)的 Swift 文件想要調(diào)用 objc 文件的話,必須引入 objc 的 target:
import MyModule_Objc // your code...
但是,我們的庫(kù)一般情況下還是要支持 cocoapods 的。在 cocoapods 模式下,同一個(gè)倉(cāng)庫(kù)的 Swift 和 objc 文件是不需要拆分為兩個(gè) target 的,pod 是通過(guò)橋接文件等來(lái)實(shí)現(xiàn)兩者之間相互調(diào)用的。
那么問(wèn)題就來(lái)了,當(dāng)使用 cocoapods 引入當(dāng)前庫(kù)時(shí),import MyModule_Objc
是肯定會(huì)報(bào)錯(cuò)的,因?yàn)?pod 并不會(huì)生成 MyModule_Objc
。
這時(shí)候,我們?cè)?package 文件里預(yù)先定義的宏就派上用場(chǎng)了:
#if SPM_MODE import FoundationX_Objc #endif
只有在 SPM 模式下,才會(huì) import MyModule_Objc
,這樣就解決了與 cocoapods 的兼容問(wèn)題。
以上就是Swift Package 技巧及混編兼容問(wèn)題詳解的詳細(xì)內(nèi)容,更多關(guān)于Swift Package混編兼容的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Swift?中的?RegexBuilder學(xué)習(xí)指南
- Swift中的高階函數(shù)功能作用示例詳解
- Swift中的可選項(xiàng)Optional解包方式實(shí)現(xiàn)原理
- Swift重構(gòu)自定義空等運(yùn)算符 “??=” 實(shí)例
- Swift?重構(gòu)重載運(yùn)算符示例解析
- SwiftUI開(kāi)發(fā)總結(jié)combine原理簡(jiǎn)單示例詳解
- 倉(cāng)庫(kù)模式及其在Swift?項(xiàng)目中的應(yīng)用詳解
- swift依賴注入和依賴注入容器詳解
- Swift?中?Opaque?Types學(xué)習(xí)指南
相關(guān)文章
Swift使用transform 實(shí)現(xiàn)重復(fù)平移動(dòng)畫效果
這篇文章主要介紹了Swift使用transform 實(shí)現(xiàn)重復(fù)平移動(dòng)畫效果,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-07-07SpringBoot3.0集成Redis緩存的實(shí)現(xiàn)示例
緩存就是一個(gè)存儲(chǔ)器,常用 Redis作為緩存數(shù)據(jù)庫(kù),本文主要介紹了SpringBoot3.0集成Redis緩存的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03Swift 3.1聊天界面鍵盤效果的實(shí)現(xiàn)詳解
這篇文章主要給大家介紹了Swift 3.1聊天界面鍵盤效果實(shí)現(xiàn)的相關(guān)資料,文中介紹的非常詳細(xì),相信對(duì)大家的學(xué)習(xí)或者工作具有一定的參考價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-04-04Swift5中fileprivate與private的差別淺析
這篇文章主要給大家介紹了關(guān)于Swift5中fileprivate與private的差別的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Swift5具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09Swift網(wǎng)絡(luò)請(qǐng)求庫(kù)Alamofire使用詳解
這篇文章主要為大家詳細(xì)介紹了Swift網(wǎng)絡(luò)請(qǐng)求庫(kù)Alamofire的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08Swift并發(fā)系統(tǒng)并行運(yùn)行多個(gè)任務(wù)使用詳解
這篇文章主要為大家介紹了Swift并發(fā)系統(tǒng)并行運(yùn)行多個(gè)任務(wù)使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06