iOS包依赖管理工具(五):Swift Package Manager(SPM)自定义篇

2,889 阅读4分钟

iOS包依赖管理工具系列

iOS包依赖管理工具(一):CocoaPods了解篇

iOS包依赖管理工具(二):CocoaPods原理和知识

iOS包依赖管理工具(三):创建自己的 Pod 库

iOS包依赖管理工具(四):Swift Package Manager(SPM)了解篇

iOS包依赖管理工具(五):Swift Package Manager(SPM)自定义篇

iOS包依赖管理工具(六):CocoaPods VS SPM 总结篇

一、前言

上篇我们了解了 SPM 如何帮助我们快速接入第三方依赖源;现实中,我们不仅需要依赖第三方源,往往我们也需要使得项目模块化、组件化;类似 CocoaPods ,我们也需要自定义库,并让我们的项目依赖;本篇,将简单分析 SPM 库的组成,以及创建我们自己的 SPM 库。

二、SPM 库组成

2.1、目录组成结构

我们先来分析一下『Alamofire』的目录结构,如下图:

alamofire-spm.png

上图中,红色框框标明的就是 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将搜索.pc文件以获取系统目标所需的其他标志;
  • providers:系统目标的程序包提供者;
  • products:此软件包可让客户使用的产品列表;
  • dependencies:软件包依赖项列表(可空,或需要其它外部依赖);
  • targets:属于此软件包的目标列表(源码目录、测试目录);
  • swiftLanguageVersions:此软件包兼容的Swift版本列表;
  • cLanguageStandard:用于此程序包中所有C目标的C语言标准;
  • cxxLanguageStandard:用于此程序包中所有C ++目标的C ++语言标准;

一般来说,上面的这些配置,通常,我们需要的是:name、platforms、products、dependencies、targets。

三、创建自己的 SPM 库

3.1、两种方式创建 SPM 库

方式一(Xcode工具化)创建:

spm-xcode.png

输入项目名,点击『Create』:

xcode-spm-name.png

Xcode 自动帮我们生成了配置文件和源码目录:

xcode-spm-auto.png

方式二(命令行)创建:

$ 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 代码如下(重点:构造器!!!\color{red}{重点:构造器!!!}):
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 库,那怎么办呢?

办法如下:

  1. 关闭我们的 SPM Xcode 工程(一定要!!!);
  2. 打开我们的项目工程;
  3. 将我们的自定义 SPM 直接拖入工程中,如下图:

drag-spm.png

拖入后,如下图:

after-drag.png

  1. 添加 framework 链接,如下图:

frameworks.png

点击『+』,选择如下:

frameworks-add.png

点击『Add』即可:

after-frameworks-add.png

  1. 引入自定义库,并测试,如下图:

run.png

OK!完美,毫无违和感.... 接下来,我们可以考虑上传至 Git 云端。

3.4、上传至 Github

  • 创建 Git 仓库:

create-repo.png

建议勾选:『README』、『.gitignore』和『license』,然后点击『Create repository』。

  • clone && commit(建议打上 tag):

repo-tag.png

3.5、重新集成

  • 去除『Frameworks』中的 SPM 库

frameworks-remove.png

  • 移除本地 SPM Reference

spm-remove-ref.png

按照上一篇《Swift Package Manager(SPM)了解篇》添加源即可:

spm-add-repo-src.png

最后来张完整的『全家福』:

spm-full-family.png