[2021年版]XcodegenでCarthageとCocoapodsを使う最小プロジェクトを作成

[2021年版]XcodegenでCarthageとCocoapodsを使う最小プロジェクトを作成

個人アプリのプロジェクト構成をXcodegenで作り直そうかと思っています。
個人アプリはライブラリーの依存関係をCarthageとCocoapodsを使って管理していますが、Xcodegenではどういう記述でproject.ymlを書けばいいのかが検討つきませんでした。
理解を深めるために最小プロジェクトを作ることにしました。

この記事ではXcodegenでCarthageとCocoapodsを使う最小プロジェクトを解説します。

実行環境

  • Xcode 12.4
  • Xcodegen
  • Carthage: 0.37.0
  • Cocoapods:

ディレクトリ

今回はTryXcodegenという名前のプロジェクトを作成して、CarthageとCocoapodsでライブラリーを管理し、プロジェクト生成にXcodegenを利用します。

最終的なディレクトリ構造は次のとおりです。
主要なもののみ掲載しています。

$ tree -L 2  
.
├── Cartfile
├── Cartfile.resolved
├── Carthage
│   ├── Build
├── Podfile
├── Podfile.lock
├── Pods
|   ├── ...
├── TryXcodegen
├── TryXcodegen.xcodeproj
├── TryXcodegen.xcworkspace
├── carthage.sh
└── project.yml

Xcodeでもとのプロジェクトを作成

まずはTryXcodegenという名前でXcodeでプロジェクトを作成しておきます。
テンプレートファイルを作成するためです。

Carthageを使う

Xcode 12でCarthageを使うにはXCFrameworkでビルドをする必要があります。
そのため、Carthageのバージョンは0.37.0を使いましょう。

詳しくはこの記事をご覧ください。
CarthageのXcode 12エラー: This usually indicates that project itself failed to compile.を直す

--use-xcframeworksオプションを使うことでXCFrameworkでビルドできます。

今回の例ではDeviceという実行端末をアプリから確認できるライブラリーを使います。
まずはCartfileはこちらです。

# Cartfile
github "Ekhoo/Device" ~> 3.2.1

プロジェクトファイルがあるディレクトリでcarthageコマンドを実行します。
--use-xcframeworksオプションを忘れずにつけます。

$ carthage bootstrap --platform iOS --use-xcframeworks

するとDevice.xcframework./Carthage/Build/以下に出力されます。

Xcodegenのproject.ymlのframeworkキーにDevice.xcframeworkのパスを指定します。
パスはproject.ymlからみたパスです。

# project.yml
dependencies:
      - framework: "Carthage/Build/Device.xcframework"

ここで、carthageコマンドを使わないの?と思われた方もいるかと思います。
以前はcarthageキーを指定することでXcodegenはcarthage copy-frameworksコマンドをrun scriptとして自動的に作成していました。
しかしXCFrameworkを利用することでその作業は不要になりました。
なので単純にframeworkキーを指定すれば問題ありません。

詳しくはこちらをご覧ください。
https://github.com/yonaskolb/XcodeGen/issues/1006

Cocoapods

CocoapodsとXcodegenの連携方法です。
通常と同じ用にPodfileをプロジェクトと同じディレクトリに置きます。
例としてFirebaseのAnalyticsを入れてみます。

# Podfile
target 'TryXcodegen' do
  use_frameworks!
  pod 'Firebase/Analytics'
end

続いてXcodegenのproject.ymlです。optionspostGenCommandを指定することでプロジェクトファイルを作成した後にスクリプトを実行できます。
pod installを指定しておきましょう。

# project.yml
options:
  postGenCommand: pod install

Firebaseの各プロジェクトの詳細設定は公式を確認してください。
https://firebase.google.com/docs/ios/setup?authuser=1

CocoapodsのフレームワークはXcodegenで指定必要なし

私、ずっと勘違いしていました。
Cocoapodsが生成したフレームワークをXcodegenで指定が必要だと思っていました。
例えば今回の例ではCocoapodsはPods_TryXcodegen.frameworkというフレームワークを生成するので次のようにXcodegenで指定が必要なのかを思っていました。

# project.yml
dependencies:
    - framework: Pods_TryXcodegen.framework # cocoapodsが生成したフレームワークを指定する? -> 間違い

これをするとビルド失敗します。
CocoapodsはXcodegenが生成したプロジェクトファイルを上書きするので、Xcodegenでの指定は必要ありません。
通りでいくら調べても指定方法の記事がないわけです。

Firebase Crashlyticsを使う場合

Firebase Crashlyticsを使う場合はビルドフェーズにCrashlyticsを初期化するスクリプトを記述する必要があります。
こうすることでアプリがクラッシュするたびに Xcode が自動的にプロジェクトの dSYM ファイルをアップロードされ、Crashlytics は自動的にクラッシュ レポートを生成できます。

詳しくは公式ドキュメントをご覧ください
Firebase Crashlytics を使ってみる

このスクリプトはビルドフェーズの一番最後に実行する必要があります。
なのでXcodegenではなくて最終的にプロジェクトファイルを編集するCocoapodsでの管理が必要です。

script_phaseでビルドフェーズのスクリプトを追加します。

target 'TryXcodegen' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!
  pod 'Firebase/Analytics'
  pod 'Firebase/Crashlytics'
  script_phase :name => 'Run Fabric',
  :script => '"${PODS_ROOT}/FirebaseCrashlytics/run"',
  :input_files => ['${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${TARGET_NAME}', 
                   '$(SRCROOT)/$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)']
end

最終的にプロジェクトには次のキャプチャのような設定になるはずです。

----------2021-03-14-15.45.53

まとめ

今回はXcodegenでCarthageとCocoapodsを使う最小プロジェクトを作成する方法について解説しました。
Xcode 12になり少し実行方法が変わって戸惑うかもしれません。
参考になれば幸いです。
最後に各ファイルの全体像を記して記事を終わりたいと思います。

Cartfile

github "Ekhoo/Device" ~> 3.2.1

project.yml

name: TryXcodegen
options:
  deploymentTarget:
    iOS: "14.1"
  bundleIdPrefix: com.personal-factory
  postGenCommand: pod install

targets:
  TryXcodegen:
    platform: iOS
    type: application
    sources:
      - TryXcodegen
    dependencies:
      - framework: "Carthage/Build/Device.xcframework"

Podfile

target 'TryXcodegen' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!
  pod 'Firebase/Analytics'
  pod 'Firebase/Crashlytics'
  script_phase :name => 'Run Fabric',
  :script => '"${PODS_ROOT}/FirebaseCrashlytics/run"',
  :input_files => ['${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${TARGET_NAME}', 
                   '$(SRCROOT)/$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)']
end

実行するコマンド

$ carthage bootstrap --platform iOS --use-xcframeworks
$ xcodegen
$ open TryXcodegen.xcworkspace

参考

宣伝

インプレスR&D社より、「1人でアプリを作る人を支えるSwiftUI開発レシピ」発売中です。
「SwiftUIでアプリを作る!」をコンセプトにSwiftUI自体の解説とそれを組み合わせた豊富なサンプルアプリでどんな風にアプリ実装すればいいかが理解できる本となっています。
iOS 14対応、Widgetの作成も一章まるまるハンズオンで解説しています。
SwiftUIを学びたい方、ぜひこちらのリンクをチェックしてください!




https://nextpublishing.jp/book/12491.html