Vision Pro 向けアプリを react-native-visionos で作ってあそぶ
Swift および Swift UI を使った Vision Pro 向けアプリの研究はそれはそれで続けていくのですが、よりひろいフロントエンドマンとしては JavaScript / TypeScript で作っていく方法についても研究していきたい。ということで react-native-visionos をとりあげていく。
さて、まずはそもそも react-native-visionos とはってところから書いていく。
react-native-visionos は callstack 社がオープンソースにて公開しているプロダクト。
react-native を fork してつくられている。
callstack とは React を中核技術に据えた開発会社らしく、ほかにもいろいろなプロジェクトが展開されている。
とりあえず、まずはリポジトリから参照できる以下のドキュメントに沿って作ってみる
コマンドラインにて以下を実行することで新規プロジェクトを作成できるようだ。
$ npx @callstack/react-native-visionos@latest init YourAppName
なので、まずは Hellow World だ!ってことで以下の名前で作成を開始。
ちなみに、Macによる作業はちょっと前に購入した Mac mini M2 に最低限のセットアップのみを行なった状態 (VisionOS 向けアプリをつくってみる (城崎温泉ワーケーション成果スライド) - よりひろい フロントエンド) なので、新しく環境を構築する人も以下に続く同様のエラーが出るかもしれない。いろいろなセットアップをしている人はすんなりいくかもしれない。
実行をしたのは以下。
$ npx @callstack/react-native-visionos@latest init helloworld-1
するとエラーが出た。どうやら alphanumeric でないといけないらしい。
error "helloworld-1" is not a valid name for a project. Please use a valid identifier name (alphanumeric).
ということで名前を変更して作成。
$ npx @callstack/react-native-visionos@latest init helloworld1
しかしこれもエラー。
error Project name shouldn't contain "HelloWorld" name in it, because it is CLI's default placeholder name.
おお、HelloWorld という名前自体がデフォルトのプレースホルダ名らしく NG らしい。 ということで、以下を実行。
$ npx @callstack/react-native-visionos@latest init MyHello
続いて、以下のエラー。
...
✖ Do you want to install CocoaPods now? Only needed if you run your project in Xcode directly … no
error Installing pods failed. This doesn't affect project initialization and you can safely proceed.
However, you will need to install pods manually when running iOS, follow additional steps in "Run instructions for iOS" section.
✖ Installing dependencies
なるほど、依存管理に CocoaPods が必要らしいため、インストールをする。
しかし、エラーが発生。必要なライブラリのバージョンが足りないらしい。
$ sudo gem install cocoapods
...
ERROR: Error installing cocoapods:
The last version of drb (>= 0) to support your Ruby & RubyGems was 2.0.6. Try installing it with `gem install drb -v 2.0.6` and then running the current command again
drb requires Ruby version >= 2.7.0. The current ruby version is 2.6.10.210.
...
ということで、以下を実行。先は長そう。
$ sudo gem install drb -v 2.0.6
あらためて CocoaPods をインストール。 またエラーが出るので、あきらめずに必要なものをインストールしていく。
$ sudo gem install cocoapods
...
ERROR: Error installing cocoapods:
The last version of activesupport (>= 5.0, < 8) to support your Ruby & RubyGems was 6.1.7.7. Try installing it with `gem install activesupport -v 6.1.7.7` and then running the current command again
activesupport requires Ruby version >= 2.7.0. The current ruby version is 2.6.10.210.
$ sudo gem install activesupport -v 6.1.7.7
今度こそ CocoaPods をインストールだ。
$ sudo gem install cocoapods
...
Installing ri documentation for cocoapods-1.15.2
Done installing documentation for cocoapods-core, cocoapods after 1 seconds
2 gems installed
うん、OK。
ではプロジェクトを作成。しかし xcode-select に関するエラー。
npx @callstack/react-native-visionos@latest init MyHello
...
✖ Installing CocoaPods dependencies (this may take a few minutes)
error xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance
error Installing pods failed. This doesn't affect project initialization and you can safely proceed.
However, you will need to install pods manually when running iOS, follow additional steps in "Run instructions for iOS" section.
✖ Installing CocoaPods dependencies (this may take a few minutes)
そこで、xcode-select に Xcode のパスを設定する。
$ sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
ということで、再実行していく。まだ心は折れていない。
npx @callstack/react-native-visionos@latest init MyHello
...
✔ Downloading template
✔ Copying template
✔ Processing template
✔ Installing dependencies
✔ Do you want to install CocoaPods now? Only needed if you run your project in Xcode directly … yes
✔ Installing Ruby Gems
✔ Installing CocoaPods dependencies (this may take a few minutes)
...
✔ Initializing Git repository
...
無事プロジェクトの作成が完了した。
デフォルトのスタートアップアプリを起動してみよう。
$ yarn visionos
...
... /react-native-visionos/MyHello/visionos/Pods/Target Support Files/Pods-MyHello/Pods-MyHello.debug.xcconfig:1:1: error: unable to open configuration settings file
warning: Unable to read contents of XCFileList '/Target Support Files/Pods-MyHello/Pods-MyHello-resources-Debug-output-files.xcfilelist' (in target 'MyHello' from project 'MyHello')
warning: Unable to read contents of XCFileList '/Target Support Files/Pods-MyHello/Pods-MyHello-frameworks-Debug-output-files.xcfilelist' (in target 'MyHello' from project 'MyHello')
error: Unable to load contents of file list: '/Target Support Files/Pods-MyHello/Pods-MyHello-frameworks-Debug-input-files.xcfilelist' (in target 'MyHello' from project 'MyHello')
error: Unable to load contents of file list: '/Target Support Files/Pods-MyHello/Pods-MyHello-resources-Debug-input-files.xcfilelist' (in target 'MyHello' from project 'MyHello')
error: Unable to load contents of file list: '/Target Support Files/Pods-MyHello/Pods-MyHello-resources-Debug-output-files.xcfilelist' (in target 'MyHello' from project 'MyHello')
warning: Run script build phase '[CP] Copy Pods Resources' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'MyHello' from project 'MyHello')
warning: Run script build phase 'Bundle React Native code and images' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'MyHello' from project 'MyHello')
error: Unable to load contents of file list: '/Target Support Files/Pods-MyHello/Pods-MyHello-frameworks-Debug-output-files.xcfilelist' (in target 'MyHello' from project 'MyHello')
warning: Run script build phase '[CP] Embed Pods Frameworks' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'MyHello' from project 'MyHello')
** BUILD FAILED **
...
しかし、ビルドエラー。長々といろいろ出ているけど、以下を実行していなかったことがわかった。
$ bundle install
$ bundle exec pod install
...
[Hermes] Using commit defined by HERMES_COMMIT envvar: xxx
Const Defined!
[!] Failed to load 'hermes-engine' podspec:
[!] Invalid `hermes-engine.podspec` file: [!] Unable to locate the executable `cmake`.
# from ... /react-native-visionos/MyHello/node_modules/@callstack/react-native-visionos/sdks/hermes-engine/hermes-engine.podspec:120
# -------------------------------------------
# puts "Const Defined!"
> CMAKE_BINARY = Pod::Executable::which!('cmake')
# # NOTE: Script phases are sorted alphabetically inside Xcode project
# -------------------------------------------
cmake が足りていなかった模様。そういえばそういう類のものを入れていなかった。 なので以下を実行。
$ brew install cmake
これでようやく、実行できる!
$ yarn visionos
yarn run v1.22.22
$ react-native run-visionos
info Found Xcode workspace "MyHello.xcworkspace"
info Found booted Apple Vision Pro
...
success Successfully built the app
...
success Successfully launched the app
✨ Done in 11.85s.
たしかに VisionOS のシミュレータにてアプリは起動するものの、エラーの表示が出る。 ようやくここまできた。
エラー表示は、このようなもの。
No bundle URL present.
Make sure you're running a packager server or have included a .jsbundle file in your application bundle.
RCTFatal
__28-[RCTCxxBridge handleError:]_block_invoke
_dispatch_call_block_and_release
_dispatch_client_callout
_dispatch_main_queue_drain
_dispatch_main_queue_callback_4CF
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
__CFRunLoopRun
CFRunLoopRunSpecific
GSEventRunModal
-[UIApplication _run]
UIApplicationMain
OUTLINED_FUNCTION_75
OUTLINED_FUNCTION_75
OUTLINED_FUNCTION_2
$s7MyHello0aB3AppV5$mainyyFZ
main
start_sim
0x0
0x0
main.jsbundle がきちんと出力されていないらしい。ということで以下を実行する。
$ react-native bundle --entry-file='index.js' --bundle-output='./visionos/main.jsbundle' --dev=false --platform='ios' --assets-dest='./visionos'
ちなみに、上記コマンドについては、こちらの記事を参考にさせていただいた。昔の記事だけど、今でも React Native を使っていると同様の問題が出るようだ。
今回は VisionOS 向けなので --bundle-output
と --assets-dest
は ./visionos
以下にする必要があった。またplatformについては ios
とする必要があった。今後どこかでここも変わるかもしれない。node_modules
以下を調べてみたが、どうやら指定されたプラットフォームに対応した js がロードされる仕様っぽいが XXX.visionos.js
のようなファイルはまだないらしい。
ということで、無事に表示され、Hello World 的なことは完了した。
次回以降、どんな UI がつかえて、どんなことはできないのかをいろいろディスカバリーしていきたい。