前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何使用Swift Package Manager那么,让我门开始吧

如何使用Swift Package Manager那么,让我门开始吧

作者头像
Leacode
发布2018-09-26 15:24:47
2K0
发布2018-09-26 15:24:47
举报
文章被收录于专栏:代码散人代码散人

Swift Package Manager 是苹果推出的用于创建使用swift的库和可执行程序的工具。

SwiftPM有什么作用?

能够通过命令快速创建library或者可执行的swift程序,能够跨平台使用,能够使开发出来的项目能够在不同平台上运行。

SwiftPM有哪些局限?

1、目前只能用来写跨平台的项目,如swift服务端开发,现在的Vapor、Perfect等服务端的web框架均使用SwiftPM来构建和管理依赖。 2、iOS和MacOS目前还未支持,但是后续一定会支持,现在只需要耐心的等待。

注意:本文适用于Swift 4.1.0 版本,后续会有更新,如果里面的demo不能正常运行,请检查版本。

那么,让我门开始吧

  • 创建一个Package

1、创建文件夹,并进入文件夹

代码语言:javascript
复制
$ mkdir Hello
$ cd Hello

2、初始化一个名为Hello的package

代码语言:javascript
复制
$ swift package init

会生成以下的文件结构

Hello项目的目录结构

3、使用命令行编译项目

代码语言:javascript
复制
$ swift build
Compile Swift Module 'Hello' (1 sources)

使用命令行运行test

代码语言:javascript
复制
$ swift test
Compile Swift Module 'HelloTests' (2 sources)
Linking ./.build/x86_64-apple-macosx10.10/debug/HelloPackageTests.xctest/Contents/MacOS/HelloPackageTests
Test Suite 'All tests' started at 2018-08-28 11:23:16.755
Test Suite 'HelloPackageTests.xctest' started at 2018-08-28 11:23:16.755
Test Suite 'HelloTests' started at 2018-08-28 11:23:16.755
Test Case '-[HelloTests.HelloTests testExample]' started.
Test Case '-[HelloTests.HelloTests testExample]' passed (0.264 seconds).
Test Suite 'HelloTests' passed at 2018-08-28 11:23:17.019.
     Executed 1 test, with 0 failures (0 unexpected) in 0.264 (0.264) seconds
Test Suite 'HelloPackageTests.xctest' passed at 2018-08-28 11:23:17.019.
     Executed 1 test, with 0 failures (0 unexpected) in 0.264 (0.264) seconds
Test Suite 'All tests' passed at 2018-08-28 11:23:17.019.
     Executed 1 test, with 0 failures (0 unexpected) in 0.264 (0.264) seconds
  • 创建一个可执行项目

1、创建文件夹,并进入文件夹

代码语言:javascript
复制
$ mkdir HelloExcutable
$ cd HelloExcutable/

2、初始化一个名为Hello的可执行文件

代码语言:javascript
复制
$ swift package init --type executable

会生成以下的文件结构

HelloExcutable的目录结构

3、运行HelloExcutable

代码语言:javascript
复制
$ swift run HelloExcutable
Compile Swift Module 'HelloExcutable' (1 sources)
Linking ./.build/x86_64-apple-macosx10.10/debug/HelloExcutable
Hello, world!

4、Build HelloExcutable

代码语言:javascript
复制
$ swift build

会在当前目录创建一个.build的文件夹,里面是编译后的内容。

编译后的目录结构

可以看到在x86_64-apple-macosx10.10/debug文件夹里有一个HelloExcutable的可执行文件。

5、直接运行HelloExcutable

代码语言:javascript
复制
$ .build/x86_64-apple-macosx10.10/debug/HelloExcutable

6、多个xxx.swift的情况: 在HelloExcutable(和Main.swift同级)的目录下创建名为Greeter.swift的文件,在里面插入代码:

代码语言:javascript
复制
func sayHello(name: String) {
    print("Hello, \(name)!")
}

修改Main.swift:

代码语言:javascript
复制
if CommandLine.arguments.count != 2 {
    print("Usage: hello NAME")
} else {
    let name = CommandLine.arguments[1]
    sayHello(name: name)
}

7、运行来查看效果

代码语言:javascript
复制
$ swift run HelloExcutable `whoami`
Compile Swift Module 'HelloExcutable' (2 sources)
Linking /Users/leacode/Documents/Swift/HelloExcutable/.build/x86_64-apple-macosx10.10/debug/HelloExcutable
Hello, leacode!

会获得命令行的结果,并打印出来

实际项目种使用

  • 创建项目

执行命令

代码语言:javascript
复制
$ swift package init --help
OVERVIEW: Initialize a new package

OPTIONS:
  --type   empty|library|executable|system-module

可以看到目前SwiftPM支持四种类型,指定不同的type可以创建不同类型的项目。由于swift支持不同的平台,所以创建项目的时候并没有生成xcode文件,如果是在非Mac平台开发,可以使用其他IDE进行开发,如果在Mac上开发就会方便很多,可以使用以下命令创建xcodeproj文件:

