8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【SwiftPM】Swift Package Manager 4.0でCLIアプリケーションを作る

Last updated at Posted at 2017-12-24

Swift Package Managerとは

Swift製のパッケージマネージャでSwiftPMと呼ばれたりします。
CocoaPodsやCarthageとは違ってCLIアプリケーションやサーバサイドSwiftで利用されることが多い状況です。
バージョン3の情報はある程度増えてきてはいますが、現在の最新バージョンである4.0.0の情報はまだまだ少ないので、今回はSwiftPM 4を使ってCLIをツールを作ってみたいと思います。

何を作るか

こんな感じであいさつするやつを作りたいと思います。

$ hello-swift-pm
Hello, SwiftPM!
$ hello-swift-pm --name Tom
Hello, Tom!
$ hello-swift-pm --name Tom --time morning
Good morning, Tom!
$ hello-swift-pm --time evening
Good evening, SwiftPM!

やっていき

バージョンの確認

SwiftとSwiftPMのバージョンは次のような感じです。

$ swift --version
Apple Swift version 4.0.3 (swiftlang-900.0.74.1 clang-900.0.39.2)
$ swift package --version
Apple Swift Package Manager - Swift 4.0.0-dev (swiftpm-13752)

プロジェクトの新規作成

今回はhello-swift-pmというディレクトリに作っていきます。

$ mkdir hello-swift-pm
$ cd hello-swift-pm
$ swift package init --type executable
$ tree
.
├── Package.swift
├── README.md
├── Sources
│   └── hello-swift-pm
│       └── main.swift
└── Tests

3 directories, 3 files

ビルドしてみる

デフォルトで生成されているHello, world!アプリをビルドしてみましょう。

$ swift build
$ ./.build/debug/hello-swift-pm 
Hello, world!

Xcodeプロジェクトの生成

コードの編集はXcodeでやりたいってことでXcodeプロジェクトを生成します。
しかし、これはコードからいい感じにXcodeプロジェクトを生成しているだけなので、Xcodeからはコードの編集のみを行うようにしてください。
ファイルやディレクトリを追加する場合はコマンドラインから作成し、Xcodeプロジェクトを再度生成したほうが良いです。

$ swift package generate-xcodeproj
$ open hello-swift-pm.xcodeproj/

外部依存ライブラリの指定

今回はCommanderというライブラリを用いてCLIアプリケーションを作りたいと思います。
次のような変更を加えて依存パッケージをビルドします。

Package.swift
// 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: "hello-swift-pm",
    dependencies: [
        // Dependencies declare other packages that this package depends on.
        // .package(url: /* package url */, from: "1.0.0"),
+       .package(url: "https://github.com/kylef/Commander.git", from: "0.8.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: "hello-swift-pm",
-           dependencies: []),
+           dependencies: ["Commander"]), // ここはimportするときのパッケージ名を書く
    ]
)

$ swift package update
Fetching https://github.com/kylef/Commander
Fetching https://github.com/kylef/Spectre.git
Cloning https://github.com/kylef/Spectre.git
Resolving https://github.com/kylef/Spectre.git at 0.8.0
Cloning https://github.com/kylef/Commander
Resolving https://github.com/kylef/Commander at 0.8.0

ちなみに、targetsの中のdependenciesに書く名前は、リポジトリ名ではなく、importするときのパッケージ名を書く必要があることに注意してください。
ライブラリ名とパッケージ名は同じことが多いのでハマりポイントだと思います。
(例: SwiftYaml -> Yaml ( https://github.com/behrang/YamlSwift ))

main.swiftの実装

CLIアプリケーションのメイン部分を作っていきましょう。
CommanderimportできないときはXcodeプロジェクトを再生成してみると直るかも。

main.swift
import Commander

enum Greeting {
    enum ParseError: Error, CustomStringConvertible {
        case invalidTime

        var description: String {
            switch self {
            case .invalidTime:
                return "Invalid time option"
            }
        }
    }

    static func validator(time: String) throws -> String {
        switch time {
        case "morning": return "Good morning, "
        case "evening": return "Good evening, "
        default: throw ParseError.invalidTime
        }
    }
}

let main = command(
    Option("name", default: "SwiftPM"),
    Option("time", default: "daytime", description: "morning or evening", validator: Greeting.validator)
) { name, time in
    let greeting = time == "daytime" ? "Hello, " : time
    print(greeting + name + "!")
}

main.run()

最後にリリースビルドして完了

$ swift build -c release
$ ./.build/release/hello-swift-pm --name Tom --time morning
Good morning, Tom!

完成品

完成品のコードはGitHubに置いています。

おわりに

今回はSwift Package Manager 4.0を使ってCLIアプリケーションを作ってみました。
最後まで読んでいただきありがとうございました。
今回はあまり難しいことはしていませんが、Package.swiftの書き方がバージョン3から少し変更されていてしっかり最新情報を追っていないとハマりそうだと思いました。
間違いや追加情報などあればコメントしていただけると嬉しいです。

8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?