mcpField
S
Shared SwiftUI App Workflow

Shared SwiftUI App Workflow

github.com/mosif16開発1837 回インストール48 週間前に更新
リポジトリ

Shared SwiftUI App Workflow について

iOS と macOS 向けの SwiftUI アプリの構築、テスト、配布を扱うワークフローガイドです。Catalyst も選択肢に含み、共通プロジェクト設定、アーキテクチャ、デバッグ、自動テスト、CI/CD、TestFlight 配信を説明します。

主な機能

  1. 01iOS と macOS の共通プロジェクトを設定
  2. 02SPM または CocoaPods で依存関係を管理
  3. 03MVVM または TCA でアプリを構成
  4. 04Xcode のツールでデバッグとプロファイル
  5. 05ユニットテストと UI テストを計画
  6. 06CI/CD と TestFlight 配信を設定

活用シーン

  1. 01iOS と macOS 向け SwiftUI アプリを開始
  2. 02アプリのアーキテクチャを選択
  3. 03UI やパフォーマンスの問題を調査
  4. 04テストとアプリ配布を準備

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mosif16/codex-skills --skill shared-swiftui-app-workflow

インストール後、Claude Code で/shared-swiftui-app-workflowを入力して読み込まれたか確認します。

詳細

手順

  • 概要: このワークフローでは、iOS と macOS の両方を対象とした SwiftUI アプリのビルド、テスト、デプロイに関するベストプラクティスを説明します(Catalyst の利用も可能です)。プロジェクトのセットアップ、アーキテクチャの選択、開発手法、継続的デリバリーの手順を取り上げます。
  • 前提条件: 最新の Xcode(Xcode 15 以降)をインストールし、Apple Developer Program に登録してください(コード署名、Xcode Cloud、TestFlight の利用に必要です)。SwiftUI、Git によるソース管理、iOS/macOS アプリ開発の基本知識があることを前提とします。
  • 使い方: 以下の手順に沿って、マルチプラットフォーム Xcode プロジェクトを構成し、依存関係を管理して、アーキテクチャ(MVVM または TCA)を実装します。また、効率的にデバッグとプロファイリングを行い、CI/CD パイプラインを設定して、最後に TestFlight 経由でアプリを配布します。
  • 表記規則: このガイドでは、重要な操作に太字のタイトルを、ツール名や概念にイタリック体を使用します。これらの手順を適用する際は、例に含まれるプレースホルダー(バンドル識別子やスキーム名など)を、ご自身のプロジェクトに固有の値に置き換えてください。

