Swift Package Manager 2026年完全ガイド:パッケージ作成・公開・面接対策

Swift Package Managerの使い方を徹底解説。パッケージの作成、依存関係管理、ライブラリの公開方法、iOS技術面接でよく出る質問と回答例を網羅したチュートリアル。

Swift Package Manager 2026年完全ガイド:パッケージ作成・公開・面接対策

Swift Package Manager(SPM)は、Swiftプロジェクトにおける依存関係管理とパッケージ配布を担当するツールです。CocoaPodsやCarthageとは異なり、SPMはXcodeとSwiftツールチェーンに直接統合されており、外部ツールのインストールは不要です。Swift 6.2および6.3では、厳格なメモリ安全性設定、デフォルトアクター分離、新しいSwift Buildシステムが導入され、SPMはモダンなiOS開発における決定的な選択肢となっています。

SPMの役割

Swift Package Managerは依存関係の解決、ソースコードのダウンロード、モジュールのコンパイル、最終バイナリへのリンクを実行します。単一のPackage.swiftマニフェストファイルで、依存関係、ターゲット、プロダクト、ビルド設定のすべてを定義できます。

Package.swiftマニフェストの構造と構文

すべてのSwiftパッケージは、リポジトリのルートにあるPackage.swiftファイルから始まります。このマニフェストはSwiftコードを使用して、パッケージ構造、依存関係、ビルド構成を宣言します。

Package.swiftswift
import PackageDescription

let package = Package(
    name: "NetworkKit",
    platforms: [
        .iOS(.v15),
        .macOS(.v12)
    ],
    products: [
        .library(
            name: "NetworkKit",
            targets: ["NetworkKit"]
        )
    ],
    dependencies: [
        .package(
            url: "https://github.com/Alamofire/Alamofire.git",
            from: "5.9.0"
        )
    ],
    targets: [
        .target(
            name: "NetworkKit",
            dependencies: ["Alamofire"]
        ),
        .testTarget(
            name: "NetworkKitTests",
            dependencies: ["NetworkKit"]
        )
    ]
)

platforms配列は最小デプロイメントターゲットを指定します。productsセクションは他のパッケージがインポートできるものを定義します。targetsセクションはそれぞれの依存関係を持つコンパイル単位をリストします。

コマンドラインからのSwiftパッケージ作成

swift package initコマンドは、標準的なディレクトリ構造を持つ新しいパッケージの雛形を作成します。--typeフラグはパッケージがライブラリを生成するか実行可能ファイルを生成するかを決定します。

bash
# Create a library package
mkdir NetworkKit && cd NetworkKit
swift package init --type=library

# Generated structure:
# NetworkKit/
# ├── Package.swift
# ├── Sources/
# │   └── NetworkKit/
# │       └── NetworkKit.swift
# └── Tests/
#     └── NetworkKitTests/
#         └── NetworkKitTests.swift

swift buildを実行するとパッケージがコンパイルされます。swift testを実行するとテストスイートが実行されます。両コマンドは追加のセットアップなしでPackage.swiftの設定を使用します。

依存関係のバージョン要件と解決

SPMは3つのバージョン指定戦略をサポートしています:正確なバージョン、バージョン範囲、ブランチまたはコミット参照です。選択は再現性と柔軟性に影響します。

Package.swiftswift
dependencies: [
    // Semantic versioning: 5.9.0 up to next major
    .package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.9.0"),
    
    // Exact version: locks to 5.9.1
    .package(url: "https://github.com/Alamofire/Alamofire.git", exact: "5.9.1"),
    
    // Version range: 5.8.0 to 5.9.9
    .package(url: "https://github.com/Alamofire/Alamofire.git", "5.8.0".."5.9.9"),
    
    // Branch reference: for development
    .package(url: "https://github.com/Alamofire/Alamofire.git", branch: "main"),
    
    // Commit reference: pinned to specific commit
    .package(url: "https://github.com/Alamofire/Alamofire.git", revision: "abc123")
]

Package.resolvedファイルは依存関係解決時に解決された正確なバージョンを記録します。このファイルはチームメンバーやCIシステム間で再現可能なビルドを実現するために、バージョン管理にコミットする必要があります。

本番環境でのブランチ依存関係

ブランチおよびコミット参照はセマンティックバージョニングをバイパスします。本番アプリでbranch: "main"を使用すると、mainへのプッシュでビルドが壊れる可能性があります。ブランチ参照は未リリース機能に対するアクティブな開発のみに限定してください。

Xcodeプロジェクトへのパッケージ追加

Xcodeはファイルメニューを通じてSPMを統合しています。「File」から「Add Package Dependencies」に移動します。リポジトリURLを入力し、バージョンルールを選択し、どのターゲットが依存関係をリンクすべきかを選びます。

AppDelegate.swiftswift
import UIKit
import Alamofire // Available after adding via Xcode

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        AF.request("https://api.example.com/health").response { response in
            print(response.result)
        }
        return true
    }
}

Xcodeはパッケージ参照を.xcodeprojファイルに保存し、解決されたバージョンをプロジェクトルートのPackage.resolvedに保存します。Derived Dataフォルダはダウンロードされたパッケージをキャッシュします。

