Contents
Swift と SwiftUI のマルチプラットフォーム対応概要
Swift と SwiftUI は、Apple が公式に提供する「単一コードベースで iOS・macOS・watchOS・tvOS へ展開できる」フレームワークです。近年はオープンソース化が進み、コミュニティ主導のツールを使って Android 向けバイナリを生成する試みも見られます。本節では、公式サポート範囲と 2026 年時点で実務的に利用できる手段を整理し、全体像を把握できるようにします。
Apple が提供する公式ガイドの要点
Apple の開発者向けサイト(Swift – Get Started)では、以下が強調されています。
- 共通言語としての Swift:同一言語で iOS・macOS・watchOS・tvOS にコードを流用できることが公式に保証されています。
- SwiftUI の宣言的 UI:
Viewプロトコルと@State系プロパティラッパーにより、プラットフォーム固有の差分を最小限に抑えた UI 開発が可能です。 - Catalyst の位置付け:iPad アプリを macOS に移植する公式手段としてサポートされています。一方、Android 向けの「Swift for Android」については Apple が正式に提供しているわけではなく、オープンソースコミュニティが実験的に取り組んでいる領域です【※1】。
ポイント:Swift と SwiftUI を使うことで多くのロジックを共有できますが、実際に共有できるコード量はプロジェクトの構造や使用 API に依存し、一般的には 50 %〜70 % 程度と評価されています【※2】。
Xcode 15 以降でのマルチターゲットプロジェクト作成手順
Xcode 15 からは「Supports Multiple Platforms」オプションが標準化され、1つのワークスペースで iOS と macOS(さらには watchOS・tvOS)を同時に管理できます。このセクションでは、新規プロジェクト作成から共有コード配置までの実務フローを具体的に示します。
新規プロジェクトの設定
まず Xcode を起動し、File > New > Project を選択します。テンプレートは App (SwiftUI) を選び、以下の項目を入力してください。
- Product Name:例
MultiPlatformDemo - Interface:SwiftUI
- Life Cycle:SwiftUI App
- Language:Swift
- Supports Multiple Platforms にチェック(iOS と macOS が自動で追加されます)
ポイント:この設定だけで iOS 用と macOS 用の 2 つのターゲットが生成され、
@mainエントリは共通化されたままビルドできます。
プラットフォーム別ターゲットと共有コードディレクトリの構築
次にプロジェクト構造を整理します。推奨するフォルダ構成は以下の通りです(※ディレクトリ名は任意で変更可能)。
|
1 2 3 4 5 6 7 8 9 10 |
MultiPlatformDemo/ ├─ Packages/ │ └─ Shared/ # すべてのプラットフォームで共通利用 │ ├─ Models/ │ └─ Views/ ├─ iOSOnly/ # iOS 固有コード(例:WidgetKit、ARKit) │ └─ Info.plist └─ macOSOnly/ # macOS 固有コード(例:AppKit ラッパー) └─ Info.plist |
- Packages/Shared に
Package.swiftを作成し、.target(name: "Shared", path: "Sources")のように設定すれば、Swift Package Manager 経由で両ターゲットから参照可能です。 - 各プラットフォーム固有のリソース(画像や
Info.plist等)はiOSOnly/macOSOnlyに配置し、Xcode の「Target Membership」チェックボックスで対象を限定します。
ポイント:共有ロジックを SPM パッケージ化すると、他プロジェクトでも再利用が容易になるだけでなく、CI でのビルドキャッシュも有効活用できます。
共通コードとプラットフォーム固有コードの分離方法
Swift の条件コンパイルディレクティブ #if os(...) を活用すると、同一ファイル内で OS 毎の実装差分を明示的に管理できます。ここではベストプラクティスと具体例を紹介します。
#if os(iOS) / #if os(macOS) での条件コンパイル
以下は UI コンポーネントの差分を扱う典型的なコードです。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import SwiftUI struct PlatformButton: View { var body: some View { #if os(iOS) Button("iOS ボタン") { // iOS 専用ロジック } .buttonStyle(.borderedProminent) #elseif os(macOS) Button("macOS ボタン") { // macOS 専用ロジック } .buttonStyle(.plain) // macOS ではフラットがデフォルト #endif } } |
#ifブロックはコンパイル時に除外されるため、実行ファイルサイズの無駄な増大を防げます。- 条件分岐が多数になる場合は ファイルレベルで分割 し、
iOSOnly/Views/...swiftとmacOSOnly/Views/...swiftに配置すると可読性が向上します。
| ディレクトリ | 主な内容 |
|---|---|
| Packages/Shared | ビジネスロジック、データモデル、プラットフォーム非依存の View |
| iOSOnly | #if os(iOS) が不要な純粋 iOS 実装(例:WidgetKit、ARKit) |
| macOSOnly | macOS 固有 API(例:AppKit ラッパー、メニューバー拡張) |
ポイント:共通ロジックは必ず
Sharedに置き、プラットフォーム固有の UI やネイティブ API は条件コンパイルまたは別ファイルで分離することで、リファクタリング時の影響範囲を瞬時に把握できます。
Swift を Android に展開する – コミュニティツールチェーンの概要
Apple が公式に Android 向けサポートを提供しているわけではありませんが、Swift のオープンソース化に伴い Scade(正式名称:Scade – Swift‑to‑Android toolchain)というコミュニティベースのツールチェーンが注目されています。以下は 2026 年時点で確認できた情報をもとに、インストールから Xcode プロジェクトへの組み込み手順をまとめたものです【※3】。
Scade の公式情報とインストール方法
Scade は GitHub 上のリポジトリ(github.com/scade-io/scade)で公開されており、Homebrew からインストール可能です。Mac と Linux の両環境で動作します。
|
1 2 3 4 5 6 7 8 9 |
# Homebrew が未インストールの場合は先に導入 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" # Scade のインストール brew install scade # バージョン確認(2026‑04 時点の最新は 2.4.1) scade --version |
- 必須環境:Java Development Kit (JDK) と Android SDK。
bash
brew install openjdk@17 # JDK 17 をインストール
export JAVA_HOME=$(brew --prefix openjdk@17)/libexec/openjdk.jdk/Contents/Home
# Android SDK は Android Studio の「SDK Manager」から Command line tools と Platform‑Tools を導入
export ANDROID_SDK_ROOT=$HOME/Library/Android/sdk
注意:Scade は実験的なツールであり、すべての Swift 標準ライブラリが Android 上で動作するわけではありません。商用リリース前には必ず対象デバイスで包括的にテストしてください。
Xcode と Scade の連携例(Qiita 実装例へのリンク)
2026 年版 Qiita 記事「Swift でマルチプラットフォーム開発をしよう! #iOS」では、Scade を利用したビルドフローが具体的に示されています。主な手順は次の通りです。
- プロジェクト構成:
SwiftApp/配下にandroid/ディレクトリを作り、Scade が生成した.aarパッケージ(例libMyApp.aar)を配置。 - Xcode 側設定:
Build Phases → Run Scriptに以下のスクリプトを追加し、ビルド時に Scade を呼び出す。
bash
#!/bin/bash
set -e
SC_PATH=$(which scade)
$SC_PATH build --target android --output ./android/libMyApp.aar
- Android Studio 側:
settings.gradleにローカル.aarをインポートし、Kotlin/Java から Swift のエクスポート関数を呼び出すブリッジコードを作成。
ポイント:Scade は LLVM バックエンドを利用するため、Apple Silicon(M1/M2)環境でも高速ビルドが期待できます。ただし、Android API 33 以上での実機テストは必須です。
CI/CD とデバッグ・テスト戦略
マルチプラットフォームアプリは自動化されたパイプラインで品質を担保することが重要です。ここでは GitHub Actions を用いた macOS/Linux ビルドと、実機・エミュレータでの検証フローを示します。
GitHub Actions で macOS と Linux ビルドを自動化
以下は公式サンプルに基づくワークフローファイル(.github/workflows/multi.yml)です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
name: Multi‑Platform Build on: push: branches: [ main ] pull_request: jobs: build-ios-macos: runs-on: macos-14 # Apple Silicon ランナー steps: - uses: actions/checkout@v4 - name: Set up Xcode run: sudo xcode-select --switch /Applications/Xcode_15.2.app - name: Resolve Swift Packages run: swift package resolve - name: Build Shared Package (Release) run: swift build -c release - name: Archive iOS & macOS run: | xcodebuild -scheme MultiPlatformDemo \ -destination 'generic/platform=iOS' \ -archivePath ${{ runner.temp }}/iOS.xcarchive archive xcodebuild -scheme MultiPlatformDemo \ -destination 'generic/platform=macOS' \ -archivePath ${{ runner.temp }}/macOS.xcarchive archive build-android: runs-on: self-hosted-linux # Linux ランナー(Docker 推奨) steps: - uses: actions/checkout@v4 - name: Install dependencies (brew, scade, jdk) run: | curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh | bash brew install scade openjdk@17 export JAVA_HOME=$(brew --prefix openjdk@17)/libexec/openjdk.jdk/Contents/Home - name: Build Android AAR with Scade run: scade build --target android --output ./android/libMyApp.aar |
- キャッシュ:
actions/cache@v3を利用すれば、Swift パッケージや Gradle の依存関係を永続化できます。 - コード署名:iOS/macOS ビルドでは
PROVISIONING_PROFILE_SPECIFIERとCODE_SIGN_IDENTITYを GitHub Secrets に登録し、環境変数で渡す必要があります。
実機・エミュレータでのデバッグとベータ配布
| 作業 | ツール | 主なポイント |
|---|---|---|
| iOS デバッグ | Xcode Simulator | Cmd+Shift+K でクリーン後、対象デバイスを選択し実行。SwiftUI のプレビューは Option+Cmd+P でライブ更新可能。 |
| Android デバッグ | Android Emulator (AVD) | API 33+ の仮想デバイスを作成し、adb install ./app-debug.apk でデプロイ。Scade が生成した .aar は Android Studio にインポートして使用。 |
| ベータ配布(iOS) | TestFlight + fastlane | GitHub Actions に fastlane pilot upload ステップを追加し、.ipa を自動アップロード。 |
| ベータ配布(Android) | Google Play Console (Internal testing) + fastlane | gradle bundleRelease で .aab を作成し、fastlane supply で内部テストトラックへ自動投入。 |
ポイント:CI 上でシミュレータ/エミュレータを起動できないケースでは、ユニットテストと UI テストだけを実行し、実機テストはプルリクエストマージ後に手動で行うフローが安全です。
次のステップ
本稿で紹介した Swift と SwiftUI の基本的なマルチプラットフォーム戦略、Xcode 15 のマルチターゲット設定、条件コンパイルによるコード分離、コミュニティツール Scade を用いた Android 展開、そして GitHub Actions による CI/CD 構築 の順番で実装すれば、iOS・macOS・Android 向けの単一リポジトリが完成します。以下の手順で早速体験してください。
- 公式テンプレートリポジトリ(例
github.com/example/MultiPlatformDemo)をクローン - Xcode でプロジェクトを開き、Supports Multiple Platforms が有効か確認
Packages/Sharedに簡単なビジネスロジックを書き、iOS と macOS の両方で動作することを確かめる- Scade をインストールし、
android/libMyApp.aarを生成して Android Studio へ取り込む - GitHub Actions に上記 workflow ファイルを配置し、プッシュごとにビルドが走ることを確認
このサイクルを回すことで、コードの再利用性とデリバリー速度が大幅に向上します。疑問点や環境依存の問題は、公式フォーラム(Apple Developer Forums, Scade GitHub Issues)で質問すると迅速な回答が得られます。
参考文献・リンク
- 【※1】「Swift for Android」については Apple の公式ドキュメントに記載なし。コミュニティ情報は https://github.com/scade-io/scade を参照。
- 【※2】実際のコード共有率はプロジェクト規模・使用 API に依存する旨、2025 年の開発者調査(Swift.org Survey 2025)を基にした概算。
- 【※3】Scade の公式リポジトリと README(2026‑04 時点)。