📱

Expoキャッチアップ会 〜Expo SDK 51まとめ〜

2024/05/24に公開

みなさんこんにちは、株式会社Fusicのフロントエンドチーム「雅」の浦田です。

チーム雅では、スマートフォンアプリ開発にReact Nativeの開発プラットフォームであるExpoを利用しております。
Expo SDKの更新があるたびにチーム内でリリースノートの読み合わせをしており、今回もSDK 51がリリースされたということでまとめてみました。

https://expo.dev/changelog/2024/05-07-sdk-51

SDK51ではSDK50ほどの目玉機能のようなものは追加されませんでしたが、React Nativeの新しいアーキテクチャが使えるようになったのは大きな変更ですね!
アップデートの際に気を付ける点で言うと、よく使うexpo-cameraが新APIに移行するのと、Expo Goが最新バージョンのみのExpo SDKしかサポートしなくなることは気を付けたいですね。

New Architecture is rolling out in 2024!

  • Expo SDK51とReact Native 0.74を用いて新しいReact Nativeアーキテクチャのテストを進めている
  • 新しいアーキテクチャのKnown issuesについてはこちら
  • まだデフォルトでは有効になっていませんが、試したい場合はこちらを参考に
  • SDK52から新アーキテクチャを利用できる予定とのこと

New default project template and "Getting Started" flow

  • npx create-expo-appコマンドで新しいテンプレートによるプロジェクトが作成されるようになった
  • プロジェクトの中身としては、ほとんどのプロジェクトで使われるような一般的な依存関係と設定が含まれている
  • npm run reset-projectコマンドが用意されていて、これを実行するとデフォルトで用意されたボトムタブのレイアウトから不要なコードが削除され完全なブランク状態に変更することができる(最初のボトムタブのコードはapp-exampleディレクトリへ移動される)
  • ドキュメントの「Getting Started」フローも更新され、開発環境の選択(物理デバイス or シミュレータ。Expo Go or Developement Build)を行ってから、Getting Startedフローを進めていくような流れになったので、初学者でもExpoを始めやすくなった

"Next" Camera and SQLite APIs are now the defaults

  • expo-camera/nextexpo-sqlite/nextがデフォルトAPIのexpo-cameraexpo-sqliteになった
  • これにより、従来のCameraとSQLite APIはSDK 51ではexpo-camera/legacyexpo-sqlite/legacyとなり、SDK 52では削除される
  • 新しいAPIにはlegacyと同じpropsや関数が残っていますが、いくつか変更されたものもあり、例えばonBarCodeScannedonBarcodeScannedに変わっている
  • 新しいCamera APIのモチベーションについては expo-camera/next is ready for a close upのブログ記事で詳細に知ることができる
    • AndroidではCameraXを使うようにした
    • バーコード読み取りの信頼性向上
    • ほとんどの設定値をpropsから設定できるようにした
    • あまり使われていない顔検知機能をなくした
  • 新しいSQLite APIはSQLite 3.45.3ベースで構築されており、WebやNode.jsに存在しているような同等のモダンなAPIを提供することを目的に作られた
  • 例としてsync/asyncメソッド、既存DBのインポート、prepared statements、update callbacks、Blob data type、custom build flagsなどがある

Introducing expo-symbols

  • expo-symbolsは、iOSのSF Symbolsライブラリへのアクセスを提供する新しいパッケージ
  • SF Symbolsは、Appleが提供するアイコンセットで、サイズや線の太さなどを変更できるため、アプリのデザインに柔軟に対応できる
  • expo-symbolsを使うことで、iOSアプリのデザインがさらに洗練され、統一感を持たせることが可能になる
  • しかし、Androidとの一貫性をどのように維持するかは悩ましいところがある

Fingerprint runtime version policy promoted from experimental to beta

  • フィンガープリントのランタイム・バージョン・ポリシーが experimental から beta に昇格した
  • "runtimeVersion": { "policy": "fingerprint" }フィールドを app.json に使用することで、アップデートが常に互換性のあるネイティブランタイムをターゲットすることができる
  • これにより@expo/fingerprintとEAS BuildとUpdateの統合がシームレスになるとのこと