ワークフロー

  1. マルチプラットフォーム Xcode プロジェクトを作成する: まず、iOS と macOS の両方を対象とする新しい Xcode プロジェクトを作成します。Xcode 14 以降には Multiplatform App テンプレートが用意されており、SwiftUI を使って iOS(および iPadOS)と macOS 向けにビルドできる単一のターゲットを設定できます。この統合されたターゲットでは、ほとんどのコードとアセットをプラットフォーム間で共有できます。ターゲットを分けたい場合は、iOS アプリを作成してから macOS ターゲットを追加する(または iOS ターゲットで Mac Catalyst を有効にする)方法もあります。共有コード(SwiftUI のビューやモデルなど)をクロスプラットフォームのグループにまとめ、プラットフォーム固有のコードにはプラットフォームチェック(#if os(iOS)、#if os(macOS))を使用してください。プロジェクトを共有コードベースとして構成することで、デバイスの種類に応じて必要な UI を調整しながら、重複を最小限に抑えられます。

  2. ターゲット、スキーム、構成を設定する: マルチプラットフォームプロジェクトには、Debug と Release の構成がすでに含まれている場合があります。必要に応じて、独自の ビルド構成(Staging や QA など)を追加できます。ターゲットを分ける場合(Catalyst 用、または環境ごとのバリエーション用)は、各ターゲットに固有の バンドル識別子 と Info.plist を設定してください。たとえば、macOS ターゲットのバンドル ID には ".mac" を、開発ビルドには ".dev" を末尾に付けます。各アプリターゲットまたは環境に対応する スキーム を作成すると、それぞれのバージョンを簡単に実行してアーカイブできます。スキームを「Shared」としてマークし、ソース管理に含めてください(チームでの利用や CI に重要です)。このマルチターゲット構成を使えば、たとえば iOS アプリ、ネイティブ macOS アプリ、さらには Catalyst アプリを、それぞれ独自のスキームとバンドル ID を持たせて、すべて 1 つのプロジェクトにまとめられます。

  3. 環境設定を構成する: Xcode のビルド構成オプションを使って、環境ごとの設定を管理します。たとえば、カスタム XCConfig ファイルを定義するか、API エンドポイントや機能フラグなどの値に ユーザー定義のビルド設定 を使用できます。Info.plist には、それらの設定を参照するキーを定義してください。たとえば、Info.plist に BaseURL キーを追加し、構成ごとに設定する $(BASE_URL) などの値を割り当てます。Build Settings で、構成(Dev、QA、Prod など)ごとに、適切な URL を指定したユーザー定義変数 BASE_URL を作成します。アプリでは、たとえば実行時に次のように読み取れます。

    let apiURL = Bundle.main.object(forInfoDictionaryKey: "BaseURL") as? String この方法なら、環境値をハードコードせずに済みます。さらに、条件付きコードにはコンパイラフラグの使用も検討してください。各構成のビルド設定で、-DDEVELOPMENTや-DPRODUCTIONなどのSwiftフラグを追加できます。その後、Swiftコードで#if DEVELOPMENTを使用して、デバッグ専用のロジックを含めたり、テスト用のプレースホルダーを使用したりできます。この方法なら、構成の違いをビルド時に分離できます。最後に、必要に応じて各アプリターゲットで異なるアプリアイコンと名前を使用してください(たとえば、開発ビルドのアプリ名に「Dev」という接尾辞を追加します)。これは、ターゲットごとにInfo.plistまたはアセットカタログで設定できます。

  4. 依存関係を管理する(SPMとCocoaPods): ライブラリやフレームワークを追加する際は、**Swift Package Manager(SPM)**を主要なツールとして使用してください。SPMはXcodeに組み込まれているため、SwiftUIプロジェクトの依存関係をシームレスに管理できます。パッケージを追加するには、**File ▸ Add Packages...**に移動し、パッケージのGit URLを入力します。依存関係はアプリターゲットに割り当ててください(CocoaPodsが生成したターゲットには割り当てないでください)。これにより、パッケージが正しく統合されます。SPMはパッケージを自動的に取得および更新し、Xcode内のサンドボックスに保持します。チームメンバーとCIで同じバージョンを使用できるよう、Package.resolvedファイルをコミットしてください。SPMでは利用できないライブラリ(または、Objective-C/レガシーコードを多く含むライブラリ)が必要な場合は、CocoaPodsを統合できます。Podfileを初期化し(pod init)、Podを指定してから、pod installを実行して.xcworkspaceを生成します。その後はワークスペースから作業を続けてください。1つのプロジェクトでSPMとCocoaPodsを併用することもできます。SPMパッケージを追加するときは、追加ダイアログでPodsプロジェクトではなくメインプロジェクトを選択してください。必要に応じて、pod updateを実行し、Podの依存関係を最新の状態に保ってください。一般的には、Xcodeのネイティブサポートを利用でき、使いやすいため、純粋なSwiftの依存関係にはSPMを優先し、例外的な場合にのみCocoaPodsを使用してください。サードパーティ製パッケージについては、READMEに明確なドキュメントを記載してください。

  5. アーキテクチャパターン(MVVM または TCA)を適用する: 複雑さを管理できる堅牢なアーキテクチャを使って、SwiftUI コードを構成します。よく選ばれるのは MVVM(Model-View-ViewModel) です。SwiftUI のデータバインディングと自然に連携します。MVVM では、アプリのデータを表すデータモデルを定義し、UI には SwiftUI の View を使い、ビジネスロジックと状態を扱う ViewModel クラス(ObservableObject に準拠)を作成します。たとえば、GameViewModel で @Published var score を公開し、スコアを更新するメソッドを実装できます。対応する GameView では @StateObject または @ObservedObject を使って ViewModel を監視し、UI を更新します。この分離により、SwiftUI の View は宣言的で軽量なまま、ロジックは ViewModel に置かれるため、テストしやすくなります。より大規模なアプリや、さらに複雑な状態管理には、The Composable Architecture (TCA) の採用を検討してください。TCA は一方向のデータフロー(Redux に着想を得ています)に従うライブラリで、SPM 経由で追加できます。アプリを State、Actions、Reducers に分割します。Reducer は、現在の State と Action を受け取り、新しい State(および必要に応じて Effect と呼ばれる副作用)を生成する純粋関数です。Store は SwiftUI の View と状態およびビジネスロジックをつなぎます。View が Action(たとえばボタンのタップ)を送信すると、Store が受け取り、Reducer に渡します。Reducer が State を更新し、その状態が View に戻ります。TCA では、モジュール性の高い構造を推奨しています。小さな機能を組み合わせて大きな機能を構成でき、依存関係や副作用を制御された方法で管理するツールも提供します。TCA は習得に時間がかかりますが、テストのしやすさ(Reducer のロジックを簡単にテストできます)と、大規模なアプリでの拡張性に優れています。プロジェクトのニーズに応じて、MVVM(よりシンプルで、SwiftUI に組み込まれたリアクティブな状態管理機能を使います)か、TCA(より構造化されており、複雑なアプリに最適です)のいずれかを選んでください。どちらも、コード内の関心事を明確に分離するのに役立ちます。

  6. デバッグとプロファイリングの実践: 開発中は、Xcode の強力なデバッグツールを使って、問題を早期に発見して修正します。コードに ブレークポイント を設定し(行番号の横にあるガターをクリックします)、実行を一時停止して実行時の変数を調べます。一時停止中に LLDB コンソール の po コマンドを使うと、値を出力したり関数を呼び出したりして、状態を確認できます。これは、データの流れが正しいことを確かめたい ViewModel や TCA Reducer のロジックを調べる際に非常に役立ちます。SwiftUI の View では、View Hierarchy Debugger が特に便利です。Simulator でアプリを実行し、Debug ▸ View Debugging ▸ Capture View Hierarchy を選択します。実行を一時停止した後に UI のレイアウトを調べられるため、View が表示されない理由や、位置がずれている理由を特定できます。さらに、Instruments を活用してプロファイリングを行います。Xcode の Instruments アプリには、Time Profiler(CPU パフォーマンスを測定し、処理の遅い関数を見つけます)や Leaks(メモリリークやリテインサイクルを検出します)などのテンプレートが用意されています。たとえば、SwiftUI の View の動作が遅い場合は、操作しながら Time Profiler を実行して、負荷の高い計算を特定します。Xcode 15 以降の SwiftUI には、UI パフォーマンスを分析するための専用の「SwiftUI」アニメーションおよびレンダリングタイムラインインストゥルメントも含まれています。SwiftUI のパフォーマンスは Debug ビルドと Release ビルドで異なる場合があるため、定期的に Release モード でもテストとプロファイリングを行ってください。特に実行経路やデータの変更を追跡する際は、軽量なデバッグ手段として os_log や print 文を使います(本番環境では、出力量の多いログを必ず削除するか無効にしてください)。開発全体を通じて定期的にデバッグとプロファイリングを行うことで、アプリがスムーズに動作し、リリース前にバグを発見できます。

  7. ユニットテストと UI テストを作成します: コードの品質を維持するため、自動テストを設定します。プロジェクトの作成時に、Xcode でユニットテストターゲットと UI テストターゲットを生成できます(存在しない場合は、File ▸ New ▸ Target から手動で追加することもできます)。ユニットテスト(XCTest フレームワークを使用)では、ビジネスロジックの中核をテストします。MVVM の場合は、UI から独立して ViewModel のメソッドや状態の変化をテストします。TCA の場合は、TCA のテストユーティリティを使ってリデューサーにアクションを送信し、状態の変化やエフェクトの出力を検証できます。エッジケースやエラー条件(たとえば、ネットワーク呼び出しが失敗した場合に ViewModel がエラー状態を表示するなど)もテストすることを目指します。UI テストでは、XCTest をベースとする Xcode の UI Testing フレームワークを使ってアプリを起動し、ユーザー操作をシミュレートします。シミュレーターでアプリを操作して UI テストスクリプトを記録すると、タップやスワイプのコードが生成されます。または、より細かく制御するために手動で記述することもできます。オンボーディングや購入フローなど、確実に動作する必要がある重要なフローに UI テストを集中させます。アサーションを使って、期待する要素が表示されることや、特定の画面への遷移が成功することを検証します。テストをグループごとに整理し、内容が分かりやすいテストメソッド名を付けます。異なる構成でテストを実行するのも有効です(Xcode の Test Plans を使うと、複数のスキームや環境でテストスイートを実行できます)。テストを自動化すれば、リグレッションをすばやく検出し、新しい変更によって既存の機能が壊れていないことを確認できます。開発中は定期的にテストスイートを実行し、CI パイプラインにも必ずテストの実行を組み込んでください。

  8. Xcode Cloud による継続的インテグレーション: ビルドとテストを効率化するため、サポート対象の Git リポジトリ(GitHub、Bitbucket、GitLab など)でコードをホストしている場合は、Xcode Cloud を設定します。Xcode Cloud は、Apple のサーバー上でアプリを自動的にビルドできる、Apple の統合 CI サービスです。設定するには、Xcode でプロジェクトを開き、Xcode Cloud の設定(Report Navigator または Product ▸ Xcode Cloud)に移動して、新しいワークフローを有効にします。リポジトリのブランチ(例:main)を選択し、ビルド、解析、テスト、アーカイブなどのアクションを選びます。トリガーも指定できます。たとえば、プッシュのたびに実行する、またはプルリクエストの場合のみ実行する、といった設定が可能です。Xcode Cloud は Apple Developer アカウントと連携してプロビジョニングを処理します。自動署名を設定すれば、クラウドビルド用の証明書やプロファイルもシームレスに管理できます。ビルドやテストが必要なすべてのスキームをワークフローに追加します(たとえば、iOS アプリと macOS アプリの両方のスキームと、テストターゲットを含めます)。Xcode Cloud では、シンプルな Web インターフェース(または Xcode 内)でビルドのステータスを監視し、ログやテスト結果を確認できます。成功したビルドを TestFlight に自動配布するよう設定することもできます(手順 10 を参照)。Xcode Cloud の利点のひとつは、Xcode と深く統合されていることです。ローカルの Xcode と同じ環境を使い、複数のデバイスで並列テストを実行できます。Xcode Cloud の利用時間にも注意してください(Apple は無料枠を提供していますが、利用量が多い場合はサブスクリプションが必要になることがあります)。チームでのプロジェクトでは、Xcode Cloud によって全員の変更が継続的に検証されます。プロジェクトが適切に設定されていれば、Apple プラットフォームアプリ向けに、一度設定すれば後は手間のかからない優れた CI です。

  9. GitHub Actions による継続的インテグレーション: Xcode Cloud の代わりに、または Xcode Cloud に加えて、GitHub Actions を使用して CI/CD を設定できます。より柔軟にカスタマイズできます。リポジトリにワークフロー YAML(例:.github/workflows/ci.yml)を作成します。iOS/macOS アプリをビルドするには、macOS ランナー(例:runs-on: macos-latest)を使用します。一般的なジョブでは、依存関係をインストールし、アプリをビルドして、テストを実行し、アプリの成果物をアーカイブします。たとえば、コードをチェックアウトする(actions/checkout)、必要な Ruby または Node の環境をセットアップする(Fastlane や CocoaPods などのツールを使用する場合)、その後 Xcode のビルドコマンドを実行するステップを含めます。コマンドラインモードで xcodebuild を使用して、ビルドとテストを実行できます。

    • name: Build and Test (iOS) run: xcodebuild -workspace YourApp.xcworkspace -scheme "YourApp-iOS" -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 14' clean test

上記のサンプルコマンドは iOS スキームをビルドし、シミュレーターでテストを実行します。同様に、スキームとデスティネーションとして Mac を指定すれば、macOS スキームをビルドできます。CocoaPods を使用している場合は、ビルドの前に pod install を実行してください。必要に応じてビルド成果物を保存します(Xcode は .xcarchive アーカイブを生成し、iOS 用に .ipa をエクスポートできます)。GitHub Secrets を使用すると、配布用署名証明書(Base64 形式の .p12 ファイル)やプロビジョニングプロファイルに加え、App Store Connect API キーやアプリ固有のパスワードを保存できます。その後、証明書を Keychain にインストールし、署名用の環境変数を設定するステップを追加します。多くのチームは、コード署名とアップロードを簡素化するために Fastlane を GitHub Actions に組み込んでいます。たとえば、ビルド後に fastlane deliver またはカスタムレーンを呼び出して、TestFlight にアップロードします(Fastlane は App Store Connect の API キーを使用して認証できます)。TestFlight にバイナリをアップロードするためのコミュニティ製 GitHub Actions(apple-actions/app-store-connect など)もあります。すべての変更が検証されるよう、プルリクエストと main へのマージ時にワークフローが実行されるようにしてください。GitHub Actions では、追加のチェック(lint、SwiftLint など)を組み込んだり、デバイスや OS バージョンのマトリックスを使って並列化したりすることも自由に制御できます。CI 設定をリポジトリ内のコードとして保存したい場合は、Xcode Cloud を補完する、またはその代わりとなる柔軟な選択肢です。

  1. コード署名とプロビジョニングの管理: デバイスで実行したり、TestFlight/App Store で配布したりするには、コード署名が必要です。 開発中は、各ターゲットで Xcode の自動署名を有効にできます。これにより、プロジェクトが Apple Developer チームに関連付けられ、Debug ビルドと Release ビルドに必要な証明書とプロビジョニングプロファイルが作成されます。 各アプリターゲットの Signing & Capabilities でチームが選択されており、一意のバンドル識別子が設定されていることを確認してください。 配布(TestFlight/App Store)には、各アプリターゲットに iOS Distribution 証明書と App Store プロビジョニングプロファイルが必要です。 自動署名が有効で、プロジェクトのアーカイブビルドの対象が「Any iOS Device」(iOS の場合)または「Any Mac」(Mac アプリの場合)に設定されていれば、Xcode でこれらを作成できます。 Xcode の外部(GitHub Actions など)で CI を使用する場合は、署名に必要な情報を用意する必要があります。Distribution 証明書を .p12 ファイルとして書き出し、プロビジョニングプロファイル(.mobileprovision)を Apple Developer ポータルからダウンロードしてください。 これらを安全に保管し(CI の環境シークレットまたはキーチェーンを使用)、ビルド中にスクリプトまたは Fastlane でインポートします。 署名 ID を安全かつ自動的に管理するには、Fastlane Match または codemagic/xcodesign の使用をおすすめします。 また、API 経由でビルドをアップロードする予定がある場合(CI ツールや Fastlane で使用)、App Store Connect API キー(App Store Connect > Users and Access > Keys)を生成してください。 キー ID、発行者 ID、秘密鍵ファイルは安全に保管してください。これらを使用すると、Apple ID の認証情報を使わずに CI から App Store Connect に認証できます。 まとめると、早い段階で署名を設定し、アプリをローカルでアーカイブして書き出せることをテストしてください。 これにより、CI で同じ処理を行う際もスムーズに進められます。 ローカル環境と CI 環境でバンドル ID、プロビジョニングプロファイル、エンタイトルメントを一貫させることが重要です。

  2. TestFlight へのデプロイ: 署名済みのアーカイブビルド(.xcarchive)を用意できたら、次はテスターに配布します。 TestFlight は、App Store Connect に統合された Apple のベータ配布プラットフォームです。 Xcode をローカルで使用する場合は、Product ▸ Archive を選択し、次に Organizer で Distribute App → App Store Connect → Upload を選びます。 Xcode が TestFlight へのアップロードを処理します(アップロードのたびにアプリのバージョンまたはビルド番号を増やす必要があります)。 CI によるアップロードには、Xcode のコマンドラインツールまたは Fastlane を使用します。 Xcode コマンドラインを使用する場合は、アーカイブ後、エクスポートオプションの plist を指定して xcodebuild -exportArchive で IPA を書き出し、Apple の altool または新しい Transporter CLI でアップロードします。 Fastlane を使うと、fastlane pilot(TestFlight 用)または fastlane upload_to_testflight で簡単に実行できます。 Xcode Cloud では、ワークフローで「Upload to TestFlight」アクションを有効にすると、クラウドビルドの成功後にアーカイブが App Store Connect に自動的に送信されます。 アップロード後、App Store Connect がビルドを処理します(数分かかることがあります)。 その後、App Store Connect にログインしてテスターを管理し、社内または社外のテスターグループにビルドを送信できます。 テスター向けに、ビルドに含まれる変更点(TestFlight のリリースノート)を記載するのが望ましいです。 CI/CD では、迅速に反復できるよう、すべてのコミットを社内の TestFlight グループにデプロイし、特定のビルドを社外のテスターへの配布や App Store への提出に進める方法もあります。 最後に、Apple が指摘した 重大な問題(クラッシュやコンプライアンス情報の不足など)がないか、TestFlight のビルドを常に確認してください。対応が必要な場合は、App Store Connect から通知が届きます。 テストでビルドの確認が完了したら、そのビルドを使って App Store の審査にアプリを提出できます。

例

  • GitHub Actions CI ワークフロー(抜粋): 以下は、依存関係をインストールし、ビルドとテストを行い、TestFlight ビルドをアップロードする iOS アプリ用 GitHub Actions ワークフローファイルの簡略化した例です。CI で Xcode のコマンドラインツールと Fastlane を使用する方法を示しています。

    name: CI-iOS-TestFlight on: push: branches: [ main ] jobs: build-test-deploy: runs-on: macos-latest steps: - name: Checkout code uses: actions/checkout@v3

        - name: Install CocoaPods dependencies
          run: pod install
          continue-on-error: true  # Only if using CocoaPods
    
        - name: Build and Run Unit Tests (iOS)
          run: xcodebuild clean test -workspace YourApp.xcworkspace -scheme "YourApp-iOS" -sdk iphonesimulator -configuration Debug -destination 'platform=iOS Simulator,name=iPhone 14,OS=latest'
    
        - name: Archive App for Distribution
          run: xcodebuild clean archive -workspace YourApp.xcworkspace -scheme "YourApp-iOS" -configuration Release -destination 'generic/platform=iOS' -archivePath ${{ github.workspace }}/YourApp.xcarchive
    
        - name: Export .ipa from Archive
          run: xcodebuild -exportArchive -archivePath ${{ github.workspace }}/YourApp.xcarchive -exportOptionsPlist ExportOptions.plist -exportPath ${{ github.workspace }}/build
    
        - name: Install Fastlane
          run: gem install fastlane
    
        - name: Upload to TestFlight
          env:
            APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.ASC_KEY_ID }}
            APP_STORE_CONNECT_API_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }}
            APP_STORE_CONNECT_API_KEY: ${{ secrets.ASC_KEY }}
          run: fastlane pilot upload -u ${{ secrets.APP_STORE_CONNECT_EMAIL }} -ipa ${{ github.workspace }}/build/YourApp.ipa --api_key_path ./ApiKeyFile.p8
    

