Xcode Cloudから無理やりMagicPodにARM64アプリをアップロードする
おはようございます。noteでiOSアプリ開発をしているwaturaです。最近、自動車免許をとったんですが、よくもまあみんな運転できるよなぁと感じています。運転めっちゃ怖くないですか?
MagicPod
note iOSアプリではMagicPodを使ってテストを行っています。
いくつかMagicPod関連の記事があるので、前提としてみていただけるとうれしいです。
画像をアップロードできない問題
MagicPodのヘルプページにもあるのですが、一部の条件下で画像を選択出来なくなります。それが下記なのですが、ばっちしnoteアプリが当てはまっていました。
MagicPodにはXcode Cloudからアプリをアップロードしています。Xcode CloudはIntel Macなようなので、Simulator向けビルドはx86向けにビルドされてしまいます。そして、PHPickerViewControllerを使っています。そのため、上記の条件に当てはまってしまい、画像が選択できず、画像がアップロードできるかどうかのテストが必ず失敗するという事態になってしまっていました。
MagicPodの方に相談したりして、一時しのぎの対応として INTEL_MACオプションを設定し、iOS 14を使うようにしていました。
iOS 14を切る準備はしたい
いまのところ切る予定は決まっていないのですが、アプリエンジニアとしては早く新しい機能を取り込んでいきたいし、プリプロセッサで条件分岐をかくのもあれなので、早く15以上にしていきたいなぁと思っています。
しかし、たとえnote社内ルール的にiOS 14をきれる状態になったとしても、MagicPodでテストを実行し続けるために、14対応を維持し続けなければいけませんでした。
これを解消するためには、なんらかの方法でMagicPodで画像アップロードまわりを対応する必要がありました。
そのためにできることとしては、おおむね次の2つです。
PHPickerViewControllerを使うテストをやめる
arm64でビルドしたものをアップロードする
画像アップロード機能があるnoteというアプリで、「CIが画像アップロードに対応しなくなるから、画像アップロードのテストを削除します。」は、「なんのためのテストだよ。」となってしまうのでどう考えてもNGです。
それでは、arm64でビルドしたものをアップロードする方法を考えていきます。
arm64でビルドしたものをアップロードするには
arm64環境のCIを使ってビルドする
M1, M2のPCでビルドする
のどちらかだと思っていました。しかし、実際には「x86環境からでもarm64向けのビルドができる」ことがわかりました。
まあ、考えてみれば簡単なことなのですが、iOS実機がそもそもarm系CPUなのでIntel macからでもarm64ビルドは出来てもおかしくないはずでした。
Xcode Cloudでarm64 simulator向けビルドを行う
注意としては、
1. 無理やりビルドしているだけなので動かなくなる可能性はある
2. Xcode CloudがApple Siliconになれば万事解決
3. 余分なビルドを実行しているので実行時間が延びる
4. ビルドするタイミングによっては動かない
5. Artifactとして保存するようにはまだしていない
とかがあります。
また、Xcode Cloudで実行するとはしていますが、Xcode Cloud以外の環境でもほぼほぼ同様に実行できるかと思います。
やったこと
Xcode Cloudでテスト環境向けビルドしているときのxcodebuildコマンドをコピってくる
コピったコマンドの意味をある程度理解する
xcodebuildコマンドでiphonesimulator向けのビルドにする方法を探す
Xcode Cloudのログをみていくと、xcodebuild build-for-testing hogehogeというコマンドを実行しているところが見つかるかと思います。そこがxcodebuildをつかって、Simulator向けビルドをしているところになります。
そのコマンドをなるべく周到するかんじで、いじくっていきました。
その結果がこのgistになります。(使っているものから、ちょっといじっていたりするのでそのままでは動かないかもしれません)
重要なのはラスト2行になります。
-arch arm64
-sdk iphonesimulator
ここです。これは、ビルドするときのarchをarm64にして、sdkとしiphonesimulatorをつかってビルドしてください!というオプションになります。
-archがなかった場合は、x86ビルドになり、-sdkがなかった場合はiphoneos向けのビルドになります。なので、両方を指定する必要があります。
また、コピペしたコマンドでは、destinationとしてiPhone Simulatorが指定されていたのですが、Simulatorを指定してある場合は、archが指定できなくなります。destinationの向いている先のarchとsdkを自動で使ってくれるという設定なので、当然といえば当然です。
この処理と、別記事のmagicpodにアップロードするスクリプトをci_post_clone.shで実行するようにしました。
すくなくともこのスクリプトのままでは、実行するタイミングをci_post_xcodebuild.shにしてはダメです。このスクリプトで作られるアプリがXcode Cloudがつかうつもりで作っていたアプリを上書きしてしまっているためです。Xcode CloudのSimulatorで実行しようとしたさいにエラーが発生します。
なので、Xcode Cloudがビルドする前か、テストし終わったあとに実行する必要があります。
MagicPodの実行には非常に時間がかかっているので、1分でも早くテストを開始しておきたいのと、Xcode Cloudがビルドした結果も保持しておきたかったので、post_cloneのタイミングで実行するようにしました。
まとめ
iOS 14をそのうち切りたい。切りたいが、MagicPodがiOS 14じゃないとダメなんだ。じゃあ、なんとかするぞ!ではじめたことなんですが、無事にできました。
MagicPodでPHPickerViewControllerを使いたかったら、iOS 14かarm64のアプリを用意する必要がありました。
Xcode Cloudはx86環境なので、何も考えずにアップロードするとx86アプリがアップロードされる。
無理やりxcodebuildをたたくようにして、arm64アプリをつくって、MagicPodにアップロードするようにしました。
これで、iOS 15以上をターゲットにするようにできて、かつ、MagicPodも使えるので、幸せに少し近づきました。
こんなかんじでテストをしたりしてガシガシ作っているアプリなので、ぜひ使ってみてください。
▼noteエンジニアアドベントカレンダーはこちら
▼さらにnoteの技術記事が読みたい方はこちら