パッケージマネージャ


Swift Package Manager は、Swift コードの配布を管理するためのツールです。ダウンロード、コンパイル、および依存関係リンクのプロセスを自動化するために、Swift ビルドシステムと統合されています。


パッケージマネージャは、Swift 3.0 以上に含まれています。


概念の概要


このセクションでは、Swift Package Manager の機能を動機付ける基本的な概念について説明します。


モジュール


Swift は、コードを モジュール に整理します。各モジュールは名前空間を指定し、そのコードの一部をモジュール外で使用できるアクセス制御を強制します。


プログラムは、すべてのコードを 1 つのモジュールに持つこともあれば、他のモジュールを 依存関係 としてインポートすることもあります。MacOS 上の Darwin や Linux 上の Glibc など、システムが提供するいくつかのモジュールのほかに、ほとんどの依存関係では、コードをダウンロードして使用するためにビルドする必要があります。


特定の問題を解決するコードに別のモジュールを使用すると、そのコードは他の状況で再利用できます。例えば、ネットワーク要求を作成するための機能を提供するモジュールは、写真共有アプリと天気アプリとの間で共有することができます。モジュールを使用すると、同じ機能を自分自身で再実装するのではなく、他の開発者のコードの上にビルドできます。


パッケージ


パッケージ は Swift ソースファイルとマニフェストファイルで構成されます。Package.swift というマニフェストファイルは、PackageDescription モジュールを使用してパッケージの名前とその内容を定義します。


パッケージには 1 つ以上のターゲットがあります。各ターゲットは製品を指定し、1 つ以上の依存関係を宣言することができます。


製品


ターゲットは、その製品としてライブラリまたは実行可能ファイルのいずれかをビルドできます。ライブラリ には、他の Swift コードでインポートできるモジュールが含まれています。実行可能ファイル は、オペレーティングシステムによって実行できるプログラムです。


依存関係


ターゲットの依存関係は、パッケージ内のコードによって必要とされるモジュールです。依存関係は、パッケージのソースへの相対 URL または絶対 URL と、使用可能なパッケージのバージョンに対する一連の要件で構成されます。パッケージマネージャの役割は、プロジェクトのすべての依存関係をダウンロードしてビルドするプロセスを自動化することによって、調整コストを削減することです。これは再帰的プロセスです。依存関係には独自の依存関係を持たせることができ、それぞれの依存関係も依存関係を持つ事ができ、依存関係グラフを作成することもできます。パッケージマネージャは、依存関係グラフ全体を満たすために必要なすべてをダウンロードしてビルドします。


以下のセクションでは、Swift の実践的知識を前提としています。言語に慣れていない場合は、最初に導入リソースの 1 つを参考にしてください。Swift プログラミング言語Swift のツアー をお勧めします。

コード例を踏襲したい場合は、Swift をインストールしておく必要があります。Swift をインストールする方法については、入門 を参照してください。


例の使用法


Swift 4.0 入門 では、Swift Package Manager を使用して簡単な "Hello、world!" プログラムをビルドしました。


Swift Package Manager ができることをより完全に理解するために、以下の例は 4 つの相互依存するパッケージで構成されています。


GitHub からディーラープロジェクト のソースコードをダウンロードし、以下のコマンドを実行することで、完全なサンプルをビルドして実行することができます。

$ cd example-package-dealer
$ swift build
$ .build/debug/Dealer


ライブラリパッケージの作成


標準の 52 枚のカードデッキにトランプを表すモジュールを作成するのを始めます。PlayingCard モジュールは、Suit 列挙値 (Clubs、Diamonds、Hearts、Spades) と Rank 列挙値 (Ace、Two、Three、...、Jack、Queen、King) からなる PlayingCard 型を定義します。


public enum Rank : Int {
    case Ace = 1
    case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
    case Jack, Queen, King
}

public enum Suit: String {
    case Spades, Hearts, Diamonds, Clubs
}

public struct PlayingCard {
    let rank: Rank
    let suit: Suit
}