この YAML では、ワークフローは main ブランチへのプッシュをトリガーとして実行されます。リポジトリをチェックアウトし、該当する場合は Pod をインストールした後、iOS シミュレーター上でアプリをビルドしてテストします。次に、アプリをアーカイブし、ExportOptions.plist(配布方法として「app-store」とプロビジョニングプロファイルを指定するファイル)を使って IPA をエクスポートします。最後に、GitHub Secrets に保存された App Store Connect API キーの認証情報を使用し、Fastlane Pilot で IPA を TestFlight にアップロードします。この例には、Mac のビルドやコードのリントなどを行う追加のジョブやステップを加えることができ、CI によってビルドとデプロイのプロセス全体を自動化できることを示しています。

  • MVVM ViewModel の例(SwiftUI): 以下は、MVVM パターンに従った SwiftUI のビューと ViewModel の簡単な例です。ビューモデルが UI の状態を管理し、ロジックを処理する方法を示しています。これにより、ビューとは独立してユニットテストを実施できます。

    import SwiftUI import Combine

    // Model struct Game { var score: Int }

    // ViewModel class GameViewModel: ObservableObject { @Published var game: Game private var cancellables = Set()

      init(game: Game = Game(score: 0)) {
          self.game = game
      }
    
      func increaseScore() {
          game.score += 1
      }
    
      func resetScore() {
          game.score = 0
      }
    

    }

    // View struct GameView: View { @StateObject private var viewModel = GameViewModel()

      var body: some View {
          VStack {
              Text("Score: \(viewModel.game.score)")
                  .font(.largeTitle)
              HStack {
                  Button("Increase") {
                      viewModel.increaseScore()
                  }
                  Button("Reset") {
                      viewModel.resetScore()
                  }
              }
          }
          .padding()
      }
    

    } この例では、GameViewModel は状態(Game モデル)を管理する ObservableObject です。SwiftUI の GameView は @StateObject を使用して ViewModel をインスタンス化し、監視します。「Increase」ボタンをタップすると、ViewModel のメソッドが呼び出されてスコアが更新されます。@Published のおかげで、ビューには変更が自動的に反映されます。このアーキテクチャでは UI とロジックが明確に分離されています。SwiftUI をまったく使用せずに、GameViewModel.increaseScore() と resetScore() の単体テストを書いて、正しく動作することを確認できます。ビューは現在の状態に基づいて表示するだけです。このパターンは、画面やコンポーネントごとに対応する ViewModel(および必要に応じてサービス/モデルのレイヤー)を設ける形で拡張でき、アプリの保守性とテスト容易性が向上します。

参考資料

  • Apple Developer Documentation -- マルチプラットフォームアプリ: iOS と macOS 用の単一の Xcode ターゲットを設定し、プラットフォーム間でコードを共有するためのガイドです。
  • Apple Developer Documentation -- Xcode Cloud: アプリの継続的インテグレーションとデリバリー(TestFlight でのビルド、テスト、デプロイ)を行うための Xcode Cloud ワークフローの設定方法を解説しています。
  • Apple Developer Documentation -- TestFlight での配布: Xcode または CI ツールを使ってアプリをアーカイブし、ビルドを TestFlight にアップロードする手順を説明しています。
  • Pointfree(Composable Architecture): The Composable Architecture(TCA)ライブラリの公式 GitHub リポジトリとドキュメントです。SwiftUI プロジェクトへの統合ガイドも含まれています。
  • XCTest フレームワークのリファレンス: XCTAssert 関数の使用や UI テストの記録など、XCTest を使った単体テストと UI テストの作成に関する Apple のリファレンスです。
  • Fastlane のドキュメント: Fastlane ツール(match、pilot など)を使ってコード署名や TestFlight へのデプロイを自動化するためのガイドです。Xcode Cloud 以外で CI/CD パイプラインを設定する際に役立ちます。

コメント