Swift Package Manager 详细使用(2018-10-14更新)

Swift Package Manager (SwiftPM) 是 Apple 推出的一个包管理工具, 用于创建, 使用 Swift 的库, 以及可执行程序的工具.

使用方法

1. 基本使用: 创建可执行程序.

    1. 创建目录, 进入目录
$ mkdir executableDemo     
$ cd executableDemo        
    1. 创建一个可执行的包

一共可快捷创建四种类型的包文件, executable 指可执行的二进制包, Library 指静态库包, system-module 指 系统库的包.

$ swift package init --help
OVERVIEW: Initialize a new package

OPTIONS:
  --type   empty|library|executable|system-module
$ swift package init --type executable 

创建完可执行的包后, 我们在 Source 的子目录下可以看见以包名建的一个子目录, 在子目录里会默认生成一个 main.swift 文件, 这是执行 module 的入口.

在 main.swift 中输入以下代码. 代码意思是 如果执行 Module 时带的参数不为 2 , 输出 Usage: hello NAME, 否则调用 sayHello 方法.

if CommandLine.arguments.count != 2 {
    print("Usage: hello NAME")
} else {
    let name = CommandLine.arguments[1]
    sayHello(name: name)
}

在与 main.swift 同目录下创建一个 Greeter.swift 目录, 输入以下代码, 可供调用.

func sayHello(name: String) {
    print("Hello, \(name)!")
}
    1. 运行可执行包
$ swift run   # 输出 Usage: hello NAME 
$ swift run executableDemo "Lucy" # 输出 Hello Lucy

如果不带参数执行, 在 run 后面可不写包名


2. 基本使用: 类似 CocoaPods 和 Carthage 的功能, 作为第三方包管理器.

每次 SwiftPM 创建完包项目后, 都会生成一个 Package.swift 文件, 这里面管理包之间的依赖关系.
以 SwiftyJSON 为例.

import PackageDescription

let package = Package(
    name: "Hello_execute",
    dependencies: [
        .package(url: "https://github.com/SwiftyJSON/SwiftyJSON.git", from: "4.0.0"), 
        //第三方库url和版本号, 版本号可在 Release 版本里面查看
    ],
    targets: [
        .target(
            name: "Hello_execute",
            dependencies: ["SwiftyJSON"]),  //依赖的包名称
        .testTarget(
            name: "Hello_executeTests",
            dependencies: ["Hello_execute"]),
    ]
)
$ swift package init --type executable
创建完包项目后, 编辑依赖

更新依赖, 此时会自动从网上 clone 下支持 SwiftPM 的第三方库
$ swift package update 

编译依赖, 编译完会将第三方库链接到 .build 的文件夹中的可执行文件.
$ swift build 

编译完依赖后, 我们可以做两件事.

  1. 在 main.swift 中输入以下代码, 然后在当前库的主目录下, 直接执行 swift run, 可查看结果.
import SwiftyJSON      //引入模块

let json = JSON(["name":"Jack", "age": 25])
print(json)
  1. 我们可以像 CocoaPods 一样使用第三方库.
    在当前目录下生成 Xcode project 入口文件.
swift package generate-xcodeproj 
Swift Package Manager 详细使用(2018-10-14更新)_第1张图片
image.png

打开我们原来创建的 Xcode 项目, 直接将 Library.xcodeproj 拖入到主项目中.
并且 Link 我们新的第三方库.


Swift Package Manager 详细使用(2018-10-14更新)_第2张图片
image.png

3. 基本使用: 自定义一个库作为其他项目的依赖包

$ mkdir LCLib
$ cd LCLib
$ swift package init    //初始化包,不带参数的话默认是Library

在 Source 的子目录下面找到自动生成的 LCLib.swift 文件, 编辑如下代码.

public struct LCLib {
    var text = "Hello, MyLib!"
    public var num:Int
    public init() {
        num = 2
    }
}

回到 Source 所在目录, 因为 SwiftPM 依赖包必须使用git url和版本号,所以我们需要为我们的库创建一个 git 仓库并提交代码和打 tag.

$ git init
$ git add .
$ git commit -m "Initial Commit"
$ git tag 1.0.0

这是提交在本地仓库, 在使用的时候注意指名仓库路径.
编辑依赖.

let package = Package(
    name: "Hello_execute",
    dependencies: [
        .package(url: "https://github.com/SwiftyJSON/SwiftyJSON.git", from: "4.2.0"), //第三方库url和版本号, 版本号可在 Release 版本里面查看
        .package(url: "../LCLib", from: "1.0.0")
        注意: 由于我们的 库 没有 push 到远程仓库, 只在本地, 所以这里指的是本地仓库的相对路径
    ],
    targets: [
        .target(
            name: "Hello_execute",
            dependencies: ["SwiftyJSON", "LCLib"]),  //依赖的包名称
        .testTarget(
            name: "Hello_executeTests",
            dependencies: ["Hello_execute"]),
    ]
)

