アプリをダウンロードせずに起動する App Clip

# アプリダウンロードはめんどくさい

[MoAR](https://whatever.co/moar/) はビル付近にきたひとたちにその場で即 AR 体験をしてもらう必要があるので通常のアプリ形式では App Store からダウンロードしてもらうのが手間。かといって QR コードからブラウザを開いて WebAR でというのも 8th Wall のコンテンツ開発がつらかった（他人の）記憶が思い出されてつらい…し、そもそも MoAR 実現に必要な VPS はその当時の 8th Wall には搭載されてなかった。

というところで iOS に App Clip という QR コードから直接 iOS ネイティブアプリを起動する仕組みがあったことを思い出して調査することに。

# App Clip とは

https://developer.apple.com/jp/app-clips/

App Store からダウンロードせずとも QR コードや NFC タグからネイティブアプリを起動する仕組みというのが iOS 14 から搭載されている。App Clip を起動させるトリガーは以下。

- App Clip Code
- QR コード
- NFC タグ
- Smart App Banner
- Message アプリ
- Map アプリ

Apple 的には見た目で即アプリが起動できることが判断できる App Clip Code を推してるぽいけど、App Clip 自体がほとんど認知されてない現状ではそれをカメラで読み取るというアフォーダンスが全く存在しないので、MoAR ではカメラをかざせば何かが起こることが容易に想像できる QR コードを壁面に描くことにした。
<br/>

<iframe width="100%" height="500" src="https://www.youtube.com/embed/K40kRiNV0bk" title="Launch MoAR app clip from QR code" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# 10MB 制限

App Clip はメインアプリの一部機能を切り出してインスタントに提供するというコンセプトなので、通常のアプリには存在しない制限がいくつかある。そのなかで一番大きな制限がアプリサイズを 10MB に収めないといけないというもの。（iOS 16 からは 15MB に緩和）

この 10MB は非圧縮状態で 10MB 未満にしないといけないので、フレームワークや大きめのアセットを追加したときはこまめにチェックしないと気がついたらオーバーしてるなんてことも容易にありえる。

ただしアプリ起動後に別途 Web サーバーからダウンロードするデータ量はこの制限には含まれない。アプリを起動するのに最低限必要なコードやアセットたちが 10MB に収まっていればOK。

MoAR では Geospatial API を使った AR システムと UI まわりの最低限のアセットだけを App Clip に含めて、それ以外の 3D モデルやテクスチャ、UI 内の大きな画像などはすべて起動後に Web サーバーからダウンロードする仕組みにしている。（じゃないととてもじゃないけど 10MB 未満には収まらない）

### App Clip のサイズをチェックする方法

https://developer.apple.com/jp/documentation/app_clips/creating_an_app_clip_with_xcode/

↑の「App Clipのサイズの抑制」のとこに Xcode でビルドしてレポートファイルを出力して確認する方法が書いてある。ちなみに Xcode の App Clip ターゲットで何も追加しない初期状態でレポート出力すると、

```
App + On Demand Resources size: 33 KB compressed, 129 KB uncompressed
App size: 33 KB compressed, 129 KB uncompressed
On Demand Resources size: Zero KB compressed, Zero KB uncompressed
```

となっていて非圧縮で 129KB となっている。

App Store Connect でも確認することができて、MoAR の最新バージョンだとおおよそ 7.89MB。（ダイエットする余地は多少あるけどわりとギリ…
![App Clip size](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2595/f9600da9-b37d-c10e-0e94-acd08224d6b4.png)
左側の 2.5MB とあるのは圧縮状態のサイズ。実際にデバイスにダウンロードされるのはこのデータ量。

# 使えないフレームワークがある

[Choosing the right functionality for your App Clip \| Apple Developer Documentation](https://developer.apple.com/documentation/app_clips/choosing_the_right_functionality_for_your_app_clip)

>Assets Library, Background Tasks, CallKit, CareKit, Contacts, Contacts UI, Core Motion, EventKit, EventKit UI, File Provider, File Provider UI, HealthKit, HomeKit, Media Player, Messages, Message UI, PhotoKit, ResearchKit, SensorKit, and Speech.

これらのフレームワークが使えない。

MoAR の AR 体験にはどれも不要だしだいじょぶっしょーって開発をある程度進めたあとに問題発生。アプリ内で AR 体験した内容をスクリーンキャプチャしてシェアするということも MoAR のもう一つの大事な機能だったのだけど、PhotoKit が使えないことでキャプチャしたあとそれを写真ライブラリに保存できなくなってしまった。

PhotoKit が使えないので保存するのは不可能だけどそのままシェアシート経由で SNS などにシェアすることは可能だったので最終的にそういう実装になった。（@asus4 のアイデア）

# デバッグ方法

Xcode からは通常のアプリ同様に "Run" するだけで起動することができるが、App Clip Code や QR コードからの起動テストをするには iOS の Developer mode 内の Local Experience を設定する方法と、TestFlight アプリから App Clip を立ち上げる方法がある。

[Testing the launch experience of your App Clip \| Apple Developer Documentation](https://developer.apple.com/documentation/app_clips/testing_the_launch_experience_of_your_app_clip)

前述のとおり、App Clip では使えないフレームワークや使えたとしても挙動が若干異なる場合があるので、本体側のアプリだけでなく App Clip 単体での動作をチェックしながら開発することが重要。

MoAR はメインアプリと App Clip の機能の違いがなかったこともあって App Clip ではなくメインアプリ側でずっと開発を続けてしまっていたのが PhotoKit 使えない問題の発覚を遅らせた原因…

# "App Clip Unavailable"

QR コードを読み取って出てくるカードに "App Clip Unavailable" とだけ表示されて起動できなくなってしまう怖い話は公開直前のゴタゴタも含めて別の記事に書きますね…
![IMG_11049BBF1F5C-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2595/98912078-5268-5c92-26f0-5ee79dc2a4bf.jpeg)

# 感想

いろいろ制限は多いし作りづらいんだけど App Store からダウンロードしなくても Web みたいに簡単に起動できて Web アプリではできないネイティブアプリならではの機能がさくっと提供できるのはいいなーと思うんだけどあんまり普及してないのはなんでだろなー。あんまりそういう感じでアプリが必要なシチュエーションて少ないんかなー？