Swift SDK for Androidは、SwiftのコードをAndroid向けのネイティブバイナリにクロスコンパイルするためのSDKです。2025年10月にプレビュー版が公開され、2026年3月24日のSwift 6.3で正式版になりました。2026年11月時点の最新は、10月29日に出たSwift 6.4.2用のSDKです。この記事では、Swift 6.4.2とAndroid NDK r30で実際にビルドした結果をもとに、導入手順、ビルド成果物の場所、APIレベルの指定、公式サンプルの動かし方、SwiftUIの画面までAndroidに持っていくSkipとの使い分けを説明します。
まとめ:Swift SDK for Androidの現在地と導入判断
- 提供元はAppleの製品部門ではなく、Swiftのオープンソースプロジェクト(swift.org)のAndroid Workgroupです。料金はかかりません。
- 2026年11月時点の現行版はSwift 6.4.2用で、必要なNDKはLTS版のr30です。ホスト側のツールチェーンはSDKと完全に同じ版にそろえます。Xcode付属のSwiftでは代用できません。
- 公式ガイドの
.build/debugは、最後にビルドしたアーキテクチャの成果物を指すシンボリックリンクです。x86_64とaarch64を続けてビルドすると中身が入れ替わるので、端末に送る前にfileで確かめます。 - SDK自体は共通UIフレームワークを提供しません。画面はKotlinとJetpack Composeで書き、Swiftのロジックはswift-java経由で呼ぶのが公式サンプルの標準構成です。
- SwiftUIの画面までAndroidで動かすならSkipを使います。2026年1月のSkip 1.7で無料・オープンソースになり、ネイティブ方式のSkip Fuseは内部でこのSDKを使います。
Swift SDK for Androidの提供元と正式版までの経緯
「AppleがAndroid向けSDKを出した」と紹介されることがありますが、正確ではありません。開発しているのはswift.orgのAndroid Workgroupで、AndroidをSwiftの公式サポート対象プラットフォームとして追加し、維持することを目的にしています。メールクライアントのSpark、ピアノ学習アプリのflowkey、ヘルスケアアプリのMediQuoなどは、正式版の前から独自のJava連携を組んでSwiftをAndroidで本番運用してきました(swift.orgブログ「Exploring the Swift SDK for Android」)。正式版で変わったのは、パッチを当てたフォーク版ではなく公式配布のツールチェーンでビルドできるようになった点です。
| 日付 | 出来事 |
|---|---|
| 2025年6月25日 | Swift ForumsでAndroid Workgroup設立を告知 |
| 2025年10月24日 | ナイトリープレビュー公開 |
| 2026年3月24日 | Swift 6.3で初の正式版 |
| 2026年9月14日 | Swift 6.4.0(NDK r30対応) |
| 2026年10月12日 | Swift 6.4.1(Windows版インストーラーのSDK配置を修正) |
| 2026年10月29日 | Swift 6.4.2 |
リリース日はswift.orgの配布一覧(releases.json)の値です。6.4.1の告知には「Repaired the Android SDK layout in the installer」とあり、Windowsで開発している場合は6.4.0を避ける理由になります(Announcing Swift 6.4.1)。
Swift SDK for AndroidでSwiftがAndroid上で動く仕組み
SwiftはAndroid上でもJVMのバイトコードにはならず、ARMやx86_64のネイティブ機械語にコンパイルされます。アプリには標準ライブラリ、Dispatch、FoundationといったSwiftのランタイムが同梱されます。
AndroidのAPIの大半はJavaとKotlinでしか公開されていません。SwiftからAndroidの画面部品や通知を直接呼ぶ手段はなく、Android Runtime(ART)とはJNI(Java Native Interface)を介してやり取りします。Workgroupは単一のGUIソリューションを提供しない方針で、主な用途はビジネスロジック、アルゴリズム、データモデルをiOSとAndroidで共有することです。
| Swiftのトリプル | AndroidのABI名 | 主な用途 |
|---|---|---|
| aarch64-unknown-linux-android | arm64-v8a | 現行の実機ほぼすべて |
| x86_64-unknown-linux-android | x86_64 | PC上のエミュレータ |
| armv7-unknown-linux-android | armeabi-v7a | 32ビットの旧端末 |
Swift 6.4.2での環境構築とクロスコンパイル手順
ここからのコマンド出力は、Intel Mac(macOS 26・x86_64)で2026年11月8日に実行した結果です。以下はmacOS用の手順です。Linuxではツールチェーンの導入方法やSDKの保存先も異なるため、ホストOSに対応する公式手順を確認してください。
Swift・Android SDK・NDKの版の組み合わせ
| 部品 | 2026年11月時点の版 | 役割 |
|---|---|---|
| Swiftツールチェーン | 6.4.2(オープンソース版) | ホストで動くコンパイラ |
| Swift SDK for Android | swift-6.4.2-RELEASE_android | Android向けライブラリと設定 |
| Android NDK | r30(30.0.16248370・LTS) | ヘッダ・libc・リンカ |
ツールチェーンとSDKの版がずれるとビルドできません。Command Line Tools付属のSwift 6.3.3で6.4系のSDKを指定すると、package 'hello' is using Swift tools version 6.4.0 but the installed version is 6.3.3 で止まり、Package.swiftのツールバージョンを下げても could not find module 'Swift' for target 'aarch64-unknown-linux-android' になります(2026年10月に6.4.0のSDKで確認)。Macでは swift --version がXcode側を指していないかを最初に確かめてください。NDK r30がLTS版であることはAndroid NDKのダウンロードページに載っています。
ツールチェーン・SDK・NDKのインストール
ツールチェーンはswiftlyで入れるのが公式の推奨です。swiftlyの導入方法とSwiftの版の対応はSwiftの最新バージョンとXcode対応表にまとめています。SDKはURLとSHA-256チェックサムを指定して入れます。下のチェックサムはswift.orgのGetting Started with the Swift SDK for Androidの値で、手元でダウンロードしたファイルの shasum -a 256 とも一致しました。
swiftly install 6.4.2
swiftly use 6.4.2
swift --version
# Apple Swift version 6.4.2 (swift-6.4.2-RELEASE)
# Target: x86_64-apple-macosx26.0
swift sdk install https://download.swift.org/swift-6.4.2-release/android-sdk/swift-6.4.2-RELEASE/swift-6.4.2-RELEASE_android.artifactbundle.tar.gz --checksum 4d6ad63ea74becd58e123ff58b1b48c3be5ec0db0dff0ea5abe37ac007dd3233
swift sdk list
# swift-6.4.2-RELEASE_android
curl -fSL -o ndk.zip https://dl.google.com/android/repository/android-ndk-r30-$(uname -s).zip
unzip -qo ndk.zip
export ANDROID_NDK_HOME=$PWD/android-ndk-r30
ダウンロードサイズはmacOS版ツールチェーンが約1.6GB(1,591,283,484バイト)、SDKが約340MBでした。ANDROID_NDK_HOME を設定し忘れると、ビルド時に No Android NDK is installed at any of the standard locations で止まります。
aarch64・x86_64向けビルドと.build/debugの中身
mkdir hello && cd hello
swift package init --type executable
swift build --swift-sdk swift-6.4.2-RELEASE_android --triple aarch64-unknown-linux-android28 --static-swift-stdlib
ls -l .build
# debug -> out/Products/Debug-android-aarch64
file .build/debug/hello
# ELF 64-bit LSB pie executable, ARM aarch64, ... interpreter /system/bin/linker64, with debug_info, not stripped
swift build --swift-sdk swift-6.4.2-RELEASE_android --triple x86_64-unknown-linux-android23 --static-swift-stdlib
file .build/debug/hello
# ELF 64-bit LSB pie executable, x86-64, ...
ls .build/out/Products
# Debug-android-aarch64 Debug-android-x86_64
Swift 6.4ではSwiftPMの既定のビルドシステムがSwift Buildになり、成果物の実体は .build/out/Products/<構成>-android-<アーキテクチャ>/ に出ます。.build/debug はそこへのシンボリックリンクで、最後に実行したビルドのアーキテクチャに張り替わります。上の例では、aarch64の後にx86_64をビルドした時点で .build/debug/hello がx86_64版になりました。公式ガイドはx86_64、aarch64の順にビルドしてから adb push .build/debug/hello する流れなので、順番を入れ替えると実機に別アーキテクチャのバイナリを送ることになります。CIのスクリプトでは、ビルド時と同じSDK・トリプル・構成を指定した swift build --show-bin-path の結果か out/Products 側のパスを使ってください。6.4.0でも同じリンクが作られることを確認しています。
-c release を付けると .build/release が Release-android-x86_64 などを指します。標準ライブラリを静的リンクしたx86_64のHello Worldは、未stripの状態で8,209,272バイトでした(6.4.0では8,540,848バイト)。
setup-android-sdk.shの実行が必要なビルド方式
Swift 6.3までは、SDKのインストール後に setup-android-sdk.sh を実行してNDKのsysrootをSDKにリンクする必要がありました。Swift 6.4のリリース記事は、Swift BuildがAndroidに対応したためこのスクリプトは不要になったと説明しています。
ただし不要なのは既定のSwift Buildを使う場合だけです。6.4.2で旧来のビルドシステムを --build-system native で指定すると、warning: no such SDK: …/swift-android/ndk-sysroot の後に link command failed with exit code 1 で失敗しました。SDKバンドル内の swift-android/scripts/setup-android-sdk.sh を実行すると success: ndk-sysroot linked to Android NDK と表示され、同じコマンドが通ります。この指定には '--build-system native' has been deprecated and will be removed in a future release という警告も出ます。後述する公式サンプルのGradle設定はまだ --build-system native を渡しているため、サンプルを動かす前にこのスクリプトを実行してください。
bash ~/Library/org.swift.swiftpm/swift-sdks/swift-6.4.2-RELEASE_android.artifactbundle/swift-android/scripts/setup-android-sdk.sh
Android実機・エミュレータでのSwift実行ファイルの起動
USBデバッグを有効にした実機かエミュレータがあれば、実行ファイルとNDKの libc++_shared.so を /data/local/tmp へ送って起動できます。これはSDKの動作確認用の手順です。アプリとして配布するときは、Swiftを共有ライブラリ(.so)としてビルドし、ABIごとにAPKやAARへ同梱します。
swift build --swift-sdk swift-6.4.2-RELEASE_android --triple aarch64-unknown-linux-android28 --static-swift-stdlib
adb push .build/debug/hello /data/local/tmp
adb push $ANDROID_NDK_HOME/toolchains/llvm/prebuilt/*/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so /data/local/tmp/
adb shell /data/local/tmp/hello
# Hello, world!
Android APIレベルの指定と@available(Android)による分岐
トリプル末尾の数字(android28 など)が最小APIレベルです。6.4.2のSDKバンドルにはAPI 23から37までのトリプル定義が入っています(6.4.0は36まで)。公式ガイドの例はAPI 23ですが、swift.orgのPlatform Support表はAndroidの最小デプロイ対象を「9 (API 28)」としています。ビルドが通ることと公式にサポートされることは別なので、製品として出すアプリのminSdkは28以上にしておくのが安全です。公式サンプルのhello-swift-javaも minSdkVersion 28 です。
それより新しいAPIは、Appleプラットフォームと同じ @available と #available で分岐できます。
#if canImport(Android)
import Android
#endif
@available(Android 33, *)
func api33Only() -> String { "API 33+ path" }
#if os(Android)
if #available(Android 33, *) {
print(api33Only())
} else {
print("fallback path")
}
#endif
このコードは6.4.2で android28 と android33 のどちらでもビルドできました。#available を外して android28 向けにビルドすると、'api33Only()' is only available in Android 33 or newer のコンパイルエラーになります。minSdkより新しいAPIを呼んだことに、実行時ではなくコンパイル時に気づけます。
公式サンプル7種の選び方とKotlinからSwiftを呼ぶ手順
公式サンプル集のswiftlang/swift-android-examplesには7つのアプリ例があります。JNIを手で書く例と自動生成する例が混在しているので、目的から選びます。
| サンプル | やっていること | 向いている目的 |
|---|---|---|
| hello-swift-java | swift-javaでJavaラッパーを自動生成 | 新規にロジックを共有 |
| swift-java-weather-app | async関数とプロトコルの自動ブリッジ | Java側からSwiftを呼び返す |
| hello-swift-raw-jni | JNI関数を手書き | JNIの仕組みの理解 |
| hello-swift-raw-jni-callback | SwiftのタイマーからUI更新 | Swiftから呼び返す |
| hello-swift-raw-jni-library | Androidライブラリとして配布 | 既存アプリへの組み込み |
| hello-cpp-swift | C++ライブラリをSwift経由で公開 | C++資産がある場合 |
| native-activity | Swiftだけで画面を描画 | ゲームや描画処理 |
hello-swift-javaをAndroid Studioで動かす手順
hello-swift-javaは、swift-cryptoでSHA-256を計算するSwiftライブラリ(hashing-lib)と、それを呼ぶJetpack Composeのアプリ(hashing-app)で構成されています。サンプルのREADMEは、swift-javaの成果物をローカルのMavenリポジトリへ公開する工程に限ってJDK 25を要求しています。それ以外の開発ではJDK 25でなくても構いません。
git clone https://github.com/swiftlang/swift-android-examples.git
cd swift-android-examples/hello-swift-java/hashing-lib
swift package resolve
./.build/checkouts/swift-java/gradlew --project-dir .build/checkouts/swift-java :SwiftKitCore:publishToMavenLocal
cd ../..
export SWIFT_VERSION=6.4.2
./gradlew :hello-swift-java-hashing-lib:assembleRelease
最後のコマンドで、arm64-v8a・armeabi-v7a・x86_64の3つのABI向けにSwiftがビルドされ、AARにまとめられます。Android Studioで動かす場合も、hashing-libのbuild.gradleがSwift 6.4.2を選ぶように設定し、リポジトリのルートを開いてhashing-appを実行します。シェルの SWIFT_VERSION が引き継がれない環境では、同ファイルの既定値を6.3から6.4.2へ変更してください。
注意点はSwiftの版です。hashing-libの build.gradle は環境変数 SWIFT_VERSION が無いと 6.3 を使い、SDK名もそこから組み立てます。6.4.2だけを入れた環境で未設定のまま実行すると、ツールチェーンとSDKの版がそろいません。Gradleのタスクは swiftly run swift build +${swiftVersion} --swift-sdk … --build-system native を呼ぶので、前述の setup-android-sdk.sh も先に実行しておきます。
swift-javaのjniモードとSwift側のコード
swift-javaのjextractは、Swiftのソースを読んでJava側のラッパーとJNIのつなぎ込みコードを自動生成します。既定の ffm モードはJDK 22で正式化されたForeign Function & Memory APIを使うためAndroidでは使えず、Android向けには jni モードを選びます。Swift側の実装は次の1関数だけです。
import Crypto
#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
public func hash(_ input: String) -> String {
SHA256.hash(data: Data(input.utf8)).description
}
同じディレクトリの swift-java.config に、生成するJavaのパッケージ名とモードを書きます。
{
"javaPackage": "com.example.swifthashing",
"mode": "jni"
}
Package.swiftでは、ライブラリを type: .dynamic で定義し、JExtractSwiftPlugin をプラグインに指定します。Kotlin側は生成されたクラスをimportし、SwiftHashing.hash(input.value) と通常のメソッドとして呼びます。JNIの関数名規約を手で書く必要はありません。
swift-javaの最新リリースは2026年10月14日の0.7.0です。0.7.0のリリースノートには「jextract: fail on missing or empty javaPackage」があり、javaPackage を書いていない設定はこの版からjextractの段階で失敗します。ほかに、出力パラメーター経由で結果を返すasync関数のJNI生成コードの修正も入っています。
Kotlinを書かずにSwiftだけで動かすnative-activity
native-activityは、Kotlinの画面を持たず、SwiftでOpenGL ESのコンテキストを作って背景色を変化させ続けるサンプルです。ライフサイクルはAndroid Native App Glue(NDK付属のC実装)で受け取り、描画のタイミングはChoreographerに合わせます。Gradle設定は minSdk = 29、targetSdk = 36 です。
ボタンや文字入力といった通常のUIは自前で描くことになるため、業務アプリの画面をこの方式で作るのは割に合いません。ゲームや独自描画のエンジンをiOSと共有したい場合に限って検討する構成です。
SwiftUIの画面をAndroidで動かすSkip
Swift SDK for Android単体では、SwiftUIはAndroidで動きません。iOSアプリのSwiftUIを画面ごとAndroidに持っていくならSkip(skip.dev)を使います。Skipは対応済みのSwiftUI APIをJetpack Composeに対応づけ、Android側をComposeのネイティブ部品で描画します。未対応のSwiftUI APIもあるため、既存画面の移植前にSkipUIの対応一覧を確認し、必要に応じてComposeによる補完を見込みます。iOS側の成果物はSkipに依存しない通常のSwiftUIプロジェクトのままです。
Skip FuseとSkip Liteの違い
| 項目 | Skip Fuse | Skip Lite |
|---|---|---|
| 方式 | Swiftをネイティブコンパイル | SwiftをKotlinへ変換 |
| 使うコンパイラ | Swift SDK for Android | Kotlinコンパイラ |
| Swiftの言語機能 | すべて使える | 一部の総称型・演算子は変換不可 |
| Foundation | Swift公式の実装 | Kotlinで再実装したもの |
| Kotlinライブラリとの相性 | ブリッジ経由 | 直接使える |
モードはSwiftモジュール単位で選べるので、1つのアプリで混在させられます。Skip自身は多くのアプリにFuseを勧めています。メモリ解放のタイミングがSwiftと同じになり、Androidでビルドできる既存のSwiftパッケージをそのまま使えるためです。「SwiftのコードをKotlinに変換したい」場合に該当するのはLiteのほうです。
Skipの料金・導入コマンドと版の注意
Skipは以前、企業での利用に有料のサブスクリプションが必要でした。2026年1月21日の発表で、Skip 1.7以降はライセンスキー・EULA・試用期間がすべて廃止され、ビルドエンジンのskipstoneもオープンソースになりました(Skipの料金ページ)。
brew install skip
skip android sdk install
skip checkup
skip init --native-app --appid=com.example.myapp my-app MyApp
skip android sdk install はFuseモードに必要なSwift SDK for Androidを入れるコマンドで、既定では公開済みの最新リリースを選びます(Skip CLIのドキュメント)。skipstone 1.9.9(2026年9月16日)からは、Swift 6.4以降を指定するとNDKもr27ではなくr30を入れます。Liteで作るときは --native-app を --transpiled-app に替え、対話形式で選ぶなら skip create を使います。
版には注意が要ります。Skipのリリース一覧によると、2026年10月23日の1.9.17と1.9.18はバイナリの構成ミスで skip android の全コマンドが失敗し、公式は1.9.19以降を使うよう案内しています。Swift 6.4でのAndroidビルドの不具合は、10月26日の1.9.20で修正されました。Swift 6.4系と組み合わせるなら1.9.20以降にそろえてください。
Kotlin Multiplatform・Flutter・React Nativeとの選び分け
iOSとAndroidでコードを共有する手段を、既存資産の言語と共有したい範囲で比べます。
| 手段 | 共有する言語 | Androidの画面 | 向いているチーム |
|---|---|---|---|
| Swift SDK + swift-java | Swift | Kotlin/Compose | iOS資産がありロジックだけ共有 |
| Skip Fuse | Swift/SwiftUI | Composeへ自動対応 | iOS先行で画面も共有 |
| Kotlin Multiplatform | Kotlin | Compose | Android先行で資産がKotlin |
| Flutter | Dart | 独自描画 | 新規で両OSを同時に作る |
| React Native | TypeScript | ネイティブ部品 | Webのフロント人材が中心 |
Swift SDK for Androidを選ぶ理由になるのは、Swiftで書かれた検証済みのロジックがすでにある場合です。暗号処理、独自の同期エンジン、ドメインモデルのように、iOSとAndroidで挙動がずれると困るコードを1か所にまとめられます。Android側にKotlinのロジックが蓄積されていて、iOS側をそのAPIに合わせられるなら、Kotlin Multiplatform(KMP)を第一候補にします。言語ごとの選定条件はSwift・Kotlin・Dartの分岐条件で詳しく比べています。既存アプリへの組み込み方や体制の組み方で迷う場合は、Androidアプリ開発の支援にご相談ください。
Swift SDK for Androidを採用すべきでない場面
正式版になったとはいえ、Kotlinでの開発と同じ水準の開発体験はまだありません。次のどれかに当てはまる場合は、採用を見送るか、事前に条件を検証してください。
- Android側でSwiftのブレークポイントデバッグを日常的に使う場合:Android向けLLDBの調整を追跡していたswiftlang/llvm-projectのIssue #10831は2026年7月22日に「手順どおりに動く」としてクローズされましたが、手順をオンラインのドキュメントへ載せるのはこれからとされています。Android StudioでKotlinと同じ感覚でステップ実行できる前提で工数を見積もると外れます。
- Android専任のチームがSwiftを読めない場合:JNI境界で起きた不具合は、両方の言語を読める人がいないと切り分けられません。
- 共有するロジックが小さく、アプリ容量の増加を許容できない場合:Hello Worldでも実行ファイルは8MB台(未strip)になります。対象ABIと配布方式を決め、APKの容量増加を測ってから採否を判断してください。Android App Bundleなら、通常は端末に必要なABIのコードだけが配信されます。
- Xcodeのツールチェーンしか管理できないCI環境の場合:Xcodeとは別にオープンソース版ツールチェーンを管理し、Swiftを上げるたびにSDKとGradle側の
SWIFT_VERSIONをそろえ、Skipを採用している場合はその対応版も確認する必要があります。
Androidに対応させるライブラリを切り出すときのPackage.swiftの書き方は、Swift Package Manager入門で解説しています。
Swift SDK for Androidのよくある質問
Android StudioでSwiftのコードを書けますか?
Android Studioは、Gradleプロジェクトとして組んだKotlin側の開発に使います。2025年12月18日のWorkgroup記事は、デバッガとsourcekit-lspをVisual Studio CodeやAndroid Studioに統合することを今後の方向として挙げていました。Swiftのコードは、XcodeかSwift拡張を入れたVS Codeで書き、Gradleのタスクから swift build を呼ぶ構成が現実的です。Swift拡張は2026年4月8日からOpen VSX Registryにも公開され、CursorやVSCodiumでも使えます(Expanding Swift’s IDE Support)。
Swift PlaygroundsでAndroidアプリを作れますか?
作れません。Swift PlaygroundsはiPadとMac向けのアプリで、ビルド先もAppleのプラットフォームです。Android向けには、この記事の手順でオープンソース版ツールチェーンとSDKを入れます。
Xcodeに付属しているSwiftでAndroid向けにビルドできますか?
できません。公式ガイドはオープンソース版ツールチェーンを使い、SDKと版を完全に一致させることを条件にしています。Command Line Tools付属のSwift 6.3.3で6.4.0のSDKを指定すると、標準ライブラリのモジュールが見つからずに失敗しました。
SwiftのコードをKotlinに自動変換できますか?
Skip Liteを使えば、SwiftとSwiftUIのソースをKotlinとComposeに変換できます。ただし一部の総称型や演算子のオーバーロードは変換できません。Swift SDK for Android自体は変換ではなく、Swiftのままネイティブコードにコンパイルします。
Swift SDK for Androidは無料ですか?Appleの公式製品ですか?
無料で、swift.orgから誰でもダウンロードできます。Swiftプロジェクトの公式リリースとして配布されていますが、開発の主体はAndroid Workgroupです。Appleの開発者向け製品としてサポートが受けられるわけではありません。