一、前言
上篇我们了解了 SPM 如何帮助我们快速接入第三方依赖源;现实中,我们不仅需要依赖第三方源,往往我们也需要使得项目模块化、组件化;类似 CocoaPods ,我们也需要自定义库,并让我们的项目依赖;本篇,将简单分析 SPM 库的组成,以及创建我们自己的 SPM 库。
二、SPM 库组成
2.1、目录组成结构
我们先来分析一下『Alamofire』的目录结构,如下图:
上图中,红色框框标明的就是 SPM 库的最基本组成部分:
- Package.swift:该文件是包的描述文件,其描述内容在右侧编辑区,但不止这些内容;
- Source目录:包的源码文件所在的目录;
2.2、Package.swift 组成分析
Package.swift 是整个包描述,它依赖 PackageDescription 结构,该结构定义了一个 SPM 导出包需要指定哪些配置信息:
// struct Package
init(
name: String,
defaultLocalization: LanguageTag? = nil,
platforms: [SupportedPlatform]? = nil,
pkgConfig: String? = nil,
providers: [SystemPackageProvider]? = nil,
products: [Product] = [],
dependencies: [Package.Dependency] = [],
targets: [Target] = [],
swiftLanguageVersions: [SwiftVersion]? = nil,
cLanguageStandard: CLanguageStandard? = nil,
cxxLanguageStandard: CXXLanguageStandard? = nil
)
- name:Swift包的名称;
- defaultLocalization:资源的默认本地化;
- platforms:支持的最低系统平台的列表;
- pkgConfig:用于C模块的名称。如果存在,Xcode将搜索<name>.pc文件以获取系统目标所需的其他标志;
- providers:系统目标的程序包提供者;
- products:此软件包可让客户使用的产品列表;
- dependencies:软件包依赖项列表(可空,或需要其它外部依赖);
- targets:属于此软件包的目标列表(源码目录、测试目录);
- swiftLanguageVersions:此软件包兼容的Swift版本列表;
- cLanguageStandard:用于此程序包中所有C目标的C语言标准;
- cxxLanguageStandard:用于此程序包中所有C ++目标的C ++语言标准;
一般来说,上面的这些配置,通常,我们需要的是:name、platforms、products、dependencies、targets。
三、创建自己的 SPM 库
3.1、两种方式创建 SPM 库
方式一(Xcode工具化)创建:
输入项目名,点击『Create』:
Xcode 自动帮我们生成了配置文件和源码目录:
方式二(命令行)创建:
$ mkdir DemoLogger && cd DemoLogger
$ swift package init
// 以下自动生成
Creating library package: DemoLogger
Creating Package.swift
Creating README.md
Creating .gitignore
Creating Sources/
Creating Sources/DemoLogger/DemoLogger.swift
Creating Tests/
Creating Tests/LinuxMain.swift
Creating Tests/DemoLoggerTests/
Creating Tests/DemoLoggerTests/DemoLoggerTests.swift
Creating Tests/DemoLoggerTests/XCTestManifests.swift
3.2、编写我们的 SPM 库
- Logger.swift 代码如下():
public struct Logger {
var DEBUG: Bool = false
// 这里是 struct,所以按照 swift 的 struct 语法,可以不写 init,
// 但是,因为是封装成 SPM 库,需要对外暴露,
// 所以 init 构造器不能默认不写,一定需要有 public 构造器,否则外部无法初始化
public init() {
}
public init(_ DEBUG: Bool) {
self.DEBUG = DEBUG
}
public func log(_ msg: String) {
if DEBUG {
print("Logger\t\(msg)")
}
}
}
- 修改测试用例,不然会报错:
import XCTest
@testable import Logger
final class LoggerTests: XCTestCase {
func testExample() {
Logger(true).log("chris.yang")
}
static var allTests = [
("testExample", testExample),
]
}
然后『command + B』编译就能成功!
3.3、本地集成 SPM 库
我们自定义的 SPM 库,不可能每次修改一点,仅仅只是编译通过,就提交到 git 上,肯定需要本地先集成,测试逻辑之后,最终稳定后,才会考虑提交到 git 上,但是,如果你去通过 SPM 去 add ,发现只能输入 git url,没法添加本地 SPM 库,那怎么办呢?
办法如下:
- 关闭我们的 SPM Xcode 工程(一定要!!!);
- 打开我们的项目工程;
- 将我们的自定义 SPM 直接拖入工程中,如下图:
拖入后,如下图:
- 添加 framework 链接,如下图:
点击『+』,选择如下:
点击『Add』即可:
- 引入自定义库,并测试,如下图:
OK!完美,毫无违和感.... 接下来,我们可以考虑上传至 Git 云端。
3.4、上传至 Github
- 创建 Git 仓库:
建议勾选:『README』、『.gitignore』和『license』,然后点击『Create repository』。
- clone && commit(建议打上 tag):
3.5、重新集成
- 去除『Frameworks』中的 SPM 库
- 移除本地 SPM Reference
按照上一篇《Swift Package Manager(SPM)了解篇》添加源即可:
最后来张完整的『全家福』: