たろすの技術メモ

Jot Down the Tech

ソフトウェアエンジニアのメモ書き

【2024年2月版】SwiftUIでiOS/Androidのデュアルプラットフォーム開発ができるSkipを触ってみた

※2024年2月時点の情報です。

概要

先日X(旧Twitter)で以下のポストが話題になっていました。

Skip(Swiftによるデュアルプラットフォームアプリ開発)の技術プレビューを発表できることにわくわくしています。 SwiftとSwiftUIでモダンなiOSアプリを書くと、SkipのXcodeプラグインがネイティブAndroid KotlinおよびComposeバージョンを生成します!

公式のよくある質問を確認すると、「Skip は、Flutter、React Native、Xamarin、Cordova などの他のフレームワークとどう異なりますか?」という質問に「Skip は、iOSAndroid という 2 つの主要なモバイル プラットフォーム専用の真のネイティブ アプリ開発に重点を置いています。」という回答があり気になったので、Skipの概要を調べて、iOS/AndroidでWelcome Skipper(SkipにおけるHello World)を表示するところまでやってみました。

GitHubリポジトリは以下です。

github.com

Skipについて

SkipプロジェクトはAbe White氏(@aabewhite)とMarc Prud'hommeaux氏(@marcprux)によって2023年に設立されました。彼らは初期のKindleアプリ開発に携わり、Abe氏はその後10 年間をTwitterで過ごし、iOS UI フレームワークの技術責任者を務められました(About)。

Skipとは、「Swift と SwiftUI を Android 用の Kotlin と Compose にトランスパイルする Xcode プラグイン」です。他のクロスプラットフォームと違い、(iOSのみ)配布する際にSkipモジュールを削除することができ、アプリサイズを小さくすることができます。

現在は開発中のため対応しているAPIは少ないですが、順次対応中のようです。

料金

skip.tools

オープンソースプロジェクトの場合は無料、非営利およびインディーデベロッパー(前年のアプリ受益者事業を合わせた収益が25万ドル未満)は$99(現在は開発中のため無料)、Enterpriseは$999(現在は開発中のため$499)です。

現在はTechnology Previewの段階のため、登録すると早期導入者割引の資格が得られるようです。ご興味がある方は早めに登録することをオススメします。↓

skip.tools

今後料金体系が変更される可能性は十分ありますが、個人的にはUnityのように一定規模までは商用でも無料で利用できる方がハードルが下がって嬉しいです。

参考:Unityの料金体系↓

unity.com

開発に必要なもの

Xcode15、Android Studio 2023、HomebrewがインストールされたmacOS 13以上のPC

開発環境

Skipをインストール

ターミナルで以下を実行します。

$ brew install skiptools/skip/skip

Welcome to Skip 0.8.12!

インストールが完了したら以下を実行して、開発の前提条件が満たされていることを確認します。

$ skip checkup

[✓] Skip version 0.8.12 (= 0.8.12)
[✓] macOS version 14.1.1 (> 13.5.0)
[✓] Swift version 5.9 (= 5.9.0)
[✓] Xcode version 15.0.1 (> 15.0.0)
[✓] Xcode tools SDKs: 5
[✓] Homebrew version 4.2.8 (> 4.1.0)
[✓] Gradle version 8.6 (> 8.3.0)
[✓] Java version 21.0.2 (> 17.0.0)
[✓] Android Debug Bridge version 1.0.41 (> 1.0.40)
[✓] Android Studio version: 2023.1
[✓] Android SDK licenses: 7
[✓] Resolve dependencies (14.63s)
[✓] Build hello-skip (18.46s)
[✓] Test Swift (12.96s)
[✓] Test Kotlin (122.71s)
[✓] Archive iOS ipa (21.91s)
[✓] Assemble HelloSkip-release.ipa (0.02s)
[✓] Verify HelloSkip-release.ipa 24 KB
[✓] Assembling Android apk (123.98s)
[✓] Verify HelloSkip-release.apk 6.2 MB
[✓] Check Swift Package (0.65s)
[✓] Skip 0.8.12 checkup (316.39s)pk

これでSkipの開発環境が整いました。(10分ほどで完了しました)

余談(読み飛ばしてOKです)

私は最初、興味本位でAndroid Studio Chipmunk | 2021.2.1 Patch 2を使用している状態で$skip checkupを実行しました。それが直接の理由かはわかりませんが、正常に完了できなかったので、解決までに行ったことを記録しておきます。

まず最初は以下の結果となりました。

[✓] Skip version 0.8.12 (= 0.8.12)
[✓] macOS version 14.1.1 (> 13.5.0)
[✓] Swift version 5.9 (= 5.9.0)
[✓] Xcode version 15.0.1 (> 15.0.0)
[✓] Xcode tools SDKs: 5
[✓] Homebrew version 4.2.8 (> 4.1.0)
[✓] Gradle version 8.6 (> 8.3.0)
[!] Java version 11.0.12 (< 17.0.0)
[✓] Android Debug Bridge version 1.0.41 (> 1.0.40)
[✓] Android Studio version: 2021.2
[✓] Android SDK licenses: 7
[✓] Resolve dependencies (19.75s)
[✓] Build hello-skip (24.07s)
[✓] Test Swift (13.22s)
[✗] Test Kotlin (79.51s)
[✓] Archive iOS ipa (23.73s)
[✓] Assemble HelloSkip-release.ipa (0.02s)
[✓] Verify HelloSkip-release.ipa 24 KB
[✗] Assembling Android apk (43.04s)
[✗] Verify HelloSkip-release.apk: /var/folders/0w/ntt1_4g51qnfwh4zhwj83x9c0000gn/T//BD2A3EDE-8C33-457A-9880-28E6DB66FD46/hello-skip/.build/Android/app/outputs/apk/release/app-release-unsigned.apk: The file “app-release-unsigned.apk” couldn’t be opened because there is no such file.
[✓] Check Swift Package (0.51s)
[✗] Skip 0.8.12 checkup (205.81s)
Error: 4 errors

古いAndroid Studio Chipmunk | 2021.2.1 Patch 2を使用していることが原因かもしれないと思い、Android Studio Hedgehog | 2023.1.1 Patch 2にアップデートして再度実行してみました。

アップデート後の結果↓

[✓] Skip version 0.8.12 (= 0.8.12)
[✓] macOS version 14.1.1 (> 13.5.0)
[✓] Swift version 5.9 (= 5.9.0)
[✓] Xcode version 15.0.1 (> 15.0.0)
[✓] Xcode tools SDKs: 5
[✓] Homebrew version 4.2.8 (> 4.1.0)
[✗] Gradle version: error executing gradle
[✗] Java version: error executing java
[✓] Android Debug Bridge version 1.0.41 (> 1.0.40)
[✓] Android Studio version: 2023.1
[✓] Android SDK licenses: 7
[✓] Resolve dependencies (8.32s)
[✓] Build hello-skip (19.06s)
[✓] Test Swift (13.16s)
[✗] Test Kotlin (0.78s)
[✓] Archive iOS ipa (16.93s)
[✓] Assemble HelloSkip-release.ipa (0.01s)
[✓] Verify HelloSkip-release.ipa 24 KB
[✗] Assembling Android apk (0.01s)
[✗] Verify HelloSkip-release.apk: /var/folders/0w/ntt1_4g51qnfwh4zhwj83x9c0000gn/T//EAB70A4F-93B6-4CD1-A39F-712850A67345/hello-skip/.build/Android/app/outputs/apk/release/app-release-unsigned.apk: The file “app-release-unsigned.apk” couldn’t be opened because there is no such file.
[✓] Check Swift Package (0.41s)
[✗] Skip 0.8.12 checkup (59.31s)
Error: 6 errors

逆にエラーが増えてしまいました。一番上のGradle version: error executing gradleから解消します。

まずは現在のGradleのバージョンを確認します。

$ gradle -v

以下のエラーが出ました。

ERROR: JAVA_HOME is set to an invalid directory: /Applications/Android Studio.app/Contents/jre/Contents/Home

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation.

このエラーメッセージは、JAVA_HOME環境変数が無効なディレクトリに設定されていることを示しています。JAVA_HOMEは、Java開発キット(JDK)のインストールパスを指す環境変数です。この問題を解決するには、有効なJDKのインストールパスをJAVA_HOMEに設定する必要があります。

まずはJavaがインストールされているか確認します。

$ java -version
openjdk version "21.0.2" 2024-01-16
OpenJDK Runtime Environment Homebrew (build 21.0.2)
OpenJDK 64-Bit Server VM Homebrew (build 21.0.2, mixed mode, sharing)

インストールされていることが確認できたので、JAVA_HOMEを設定します。(Javaのインストールパスは$ /usr/libexec/java_homeで取得できます。)

$ export JAVA_HOME=/opt/homebrew/Cellar/openjdk/21.0.2/libexec/openjdk.jdk/Contents/Home

再度Gradleのバージョンを確認します。

$ gradle -v             

------------------------------------------------------------
Gradle 8.6
------------------------------------------------------------

Build time:   2024-02-02 16:47:16 UTC
Revision:     d55c486870a0dc6f6278f53d21381396d0741c6e

Kotlin:       1.9.20
Groovy:       3.0.17
Ant:          Apache Ant(TM) version 1.10.13 compiled on January 4 2023
JVM:          21.0.2 (Homebrew 21.0.2)
OS:           Mac OS X 14.1.1 aarch64

無事確認できたので、再度$ skip checkupを実行すると、なんと解決しました。JAVA_HOMEが設定されていなかったのが原因だったのかもしれないですね。

余談終わり。

プリプロジェクトを作成

Skipでは以下のコマンドでプロジェクトを作成します。

$ skip init --open-xcode --appid=bundle.id project-name AppName

例えば以下のようにします。適宜置き換えてください。

skip init --open-xcode --appid=com.xyz.HelloSkip hello-skip HelloSkip

コマンド実行後、HelloSkipという名前の単一モジュールを含む新しいSwiftPMパッケージを含むhello-skip/フォルダが作成されます。Xcode によって新しいプロジェクトが開きますが、トランスパイルされたアプリをビルドして起動するには、その前に Android エミュレータが実行されている必要があります。Android Studioを使用し、Virtual Device ManagerからAndroid エミュレータを立ち上げてください。

※自動で開いたXcodeを閉じてしまい、hello-skipディレクトリを再度開こうとしましたが上手くいきませんでした。手動で開く場合はhello-skip/Darwinディレクトリを指定する必要があるようです。

ビルド成功しました。最初のビルドは時間がかかるようですが、私の環境ではそこまで時間はかからずすぐにビルドされました。(最初はiOS17.0.1のiOSシミュレータが選択できずXcode 15.0.1では起動することができなかったので、Xcode15.2をインストールして実行しました。)

まとめ

SwiftUIでiOS/Androidのデュアルプラットフォーム開発ができるSkipについて調べて触ってみました。導入からビルドまで、少し躓きましたが割とスムーズに進めることができました。現在はライセンスキーが不要で、Skipをインストール後すぐに使用できたことも要因かもしれません。

まだまだ実践利用はリスキーですが、現在はTechnology Previewの段階のためこれから状況は変わっていくと思います。ほぼ完全なネイティブコードで完全なiOS/Androidのネイティブアプリを構築できる点が素晴らしいと思っているので、このツールが発展していくととても嬉しいです。

皆さんの感想も聞かせてください。

それでは。