代码语言:javascript
复制
$ swift package generate-xcodeproj
  • 编译项目

执行命令

代码语言:javascript
复制
$ swift build --help
OVERVIEW: Build sources into binary products

USAGE: swift build [options]

OPTIONS:
  --build-path            Specify build/cache directory [default: ./.build]
  --build-tests           Build both source and test targets
  --configuration, -c     Build with configuration (debug|release) [default: debug]
  --disable-prefetching   
  --disable-sandbox       Disable using the sandbox when executing subprocesses
  --enable-build-manifest-caching
                          Enable llbuild manifest caching [Experimental]
  --no-static-swift-stdlib
                          Do not link Swift stdlib statically
  --package-path          Change working directory before any other operation
  --product               Build the specified product
  --show-bin-path         Print the binary output path
  --static-swift-stdlib   Link Swift stdlib statically
  --target                Build the specified target
  --verbose, -v           Increase verbosity of informational output
  -Xcc                    Pass flag through to all C compiler invocations
  -Xcxx                   Pass flag through to all C++ compiler invocations
  -Xlinker                Pass flag through to all linker invocations
  -Xswiftc                Pass flag through to all Swift compiler invocations
  --help                  Display available options

可以看到build项目除了直接用build命令之外还可以加上一些额外的选项。这里做一下讲解

代码语言:javascript
复制
USAGE: swift build [options]

OPTIONS:
  --build-path            指定编译文件存放的路径(默认路径是./.build)
  --build-tests           编译源码和测试代码
  --configuration, -c     编译环境(debug|release),默认是debug
  --disable-prefetching   禁止prefetching
  --disable-sandbox       禁用沙盒
  --enable-build-manifest-caching 
                          打开llbuild清单缓存(实验功能,这个就是增量编译了)
  --no-static-swift-stdlib 不要静态link Swift stdlib
  --package-path          当自己指定源代码路径的时候使用此命令
  --product               编译指定的product
  --show-bin-path         打印二进制文件输出路径
  --static-swift-stdlib   静态link Swift stdlib
  --target                编译特定的target
  --verbose, -v           Increase verbosity of informational output
  -Xcc                    将标志传递给所有C编译器调用
  -Xcxx                   将标志传递给所有C++编译器调用
  -Xlinker                将标志传递给所有linker调用
  -Xswiftc                将标志传递给所有Swift编译器调用
  --help                  查看帮助

如果你只是一个swift开发人员,指定路径、指定环境是工作中会最常用到的命令。

  • 运行项目

执行命令

代码语言:javascript
复制
$ swift run --help
OVERVIEW: Build and run an executable product

USAGE: swift run [options] [executable [arguments ...]]

OPTIONS:
  --build-path            Specify build/cache directory [default: ./.build]
  --configuration, -c     Build with configuration (debug|release) [default: debug]
  --disable-prefetching   
  --disable-sandbox       Disable using the sandbox when executing subprocesses
  --enable-build-manifest-caching
                          Enable llbuild manifest caching [Experimental]
  --no-static-swift-stdlib
                          Do not link Swift stdlib statically
  --package-path          Change working directory before any other operation
  --skip-build            Skip building the executable product
  --static-swift-stdlib   Link Swift stdlib statically
  --verbose, -v           Increase verbosity of informational output
  -Xcc                    Pass flag through to all C compiler invocations
  -Xcxx                   Pass flag through to all C++ compiler invocations
  -Xlinker                Pass flag through to all linker invocations
  -Xswiftc                Pass flag through to all Swift compiler invocations
  --help                  Display available options

POSITIONAL ARGUMENTS:
  executable              The executable to run

和上面的build一样,在运行项目的时候,可以配置不同的环境参数来运行不同的target或环境

  • 添加依赖

通过SwiftPM创建项目的时候会在项目的根目录生成一个Package.swift的文件,这个文件就相当于cocoapods的Podfile 或者Carthage 的Cartfile.

首先来看看 HelloExcutable 这个项目的Package.swift文件:

代码语言:javascript
复制
// swift-tools-version:4.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "HelloExcutable",
    dependencies: [
        // Dependencies declare other packages that this package depends on.
        // .package(url: /* package url */, from: "1.0.0"),
    ],
    targets: [
        // Targets are the basic building blocks of a package. A target can define a module or a test suite.
        // Targets can depend on other targets in this package, and on products in packages which this package depends on.
        .target(
            name: "HelloExcutable",
            dependencies: []),
    ]
)

目前这个项目没有添加任何依赖,添加依赖的步骤如下:

1、引入一个依赖库SwiftNIO

代码语言:javascript
复制
import PackageDescription

let package = Package(
    name: "HelloExcutable",
    dependencies: [
        .package(url: "https://github.com/apple/swift-nio.git", from: "1.9.2")
    ],
    targets: [
        .target(
            name: "HelloExcutable",
            dependencies: ["NIO", "NIOHTTP1", "NIOFoundationCompat"]),
    ]
)

2、执行命令

代码语言:javascript
复制
swift build

这时候会下载依赖的package,下载完后会编译项目。

