iOS包依赖管理工具(五):Swift Package Manager(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将搜索<name>.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
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341

推荐阅读更多精彩内容