慣例として、パッケージには、Sources/ ディレクトリにある全てのソースファイルが含まれます。


example-package-playingcard
├─ Sources
│     ├── PlayingCard.swift
│     ├── Rank.swift
│     └── Suit.swift
└── Package.swift


PlayingCard モジュールは実行可能ファイルを生成しないため、ライブラリ として記述できます。ライブラリとは、他のパッケージからインポートできるモジュールをビルドするパッケージです。デフォルトでは、ライブラリモジュールは、Sources/ ディレクトリにあるソースコードで宣言されているすべての public 型とメソッドを公開します。


Swift ビルドプロセスを開始するために swift build を実行します。すべて正常に動作した場合、PlayingCard の Swift モジュールをコンパイルします。


PlayingCard パッケージの完全なコードは https://github.com/apple/example-package-playingcard にあります。


ビルド構成文の使用


ビルドする次のモジュールは FisherYates です。PlayingCard とは異なり、このモジュールは新しい型を定義しません。その代わりに、既存の型、特に CollectionTypeMutableCollectionType のプロトコルを拡張して、shuffle() メソッドとそれに対応する変更可能な shuffleInPlace() メソッドを追加します。


shuffleInPlace() の実装では、Fisher-Yates アルゴリズムを使用して、コレクション内の要素をランダムに並べ替えます。Swift 標準ライブラリは乱数発生器を提供しないため、このメソッドはシステムモジュールからインポートされた関数を呼び出さなければなりません。この関数が macOS と Linux の両方と互換性があるためには、コードはビルド構成文を使用します。


macOS では、システムモジュールは Darwin であり、これは arc4random_uniform(_:) 関数を提供します。Linux では、システムモジュールは Glibc で、random() 関数を提供します:


#if os(Linux)
import Glibc
#else
import Darwin.C
#endif

public extension MutableCollectionType where Index == Int {
    mutating func shuffleInPlace() {
        if count <= 1 { return }

        for i in 0..<count - 1 {
#if os(Linux)
            let j = Int(random() % (count - i)))) + i
#else
            let j = Int(arc4random_uniform(UInt32(count - i))) + i
#endif
            if i == j { continue }
            swap(&self[i], &self[j])
        }
    }
}


FisherYates パッケージの完全なコードは https://github.com/apple/example-package-fisheryates にあります。


依存関係のインポート


DeckOfPlayingCards パッケージは、前の 2 つのパッケージを一緒にします。これは、PlayCard 値の配列に対して FisherYates からの shuffle() メソッドを使用する Deck 型を定義します。


FisherYates および PlayingCards モジュールを使用するには、DeckOfPlayingCards パッケージは、そのパッケージを Package.swift マニフェストファイルの依存関係として宣言しなければなりません。


import PackageDescription

let package = Package(
    name: "DeckOfPlayingCards",
    targets: [],
    dependencies: [
        .Package(url: "https://github.com/apple/example-package-fisheryates.git",
                 majorVersion: 1),
        .Package(url: "https://github.com/apple/example-package-playingcard.git",
                 majorVersion: 1),
    ]
)


各依存関係は、ソースの URL とバージョン要件を指定します。ソースの URL は、現在のユーザーにアクセス可能な URL で、Git リポジトリに解決されます。セマンティックバージョニング (SemVer) 規約に従うバージョン要件は、どの Git タグをチェックアウトして依存関係をビルドするのかを決定するために使用されます。FisherYatesPlayingCard の両方の依存関係では、メジャーバージョンが 1 (たとえば、1.0.0) の最新バージョンが使用されます。


swift build コマンドを実行すると、パッケージマネージャはすべての依存関係をダウンロードし、コンパイルしてパッケージモジュールにリンクします。これにより、DeckOfPlayingCards は、import 文を使用して、依存モジュールのパブリックメンバーにアクセスできます。


ダウンロードしたソースは、プロジェクトのルートにある Packages ディレクトリ、およびプロジェクトのルートにある .build ディレクトリ内の中間ビルドプロダクトで見る事ができます。


