您好,登錄后才能下訂單哦!
本篇內容主要講解“Swift Package使用技巧及混編兼容問題怎么解決”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Swift Package使用技巧及混編兼容問題怎么解決”吧!
mkdir somePath cd somePath swift package init (--type library/executable/empty/system module)
其中,type 的四種類型分別對應:
library: 庫(默認)
executable: 可執行文件
empty: 空項目
system module: 系統模板項目
一般情況下默認即可
創建 package 之后,還可以使用 swift package generate-xcodeproj
創建一個Xcode項目來編譯和調試代碼
在 Xcode 菜單欄中,選擇 file -> add packages
可以指定 package 的版本規則
在 package 路徑下,使用 git init
來創建一個倉庫。之后上傳至遠端即可
對于通過 cocoapods 引入的庫,如果想在本地修改該庫并提交的話,需要在 PodFile 里面把路徑改成本地的,然后再 pod install
一下,比較麻煩
但是修改 swift package 引入的庫就很方便了,直接把 package 的文件目錄拖到工程目錄下即可。修改好提交到遠端之后,右鍵 delete -> remove reference (move to trash 會刪掉本地文件)
然后 file -> packages -> update to latest,即可更新到最新的版本
在每個 swift package 的目錄下都有個 Package.swift
文件。內容如下:
// 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: 庫/項目名字
products: 庫/項目生成的東西,可以是 library 或者 executable. 同一個庫/項目可以生成多個 library 或者 executable
dependencies: 此庫/項目所依賴的庫,及依賴庫的 URL 和版本等信息。如果依賴本地庫的話,可以添加 .package(path:"local path")
targets: 庫/項目生成的目標
相較于 cocoapods,swift package 還是更加方便點的,而且是蘋果自家的產品。但是目前很多三方庫都在 cocoapods 上,swift package 的大面積普及還需要一段時間
Apple 官方文檔里說:
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.
也就是說,SPM 是支持 objc 以及 C 系代碼的。但是同一個 target 里面只能有一種語言,Swift 文件不能和 objc 文件放到一個 target 里。
如果我們想要在一個 SPM 倉庫里面同時放置兩種語言的代碼的話,就需要將倉庫拆分為兩個 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"]), ] )
其中,倉庫文件結構應該為:
- MyModule | |-README.md | |-Package.swift | |-Sources | |-MyModule | | | |- MyPackage.swift | |-MyModule_Objc | |-Include | | | |- MyObjCClass.h | |- MyObjCClass.m
Sources 文件夾拆分為兩個子文件夾,分別是兩個 target 的路徑。Swift target 依賴 objc 的 target, objc 的 target 可以設置公開 header 的路徑。
這樣,objc 以及 C/C++ 這些 C 系的文件都放在 MyModule_Objc
文件夾下,Swift 文件放到 MyModule
文件夾下,就可以在同一個 SPM 倉庫下實現混編了。
在上面的 package 設置里面可以看到一行預處理宏的定義:
swiftSettings: [.define("SPM_MODE")]
這個設置是用來標識當前庫是通過 SPM 方式引入的。根據上文,SPM 模式下,當前庫的 Swift 和 objc 是兩個 target。因此,同一個庫的 Swift 文件想要調用 objc 文件的話,必須引入 objc 的 target:
import MyModule_Objc // your code...
但是,我們的庫一般情況下還是要支持 cocoapods 的。在 cocoapods 模式下,同一個倉庫的 Swift 和 objc 文件是不需要拆分為兩個 target 的,pod 是通過橋接文件等來實現兩者之間相互調用的。
那么問題就來了,當使用 cocoapods 引入當前庫時,import MyModule_Objc
是肯定會報錯的,因為 pod 并不會生成 MyModule_Objc
。
這時候,我們在 package 文件里預先定義的宏就派上用場了:
#if SPM_MODE import FoundationX_Objc #endif
只有在 SPM 模式下,才會 import MyModule_Objc
,這樣就解決了與 cocoapods 的兼容問題。
到此,相信大家對“Swift Package使用技巧及混編兼容問題怎么解決”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。