パス依存関係を使用したローカルパッケージ開発

開発中、リモートURLの代わりにローカルパスを指定することで、中間バージョンを公開せずに迅速な反復が可能になります。この手法はモノレポのセットアップや機能開発に適しています。

Package.swift in consuming packageswift
dependencies: [
    // Local path for development
    .package(path: "../NetworkKit"),
    
    // Remote URL for release
    // .package(url: "https://github.com/company/NetworkKit.git", from: "1.0.0")
]

非アクティブな行をコメントアウトすることで、ローカルとリモートの依存関係を切り替えます。XcodeとSwift CLIは消費パッケージからの相対パスで依存関係を解決します。

iOSの面接対策はできていますか?

インタラクティブなシミュレーター、flashcards、技術テストで練習しましょう。

GitHubへのSwiftパッケージ公開

公開にはセマンティックバージョンタグを持つGitリポジトリが必要です。SPMはGitタグをリリースバージョンとして扱います。Swift Package Indexは公開パッケージを自動的にインデックス化します。

bash
# Initialize repository and push
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/username/NetworkKit.git
git push -u origin main

# Create version tag
git tag 1.0.0
git push origin 1.0.0

# Other packages can now depend on:
# .package(url: "https://github.com/username/NetworkKit.git", from: "1.0.0")

セマンティックバージョニングの規約に従います:破壊的変更にはメジャーバージョン、新機能にはマイナーバージョン、バグ修正にはパッチバージョンをインクリメントします。SPMはfrom:バージョン要件を解決する際にこれらのルールへの準拠を前提としています。

Swift 6.2および6.3のパッケージ設定

Swift 6.2ではターゲットごとの言語モード設定と厳格なメモリ安全性設定が導入されました。Swift 6.3ではSwift Buildの統合がオプトイン機能として追加されています。

Package.swift with Swift 6.2+ featuresswift
import PackageDescription

let package = Package(
    name: "SafeNetworkKit",
    platforms: [.iOS(.v17)],
    products: [
        .library(name: "SafeNetworkKit", targets: ["SafeNetworkKit"])
    ],
    targets: [
        .target(
            name: "SafeNetworkKit",
            swiftSettings: [
                // Enable Swift 6 language mode for this target only
                .swiftLanguageMode(.v6),
                // Enable strict memory safety checking (SE-0458)
                .enableExperimentalFeature("StrictMemorySafety"),
                // Set default actor isolation (SE-0466)
                .enableExperimentalFeature("GlobalActorIsolation")
            ]
        )
    ]
)

swiftLanguageMode設定により、コードベース全体でSwift 6の機能を段階的に採用できます。同じパッケージ内のターゲットで異なる言語モードを使用することが可能です。

セキュリティコンプライアンスのためのSBOM生成

SE-0509により、Swift 6.3でネイティブのSoftware Bill of Materials生成が追加されました。SBOMドキュメントはセキュリティ監査と規制コンプライアンスのために、すべての依存関係とそのバージョンをリストします。

bash
# Generate SBOM in CycloneDX format
swift build --sbom-spec cyclonedx

# Generate SBOM using dedicated subcommand
swift package generate-sbom --format spdx

# Output includes:
# - Package name and version
# - All transitive dependencies
# - License information
# - Source repository URLs

エンタープライズ環境や政府契約では、SBOMドキュメントの要件が増加しています。CycloneDXおよびSPDXフォーマットは標準的な脆弱性スキャンツールと統合されます。

バイナリターゲットとXCFramework配布

バイナリターゲットにより、ソースコードの代わりにプリコンパイル済みフレームワークを配布できます。XCFrameworkは複数のプラットフォームとアーキテクチャ向けのバイナリをバンドルします。

Package.swift with binary targetswift
import PackageDescription

let package = Package(
    name: "AnalyticsSDK",
    platforms: [.iOS(.v14)],
    products: [
        .library(name: "AnalyticsSDK", targets: ["AnalyticsSDK"])
    ],
    targets: [
        .binaryTarget(
            name: "AnalyticsSDK",
            url: "https://releases.example.com/AnalyticsSDK-2.0.0.xcframework.zip",
            checksum: "abc123def456..."
        )
    ]
)

// Generate checksum:
// swift package compute-checksum AnalyticsSDK-2.0.0.xcframework.zip

バイナリターゲットは利用者のビルド時間を短縮し、プロプライエタリな実装を保護します。チェックサムはダウンロードの整合性を保証します。

Swift Package Managerに関するよくある面接質問

iOSポジションの技術面接では、SPMに関する質問が頻繁に含まれます。基本的な使い方からアーキテクチャの決定まで多岐にわたります。

Q: SPMはCocoaPodsやCarthageとどう違うか?

SPMは外部ツールなしでXcodeとSwiftツールチェーンに統合されています。CocoaPodsは中央仕様リポジトリを使用し、Xcodeワークスペース構造を変更します。Carthageは別のステップでフレームワークをビルドし、Xcode統合はありません。SPMは単一の統合プロセスで依存関係を解決してビルドします。Appleのswiftパッケージドキュメントで公式ツールについて確認できます。