DeckOfPlayingCards パッケージの完全なコードは https://github.com/apple/example-package-deckofplayingcards にあります。


副依存関係の解決


他のすべてが整ったら、Dealer モジュールをビルドすることができます。Dealer モジュールは、DeckOfPlayingCards パッケージに依存し、これは、PlayingCard パッケージと FisherYates パッケージに依存します。ただし、Swift Package Manager は副依存関係を自動的に解決するため、DeckOfPlayingCards パッケージを依存関係として宣言するだけで済みます。


import PackageDescription

let package = Package(
    name: "Dealer",
    targets: [],
    dependencies: [
        .Package(url: "https://github.com/apple/example-package-deckofplayingcards.git",
                 majorVersion: 1),
    ]
)


Swift では、コードで参照される任意の型のモジュールをソースファイルがインポートする必要があります。Dealer モジュールの main.swift ファイルでは、DeckOfPlayingCards から Deck 型と PlayingCard から PlayingCard 型が参照されます。Deck 型の shuffle() メソッドは FisherYates モジュールを内部的に使用しますが、そのモジュールは main.swift にインポートする必要はありません。


import PlayingCard
import DeckOfPlayingCards

let numberOfCards = 10

var deck = Deck.standard52CardDeck()
deck.shuffle()

for _ in 1...numberOfCards {
    guard let card = deck.deal() else {
        print("No More Cards!")
        break
    }

    print(card)
}


通常、ルートディレクトリに main.swift という名前のファイルを含むパッケージは、実行可能ファイルを生成します。


swift build コマンドを実行すると、Swift ビルドシステムが起動され、.build/debug ディレクトリから実行可能な Dealer 実行可能ファイルを生成します。


$ swift build
$ ./.build/debug/Dealer
♠︎6
♢K
♢2
♡8
♠︎7
♣︎10
♣︎5
♢A
♡Q
♡7


Dealer パッケージの完全なコードは https://github.com/apple/example-package-dealer にあります。


Swift Package Manager の使用方法の詳細については、GitHub の Swift Package Manager プロジェクト で提供されているマニュアルを参照してください。


コミュニティの提案


Swift Package Manager の最初のリリースは出発点に過ぎないので、可能な限り最良のツールをビルドするために参加してください。


プロジェクトを開始するのに役立つように、私たちは現在の実装での意思決定のコンテキストを提供する以下のコミュニティの提案を準備し、将来の機能の開発の方向性を示します。あなたが参加することに関心があるならば、これは読んでおくべき最初の文書です。


Swift Package Manager の "コミュニティの提案" を読んで下さい。





目次
Xcode 9 の新機能

