构建一个库

本指南的源代码可以在 GitHub 上找到

安装 Swift

为了开始您的旅程,安装 Swift 以开始在 macOSLinuxWindows 上使用它。

提示:要测试您是否已安装 Swift,请从您的 shell 或终端应用程序运行 swift --version

Swift 捆绑了 Swift Package Manager (SwiftPM),用于管理 Swift 代码的分发。它允许轻松地将其他 Swift 包导入到您的应用程序和库中,使其成为任何 Swift 开发人员的宝贵工具。

Swift 受 Apache License, Version 2.0 保护。

引导

让我们用新的 Swift 开发环境编写一个小库。首先,我们将使用 SwiftPM 为我们创建一个新项目。在您选择的终端中运行

$ mkdir MyLibrary
$ cd MyLibrary
$ swift package init --name MyLibrary --type library

这将生成一个名为 MyLibrary 的新目录,其中包含以下文件

.
├── Package.swift
├── Sources
│   └── MyLibrary
│       └── MyLibrary.swift
└── Tests
    └── MyLibraryTests
        └── MyLibraryTests.swift

Package.swift 是 Swift 的清单文件。您可以在其中保留项目的元数据以及其依赖项。

Sources/MyLibrary/MyLibrary.swift 是库的初始源文件,我们将在其中编写库代码。Test/MyLibraryTests/MyLibraryTests.swift 是我们可以为库编写测试的地方。

实际上,SwiftPM 为我们生成了一个 “Hello, world!” 项目,包括一些单元测试!我们可以通过在终端中运行 swift test 来运行测试。

$ swift test
Building for debugging...
[5/5] Linking MyLibraryPackageTests
Build complete! (7.91s)
Test Suite 'All tests' started at 2023-08-29 18:59:31.328
Test Suite 'MyLibraryPackageTests.xctest' started at 2023-08-29 18:59:31.329
Test Suite 'MyLibraryTests' started at 2023-08-29 18:59:31.329
Test Case '-[MyLibraryTests.MyLibraryTests testExample]' started.
Test Case '-[MyLibraryTests.MyLibraryTests testExample]' passed (0.001 seconds).
Test Suite 'MyLibraryTests' passed at 2023-08-29 18:59:31.330.
	 Executed 1 test, with 0 failures (0 unexpected) in 0.001 (0.001) seconds
Test Suite 'MyLibraryPackageTests.xctest' passed at 2023-08-29 18:59:31.330.
	 Executed 1 test, with 0 failures (0 unexpected) in 0.001 (0.001) seconds
Test Suite 'All tests' passed at 2023-08-29 18:59:31.330.
	 Executed 1 test, with 0 failures (0 unexpected) in 0.001 (0.002) seconds

一个小库

现在让我们编写一个小库。将 MyLibrary.swift 的示例内容替换为以下代码

import Foundation

struct Email: CustomStringConvertible {
  var description: String

  public init(_ emailString: String) throws {
    let regex = #"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,64}"#
    guard let _ = emailString.range(of: regex, options: .regularExpression) else {
      throw InvalidEmailError(email: emailString)
    }
    self.description = emailString
  }
}

private struct InvalidEmailError: Error {
  let email: String
}

现在让我们为此强类型 Email API 添加一个单元测试。将 MyLibraryTests.swift 的示例内容替换为以下代码

@testable import MyLibrary
import XCTest

final class MyLibraryTests: XCTestCase {
  func testEmail() throws {
    let email = try Email("john.appleseed@apple.com")
    XCTAssertEqual(email.description, "john.appleseed@apple.com")

    XCTAssertThrowsError(try Email("invalid"))
  }
}

保存后,我们可以再次运行测试

❯ swift test
Building for debugging...
[5/5] Linking MyLibraryPackageTests
Build complete! (3.09s)
Test Suite 'All tests' started at 2023-08-29 19:01:08.640
Test Suite 'MyLibraryPackageTests.xctest' started at 2023-08-29 19:01:08.641
Test Suite 'MyLibraryTests' started at 2023-08-29 19:01:08.641
Test Case '-[MyLibraryTests.MyLibraryTests testEmail]' started.
Test Case '-[MyLibraryTests.MyLibraryTests testEmail]' passed (0.002 seconds).
Test Suite 'MyLibraryTests' passed at 2023-08-29 19:01:08.643.
	 Executed 1 test, with 0 failures (0 unexpected) in 0.002 (0.002) seconds
Test Suite 'MyLibraryPackageTests.xctest' passed at 2023-08-29 19:01:08.643.
	 Executed 1 test, with 0 failures (0 unexpected) in 0.002 (0.002) seconds
Test Suite 'All tests' passed at 2023-08-29 19:01:08.643.
	 Executed 1 test, with 0 failures (0 unexpected) in 0.002 (0.003) seconds

本指南的源代码可以在 GitHub 上找到