3、重新生成 xcodeproj文件(仅Mac适用)

代码语言:javascript
复制
swift package generate-xcodeproj

打开生成的 HelloExcutable.xcodeproj 文件就可以看到刚刚添加的依赖已经集成到项目里了:

添加dependencies之后的项目

Package.swift怎么写?

Package.swift是用于管理项目依赖以及项目结构的文件,文件内容就是一个 Package 类的实例。

Package

这里是Package这个Class的init方法:

代码语言:javascript
复制
final public class Package {

...

public init(name: String, //项目的名称
                pkgConfig: String? = default,
                providers: [PackageDescription.SystemPackageProvider]? = default,
                 products: [PackageDescription.Product] = default, // 对外公开的产物
             dependencies: [PackageDescription.Package.Dependency] = default, // 依赖
                  targets: [PackageDescription.Target] = default, // 项目的targets
    swiftLanguageVersions: [Int]? = default, // swift版本
        cLanguageStandard: PackageDescription.CLanguageStandard? = default, // c语言标准
      cxxLanguageStandard: PackageDescription.CXXLanguageStandard? = default) // c++语言标准
      
}

可以根据项目的需要,设置对应的参数。 比如要用SwiftPM做一个framework,那么需要设置products指定Framework的名字和target。

Package.Dependency

当项目中需要添加依赖的时候,需要设置dependencies参数, 是一个Package.Dependency类的集合,下面是Package.Dependency的部分源码:

代码语言:javascript
复制
extension Package.Dependency : Equatable {

    public static func package(url: String, from version: PackageDescription.Version) -> PackageDescription.Package.Dependency

    public static func package(url: String, _ requirement: PackageDescription.Package.Dependency.Requirement) -> PackageDescription.Package.Dependency

    public static func package(url: String, _ range: Range<PackageDescription.Version>) -> PackageDescription.Package.Dependency

    public static func package(url: String, _ range: ClosedRange<PackageDescription.Version>) -> PackageDescription.Package.Dependency
    
    ...
    
}

类似cocoapods 和 Carthage, Package.Dependency有两个参数,第一个参数设置依赖库的url,第二个参数设置依赖库的版本

设置版本的语法:

代码语言:javascript
复制
 .package(url:"", from: "1.0.0")                               (1.0.0 ..< 2.0.0)
 .package(url:"", from: "1.2.0")                               (1.2.0 ..< 2.0.0)
 .package(url:"", from: "1.5.8")                               (1.5.8 ..< 2.0.0)
 .package(url:"", .exactItem(Version(stringLiteral: "1.2.0"))  (==1.2.0)
 .package(url:"", .exactItem(Version(stringLiteral: "1.2.0"))  (==1.2.0)
 .package(url:"", .revisionItem("74663ec"))                    某次提交的revision的值
 .package(url:"", .branchItem("develop"))                      分支名
 .package(url:"", .localPackageItem)                           本地依赖
 .package(url:"", Version(stringLiteral: "1.2.3")...Version(stringLiteral: "1.2.8"))   (>=1.2.3 && <=1.2.8)
 .package(url:"", Version(stringLiteral: "1.2.3")..<Version(stringLiteral: "1.2.8"))   (>=1.2.3 && <1.2.8)

同样上面的Version也可以用以下方式来写:

Version(1, 2, 0) 相当于于 Version(stringLiteral: "1.2.0") Version(1, 0, 0)..<Version(1, .max, .max) 意思是版本大于1.0.0 小于2.0.0

Target

另外一个比较重要的类是Target:

代码语言:javascript
复制
final public class Package {

...

public static func target(name: String, // target的名称
                  dependencies: [PackageDescription.Target.Dependency] = default, // target 的依赖,这里面主要指定Package添加的依赖的module的名字
                          path: String? = default, // target的路径,如果自定义文件夹需要设置此参数
                       exclude: [String] = default,  // target path中不希望被包含的path
                       sources: [String]? = default,  // 资源文件的路径
             publicHeadersPath: String? = default // 公共header文件的路径
             ) -> PackageDescription.Target

...

}

用于定义项目里的target。

本篇主要介绍了SwiftPM的一些基础用法,使用时需要注意以下几点:

1、dependencies里面的链接和版本一定要写对,target里的dependencies对应的总的dependencies中的module,一个依赖可以有多个module。

2、注意多个库依赖时的兼容性,如果出现卡着不动的时候,常常是依赖的版本有问题,可以逐步添加来排查问题。

3、Package.swift中的语法不要写错,注意 [ ]和 ""要成对存在,不要漏了前后的符号。

4、如果你不是在Mac上开发,可以使用Atom等支持高亮的编辑器来编辑Package.swift文件。

5、不要去尝试用它来管理iOS项目的依赖,现在还不支持,到支持的时候我会更新此文章。

希望本文能给你带来一些帮助,有疑问或者需要补充的地方欢迎留言。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.08.28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • SwiftPM有什么作用?
  • SwiftPM有哪些局限?
  • 那么,让我门开始吧
    • 实际项目种使用
      • Package.swift怎么写?
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档