SwiftLogo
  • Swift について
  • 特徴
    安全
    Swift.org とオープンソース
    プロジェクト
    プラットフォームサポート
    アップルのプラットフォーム
    Linux
  • ブログ:Swift 4.0 リリース!
  • 言語の更新
    文字列
    コレクション
    アーカイブとシリアル化
    その他の言語の更新
    新しい互換モード
    Package Manager の更新
    文書化
  • プラットフォーム
  • Linux
    Apple(Xcode)
    ソース
  • Swift のローカルリファクタリング
  • リファクタリングの種類
    カーソルベースのリファクタリング
    レンジベースのリファクタリング
    診断
    テスト
    文脈上のリファクタリングテスト
    コード変換テスト
    Xcode との統合
    潜在的なローカルリファクタリングの考え方
  • Swift のダウンロード
  • リリース
    Swift 4.0
    Swift 3.1.1
    Swift 3.1
    Swift 3.0.2
    Swift 3.0.1
    Swift 3.0
    Swift 2.2.1
    Swift 2.2
    スナップショット
    基幹となる開発(マスター)
    古いスナップショット
    Swift 4.0 の開発
    古いスナップショット
    Swift 3.1 の開発
    古いスナップショット
    古いリリースの分岐
    ダウンロードを使用して
    インストール
    MacOS でのコード署名
    Linux
    必要
    サポートしているターゲットプラットフォーム
    インストール
    アクティブな署名鍵
  • Swift 4.0 入門
  • Swift のインストール
    Linux の場合
    REPL の使用
    パッケージマネージャの使用
    パッケージの作成
    実行可能ファイルの作成
    複数のソースファイルの操作
    LLDB デバッガの使用
  • 文書化
  • Swift プログラミング言語
    翻訳
    API 設計ガイドライン
  • API 設計ガイドライン
  • 目次
    基礎
    ネーミング
    明確な使用の促進
    流暢な使用を目指す
    用語をよく使う
    規約
    一般的規約
    パラメータ
    引数ラベル
    特別な命令
  • Swift 4 への移行
  • 移行前の準備
    Swift 移行アシスタント
    Swift 4 移行の変更の概要
    SDK の変更点
    注目すべき特別なケース
    新しい String
    デフォルトのパラメータ値は public です
    移行の後
    移行に関する既知の問題
    Carthage/CocoaPods プロジェクトの使用
    その他
  • Swift 3 への移行
  • 移行前の準備
    Swift 移行アシスタント
    Swift 3 移行変更の概要
    API 設計ガイドライン
    SDK
    Swift 標準ライブラリ
    言語
    移行後
    Carthage/CocoaPods プロジェクトの使用 既知の移行の問題
    Swift 標準ライブラリ
    SDK
    Swift 3 言語
    その他
  • ソースコード
  • コンパイラと標準ライブラリ
    Core Library
    パッケージマネージャ
    Xcode の Playground サポート
    クローンされたリポジトリ
  • コミュニティガイドライン
  • コミュニケーション
    コミュニティの構造
    プロジェクトリーダー
    コアチーム
    コードオーナー
    ライセンス
    Runtime Library Exception (実行時ライブラリ例外)
    ソースコードの著作権とライセンス
    投稿
    入門
    コードの貢献 (投稿)
    新しい機能の提案
    行動規範
    投稿者行動規範 v1.3
    報告
    メーリングリスト
    General Interest
    Swift 開発
    Swift の発展
    通知
  • 投稿
  • 質問に答える
    バグを報告する
    バグのトリアージ
    コードの投稿
    段階的な開発
    メッセージをコミットする
    変更の帰属
    コードテンプレート
    コードのレビュー
    テスト
    品質
    コミットアクセス
    外部ライブラリ依存関係の追加
    Swift 発展プロセスへの参加
    LLVM と Swift
    LLVM の変更はどこで行われますか?
    Swift と LLVM 開発者ポリシー
  • Swift の継続的インテグレーション
  • 構成
    ジョブの組織
    ジョブの構成
    使用法
    リクエストのテスト
  • Swift ソースの互換性
  • プロジェクトの現在のリスト
    プロジェクトの追加
    合格基準
    プロジェクトの追加
    プロジェクトの維持
    リクエストのテスト
    プロジェクトをビルドする
    フォーカスエリア
  • ABI の安定性
  • データレイアウト
    メタデータ型
    切り分け
    呼び出し規約
    実行時
    標準ライブラリ
  • サーバーAPIプロジェクト
  • フォーカスエリア
    移植性
    外部ライブラリの使用
    ワークグループ
    舵取りチーム
    ステークホルダー
    開発プロセス
    API の提案
    プロトタイプ化と開発
    リリースプロセス
    メーリングリスト
  • コンパイラと標準ライブラリ
  • コンパイラのアーキテクチャ
    標準ライブラリの設計
  • パッケージマネージャ
  • 概念の概要
    モジュール
    パッケージ
    製品
    依存関係
    例の使用法
    ライブラリパッケージの作成
    ビルド構成文の使用
    依存関係のインポート
    副依存関係の解決
    コミュニティの提案
  • Swift コアライブラリ
  • プロジェクトの状態
    Foundation
    libdispatch
    XCTest
  • REPL とデバッガ、プレイグラウンド
  • なぜ REPL とデバッガを組み合わせるのか?
    Xcode プレイグラウンドサポート












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)












    トップへ(Swift 4.0)