编辑完依赖, 再次编辑 main.swift 文件

import SwiftyJSON       //引入模块

import LCLib

let json = JSON(["name":"Jack", "age": 25])
print(json)

//自定义库
let lib = LCLib()
print(lib)

最后执行 swift run, 运行过程中会编译代码.


4. 高级应用: 包含上面所有.

我们创建完一个包项目后, 编辑 package.swift 文件

import PackageDescription

let package = Package(
    name: "OC2Swift",
    products: [
        // 自定义库
        .library(
            name: "LCLib",
            targets: ["LCLib"]),
        
        // 可执行文件
        .executable(
            name: "LCOC2Swift",
            targets: ["LCOC2Swift"])
    ],
    dependencies: [
        // 外部依赖
        .package(url: "https://github.com/SwiftyJSON/SwiftyJSON.git", from: "4.2.0"),
    ],
    targets: [
        // 每一个 target 执行所需要的依赖
        .target(
            name: "LCLib",
            dependencies: []),
        .target(
            name: "LCOC2Swift",
            dependencies: ["LCLib", "SwiftyJSON"]),
        
//        
//        .target(
//            name: "OC2Swift",
//            dependencies: []),
//        .testTarget(
//            name: "OC2SwiftTests",
//            dependencies: ["OC2Swift"]),
    ]
)

从上往下看.

  • name 表示 package 的名字
  • product 表示 package 的输出, 在这里具体指自定义的 lib 和 executable 文件, 如果要使用自定义库, 不需要提交到本地仓库, 直接作为 lib 输出就可以了.
  • dependencies 表示外部依赖
  • target 指 目标文件, 在这里的 name 都与实际文件名对应, 也就是说每一个要使用的 文件夹 都要写在这里, 并表明对应的依赖. 下面那张图就是两个 target 对应的两个文件夹

这些东西具体细节可以查看官方文件

Swift Package Manager 详细使用(2018-10-14更新)_第3张图片
image.png

5. 高级应用: 带参数执行程序

在第一部分我们其实展示了如何带参数执行

$ swift run executableDemo "Lucy"

我们可以通过 CommandLine.arguments[1] 来获取到这个参数, 但是如果是多个参数, 这样来处理就比较麻烦.
官方对此提出了一个解决方案, 使用 SwiftPM module.
编辑我们的 package.swift 文件, 添加依赖包 SwiftPM.

let package = Package(
    name: "PackageName",
    dependencies: [
        .package(url: "https://github.com/apple/swift-package-manager.git", from: "0.3.0"),
    ],
    targets: [
        .target(
            name: "Hello_execute",
            dependencies: ["SwiftPM"]),  //依赖的包名称
        .testTarget(
            name: "Hello_executeTests",
            dependencies: ["Hello_execute"]),
    ]
)

这里有几点需要注意.

  • 如果一时找不到 SwiftPM 的 tag, 我们可以把官方项目 clone 下来, 在主目录中执行
$ git tag
refs/tags/0.1.0
refs/tags/0.2.0
refs/tags/0.2.1
refs/tags/0.3.0

就可以查看到官方挂在远端的库文件. 类似上面显示的才是.

  • 添加完依赖后, 在我们的 main.swift 中
import Utility     // 这个才是真正定义参数的工具库

// 定义一个参数解析器
let parser = ArgumentParser(usage: "使用", overview: "将网页转为OC")

// 添加参数规则
// --url 是参数标识, -u 是简写, 
// 参数是 String 类型, 除此以外, 参数还可以是 Int, Bool, 数组等类型
// usage 是使用说明
let urlArg = parser.add(option: "--url", shortName: "-u", 
                        kind: String.self, usage: " -u ")

// 创建子解析器
let fileParser = parser.add(subparser: "out", overview: "输出文件")
let fileArg = fileParser.add(positional: "out", kind: String.self,
                            usage: "out ")

获取参数并使用

// 获取执行参数, 1和2一样的结果
let arguments = Array(ProcessInfo.processInfo.arguments.dropFirst())
// let arguments2 = Array(CommandLine.arguments.dropFirst())

// 解析参数
let result = try parser.parse(arguments)

// 获取参数
let url = result.get(urlArg) ?? "Null"

print("url: \(url))

拿到参数后, 就能向写 App 一样来编写 Swift 代码.

参考:
Swift Package Manager使用
IOS套件管理-CocoaPods 以及 Swift package manager(SwiftPM) 兩種方式介紹

你可能感兴趣的:(Swift Package Manager 详细使用(2018-10-14更新))