Q: 依存関係解決中に何が起こるか?

SPMは再帰的にPackage.swiftマニフェストを読み込み、依存関係グラフを構築します。次にバージョン制約を適用して、すべてのパッケージの互換バージョンを見つけます。リゾルバは正確なバージョンをPackage.resolvedに書き込みます。2つのパッケージが共有依存関係の互換性のないバージョンを要求すると、競合が発生します。

Q: ダイヤモンド依存関係の競合をどう処理するか?

パッケージAとBが両方とも互換性のないバージョン要件でパッケージCに依存している場合、SPMは解決に失敗します。解決策には:1つの消費者をより広いバージョン範囲をサポートするように更新する、制限的なパッケージをフォークする、または同じモジュール名を持つ異なるパッケージ間の競合の場合はモジュールエイリアスを使用するなどがあります。

swift
// Module aliasing for name conflicts
.target(
    name: "MyApp",
    dependencies: [
        .product(name: "Logging", package: "swift-log", moduleAliases: ["Logging": "SwiftLogging"])
    ]
)

Q: ソース配布の代わりにバイナリターゲットを使用するのはいつか?

バイナリターゲットは、ソース公開が許容されないプロプライエタリSDK、コンパイル時間が開発者の生産性に影響する大規模な依存関係、プリビルトされたベンダーライブラリに適しています。依存関係へのデバッグが価値を持つオープンソースプロジェクトや内部ライブラリでは、ソース配布が依然として望ましいです。

CocoaPodsからSwift Package Managerへの移行

移行にはPodfileエントリをSPMパッケージ参照に置き換える必要があります。すべてのCocoaPodsにSPMの同等品があるわけではないので、開始前にSwift Package Indexで利用可能性を確認してください。

ruby
# Before: Podfile
pod 'Alamofire', '~> 5.9'
pod 'SwiftyJSON', '~> 5.0'
pod 'Kingfisher', '~> 7.0'
swift
// After: Package dependencies in Xcode
// File > Add Package Dependencies for each:
// https://github.com/Alamofire/Alamofire.git from 5.9.0
// https://github.com/SwiftyJSON/SwiftyJSON.git from 5.0.0
// https://github.com/onevcat/Kingfisher.git from 7.0.0

移行後、Podfile、Podfile.lock、Podsディレクトリを削除します。pod deintegrateを実行してCocoaPodsワークスペースの変更を削除します。Swiftファイルのimport文は変更されません。

本番アプリ向けSPMベストプラクティス

  • 安定性のためにfrom:でメジャーバージョンを固定し、マイナーアップデートとパッチを受け取る
  • チーム全体で再現可能なビルドを確保するためにPackage.resolvedをコミットする
  • アクティブな開発中はローカルパッケージを使用し、マージ前にリモートURLに切り替える
  • リリースビルドにバンドルされないよう、testTargetを使用してテスト専用の依存関係を分離する
  • マニフェストの先頭で最小Swiftツールバージョンを文書化する:// swift-tools-version: 5.10
  • リリースのタグ付け前にCIでパッケージのビルドを検証する
Swiftツールバージョン

// swift-tools-version:コメントはPackage.swiftの最初の行に表示される必要があります。これはマニフェストが使用するPackageDescription APIバージョンを決定します。Swift 6.0では、ライセンスヘッダーのためにこのコメントを後続の行に配置できる柔軟性が追加されました。

iOS開発者向けSPM重要ポイント

  • SPMはXcodeにネイティブに統合されており、CocoaPodsとCarthageのセットアップオーバーヘッドを排除する
  • Package.swiftマニフェストはSwiftコードを使用し、型チェックされた依存関係宣言を可能にする
  • バージョン要件はセマンティックバージョニング範囲、正確なバージョン、ブランチ参照をサポートする
  • Package.resolvedは再現可能なビルドのために依存関係バージョンをロックする
  • Swift 6.2でターゲットごとの言語モードと厳格なメモリ安全性設定が追加された
  • Swift 6.3でコンプライアンスドキュメント用のSBOM生成が導入された
  • バイナリターゲットはソース配布が実用的でない場合にプリコンパイルされたXCFrameworkを配布する
  • 面接質問は解決の競合、移行戦略、SPMと代替手段間のアーキテクチャ上のトレードオフに焦点を当てる

包括的なiOS面接対策には、SharpSkillのSwiftUI状態管理プロトコル指向プログラミングモジュールを確認してください。

今すぐ練習を始めましょう!

面接シミュレーターと技術テストで知識をテストしましょう。

今日のチャレンジ

iOS のバグを見つけられますか

実際のコード、隠れたバグ、1日1回。アカウントなしで試せます。

Anthony Fillion-Maillet

執筆

Anthony Fillion-Maillet

SharpSkill 創業者

10 年以上フルスタック開発に携わっています。SharpSkill を運営し、ここで公開される内容に責任を負っています。

2026年9月20日 更新

共有

関連記事