Expo Router v3.5

  • 新しいリリースは、バグフィックスがメインとのことで、詳細については、別途ブログが上がるとのこと
  • 主な変更点
    • #セグメントURLをサポート
    • router機能に、.dissmiss().dissmissAll().canDismiss()を追加
    • WinterCG準拠のRequest/Responseを採用(ExpoRequestExpoResponseを削除)
    • routes、_layoutファイルが、プラットフォーム固有の拡張機能に対応(よく理解できなかった...)
    • ディープリンクURLを書き換えられるようになった(これもよく理解できなかった...)
    • Typed Routesが改善
    • Typed routesのHrefがgenericではなくなった
    • experiments.baseUrlのWebサポート問題を修正

Apple Privacy Manifests

  • 5月1日より、Appleはユーザーのプライバシーやセキュリティに関するAPIを使用するアプリにプライバシーマニフェストを含めること必須可している
  • Expo configにプライバシーマニフェストを追加する機能がサポートされた
  • これによりマニフェストファイルの提出がより簡単になった
{
  "expo": {
    "ios": {
      "privacyManifests": {
        "NSPrivacyAccessedAPITypes": [
          {
            "NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategoryUserDefaults",
            "NSPrivacyAccessedAPITypeReasons": ["CA92.1"]
          }
        ]
      }
    }
  }
}
  • また、ExpoチームはCocoaPodsリソースバンドルからプライバシーマニフェストの自動集約機能を追加するコントリビュートをReact Nativeに行った
  • この機能はReact Native 0.74.1で利用可能だが、まだサポートされていないエッジケースもあるため、SDK 51プロジェクトではデフォルトで一時的に無効になっている
  • すぐ試したい場合は、expo-build-properties configプラグインios.privacyManifestAggregationEnabledtrueに設定することでオプトインできる(BareプロジェクトではPodfileで直接設定可能)

EAS Update: rollout web UI and new preview page

  • SDK50でリリースされた新機能のロールアウト(OTAアップデートを一気に反映させるのではなく、徐々に反映させていける手法のこと。誤って本番環境にバグを導入した場合の影響を最小限に抑えられるようになる)がWeb UI(ダッシュボード)で利用できるようになった
  • またアップデート情報の共有UIも刷新され、QRコードを利用することで簡単にプレビューが見られるようになった(Orbitとも統合され、より簡単に)

🧹 Expo Go: Dropped SDK 49 and 50

  • Expo GoのPlayストア/App Storeバージョンは、現在SDK 51のみをサポートしている
  • SDK 49または50を使用する場合は、Expo CLIまたはexpo.dev/goを使用して、プロジェクトに適したバージョンのExpo Goをインストールできる
  • SDK 50で発表されたように、SDK 51以降、Expo Goは一度に単一のSDKバージョンのみをサポートする
  • つまり、SDK 51をサポートする新しいExpo GoバージョンがApp StoreおよびPlayストアにリリースされると、SDK 51のみがサポートされ、SDK50以下はサポートされない
  • 特定のバージョンのExpo Goをできるだけ簡単にインストールできるように、expo.dev/goというウェブサイトを作成された
  • これは、Androidデバイス/エミュレータおよびiOSシミュレータで動作するが、物理的なiOSデバイスでは最新バージョンのExpo Goしか使用できないので要注意

Other Highlights

  • 新しいexpo-videoライブラリのベータリリース予定
    • 元々あったexpo-avのビデオ機能を書き直し刷新
    • SDK 51リリース後にも継続して更新されるため、現状ではExpo Goでの利用は不可
  • eslint-config-exponpx expo lintコマンドの実装
    • eslint-config-expoを拡張したESLint設定ファイルを生成できるようになった
    • コードの正しさを重視し、機能よりも構文の一貫性などを保証するstylistic rulesは許容しないものとなっている
  • expo-asset configプラグイン
    • assetsをネイティブリソースとして簡単にリンクできるようになった
    • 元々expo-imageのsourceはrequire('assets/images/hoge.jpg') と呼び出す必要があったが、app.jsonで以下のように記述することでsourceの呼び出しが"hoge"のみでよくなる
{
 "plugins": [
    [
      "expo-asset",
      {
        "assets": ["./assets/images/hoge.png"]
      }
    ]
  ]
}
  • build.gradleの最新化
    • Expoモジュールの整備(自分でメンテナンスしてる場合は不要)
  • Bundlerの速度改善
    • EXPO_USE_FAST_RESOLVER=1を設定することで、Metroの解像度を最大6倍まで高速化できるようになった
    • これまで高速化するために使われていたexoticモードが廃止され、デフォルトのexpo/metro-configのみで問題なくなった
  • Expo CLIは、ネットワーク経由のiOSデバイスおよびVision Proシミュレータでの実行をサポートするように
    • npx expo run:ios --deviceを使うことでExpo CLIから選択が可能になる(Xcodeと同じ操作感で使用できる)
  npx expo run:ios --device
? Select a device ›
❯   🌐 iPhone (17.4.1)
    🌐 Apple Vision Pro (1.1.1)
    iPhone 15 (17.4)
    iPhone 15 Plus (17.4)
  ↓ iPad Pro (12.9-inch) (6th generation) (17.4)
  
  • create-expo/create-expo-appでYarn、pnpm、Bun、npmのパッケージマネージャがサポート
  • Expo OrbitのWindows版のベータテストがスタート
  • EAS BuildのiOSビルド用のデフォルトイメージがmacOS 14.4とXcode 15.3に設定
  • React Native 0.74以降で動作するように(Reactは18.2.0から変更なし)

Deprecations, renamings, and removals

  • expo-camera/nextの登場によりexpo-cameraのインポートが変更

    • 既存のものを使いたい場合はexpo-camera/legacyのインポートが必要
    • SDK 52でlegacyのサポートは切れる
    • expo-sqliteも上記と同様の変更があるので注意
  • Fingerprintのランタイムポリシーが変更

    • app.jsonにて"runtimeVersion": { "policy": "fingerprintExperimental" }"runtimeVersion": { "policy": "fingerprint" }に書き換える必要がある
  • app.jsonからhooksフィールドが削除

    • Classic Updatesとsentry-expoのために使用されていたが、SDK50のタイミングで@sentry/react-nativeに移行したため非推奨となる
  • sentry-expoのサポート終了

    • @sentry/react-nativeに完全移行
  • Expo GoでのサポートがSDK 51のみとなる

  • Expo Go for iOSにてGoogle Mapsのサポート終了

    • Apple Mapsを使用するか、Buildして確認となる
  • Expo Go for Androidにてフォアグラウンド位置情報サービスのサポート終了

    • 開発で使いたい場合はisAndroidForegroundServiceEnabledを設定する必要あり
  • 通知のentitlementがprebuildでiOSに自動追加されなくなる

    • expo-notificationsを使用する場合は問題なし
    • それ以外の場合はapp.configにaps-environmentを追加する必要がある
{
  "expo": {
    "ios": {
      "entitlements": {
        "aps-environment": "development"
      }
    }
  }
}
  • Known issues
    • SDK 51でタブを切り替えるとExpo Routerがクラッシュする問題 → Expo Go v2.31.5で解決済み
    • 開発ビルドでロードするためにはruntimeVersionを設定する必要がある → expo-updates@0.25.14で解決済み
    • react-native-dotenvの非互換性
      • Babelプラグインがexpo-routerの設定環境変数を上書きし、空の「Welcome to Expo」画面が表示されてしまう
      • 解決策はライブラリとBabelプラグインの削除、またはExpo CLIの.envファイルサポートの利用をする

➡️ Upgrading your app

  • SDK 51へのアップデート手順についての記載
  • 以下のコマンドを実行する
npm i -g eas-cli
npx expo install expo@^51.0.0 --fix
npx expo-doctor@latest
  • SDK 51ではXcode15.3以降が必要となる
  • ネイティブコードが存在する場合には手動アップグレードが必要となる
  • 使用しているデバイスのExpo Goアプリを最新バージョンへの更新が必要となる(Expo CLIはシミュレータ内のアプリを自動的に更新する)
  • expo-dev-clientを使用している場合はアップグレード後に新しい開発ビルドを作成する必要がある

Tune in to upcoming conferences for more news!

React Conf、App.js Confにて、Expoについてのセッションがあります(した)!

Fusic 技術ブログ

Discussion