Files
jrshikoku/docs/refactor-audit/07-native-platform.md
harukin-expo-dev-env 68f66d0109 feat: Add CI/CD release audit documentation and refactor roadmap
- Introduced comprehensive CI/CD release audit documentation detailing current repository automation, EAS configuration, manual workflows, and recommended PR pipelines.
- Added a structured refactor roadmap outlining phases for improving API boundaries, domain model integration, and CI/CD automation.
- Proposed specific skills for project management to enhance understanding of application-specific knowledge and maintainability.
- Updated package.json to include expo-sqlite dependency and modified yarn.lock accordingly.
2026-08-29 22:43:44 +09:00

7.8 KiB

Native / Platform監査

1. Platform構成

領域 iOS Android Expo Go可否
通常React Native Expo/RN Expo/RN 可(Native依存を使わない範囲)
FeliCa CoreNFC NFCTagReaderSession NfcF ReaderMode 不可、Development Build + 実機
Live Activity/通知 ActivityKit、pushType:nil 単一Foreground Service + notification 不可
Widget targets/widget WidgetKit/ActivityKit react-native-android-widget receiver/task 不可
Maps/Share/WebView Native SDK/extension Native SDK/extension 機能により不可
local module Swift Kotlin 不可

expo-dev-clientとEAS development profileは存在するが、package scriptは単純なexpo startのみで、Dev Client利用を明示するscriptはない。

2. Local Expo modules

expo-felica-reader

構成はExpo Modules APIに沿っており、expo-module.config.json、TS wrapper、Swift/Kotlin実装がある。iOSはpingisAvailablesaveWidgetDatascanを定義し、AndroidはisAvailablescanが主である。TS wrapperはsaveWidgetDataをoptional扱いし、pingは公開ラッパー以外から参照されないため、この差だけを現在障害とは判定しない。Webはoptional module fallbackである。なおconfigはios,tvos,android,webをplatform宣言するが、Native実装はiOS/Androidのみであり、capability表現は整理余地がある。

主なリスク:

  • Android isAvailableがadapter存在だけで、NFCが有効かを見ない。
  • Android ReaderModeに画面離脱/キャンセルの明確なcleanup経路がない。
  • iOS/Androidのエラーコード・promise完了・複数scanの扱いが同一契約でない。
  • TSコメントにservice codeの古い表記が残るが、実装は0x090F
  • FeliCa system codeはapp configに宣言されているが、Info.plist、signed entitlements、Provisioning Profileの最終組み合わせは生成済み署名buildと実機で確認する。静的監査だけで「配置誤り」とは断定しない。
  • scan失敗時のdiagnostic messageがmodule keys等を含み得る。ユーザー向けエラーと開発用診断を分ける。

expo-live-activity

iOSとAndroidで機能の意味が異なる。iOSはActivityKitへstateを送るがremote push tokenはない。AndroidはActivityKit相当ではなく、通知ID一つのForeground Serviceである。

主なリスク:

  • AndroidはstartForegroundService直後に開始成功を返し、実際の起動失敗を呼び出し元が知れない。
  • Android serviceが独自URLを15秒pollし、RNのcurrent position repositoryと重複する。
  • Androidの時刻比較がCalendar.getInstance()(端末timezone)で、JST/service dayと分離されていない。
  • 一つのnotification/service IDのため、複数列車・駅追従が競合し得る。
  • iOS stateではstaleDateがnilで、更新停止をOSへ伝える契約が弱い。
  • moduleロード時・update時に詳細なconsole.logが残る。

3. Widget / App Group

targets/widget/expo-target.config.jsはWidget targetをdeployment target 17.0、App Groupを指定する。app.json、iOS module、Widget targetに同じApp Group文字列が複数記載される。SharedData.swiftはApp Group取得失敗時に標準UserDefaultsへfallbackするため、entitlement不備が空Widgetとして見える可能性がある。

Android Widgetはapp.jsonの更新周期30分と、handler内の独自fetchを持つ。RNのcache/observabilityとは分離している。

4. Config plugins

with-android-local-properties

ANDROID_HOME/ANDROID_SDK_ROOTまたはhome配下の推測値をandroid/local.propertiesへ書く。これは開発マシン依存の生成物で、CIでは環境差を作る可能性がある。local.propertiesはbuild環境の責務として扱い、アプリ設定の再現性判定から分離する。

with-nfc-widget-guard

固定パスのMainApplication.ktへimports、method、onCreate callを文字列置換する。markerで再適用を避けるが、Expo template、applicationId、生成コードの文言変更でskipしてもbuildは成功し得る。plugin testまたは生成後assertが必要。

Babel font scaling plugin

Text/TextInput/Animated.TextallowFontScaling=falseを追加する。これはnative build問題ではないが、platform accessibilityを横断して変えるため、画面単位の意図へ戻す候補である。

5. Native生成物の扱い

ios//android/はGit外なので、そこで見つかった設定差は「現在のローカル生成物の状態」であり、EASの正本ではない。app configが7.2/build 69/35なのに、生成物には古いversion/build値がある。一方、読み取り専用EAS CLIでは2026-08-25の7.2/build 69/35がiOS/Androidとも成功しており、現行CNG経路の破綻は確認していない。問題はローカル生成物の誤編集と、次回SDK/template変更時の再生成保証である。

分類:

変更場所 prebuildで消えるか 正しい扱い
ios//android/直接編集 消える可能性が高い source化せず、plugin/config/moduleへ移す
modules/** 追跡source JS/Swift/Kotlinを同時更新
targets/widget/** 追跡source Apple target configとbuild smoke
plugins/** 追跡source idempotent/生成後assert
app.json 追跡source version/permission/entitlement正本

今回prebuild --cleanや新規Native buildは実行していない。再生成を伴う検証は別作業として承認・backup・差分レビューを前提にする。既存EAS Build一覧だけを読み取り確認した。

6. Permission / entitlement

  • iOS NFC、FeliCa system code、App Group、Live Activity。
  • iOS locationはforeground requestのみ。画面ロック後の到着通知要件と一致するか要確認。
  • Android NFC、coarse/fine location、POST_NOTIFICATIONS、Foreground Service関連。
  • UIBackgroundModes=audio、duplicate location permission、Widget/Live Activity target差は最小権限の観点で確認。

permissionは宣言があるだけで機能を保証しない。拒否、NFC OFF、権限変更、OS upgrade、process kill、低電力モードを実機matrixへ入れる。

さらにruntimeVersion: sdkVersionはNative sourceの変更をruntimeへ反映しない。FeliCa API、Widget target、Live Activity、permission/config plugin変更を含むbuildと、旧binary向けEAS Updateを同じruntimeに置かない運用が必要である。Native変更前にfingerprintappVersion、custom policyを比較し、選定後も実build/update matrixで確認する。

7. 推奨Development Buildフロー

  1. Expo Go: 通常の純JS UIと軽いnavigationの確認だけ。
  2. EAS Development Build: local modules、Widget、FeliCa、Live Activity、Maps等を含む日常開発。
  3. Local native build: config pluginやSwift/Kotlinの短い反復。
  4. Preview/internal: storeに近いsigning、push、widget、OTA compatibility確認。
  5. Production: EAS Build/Submit、release channel確認。

Development Buildではexpo start --dev-clientを明示する運用scriptと、端末でのmodule capability表示を用意する。Expo Goで再現できない機能を「Expo Goで動かないbug」と扱わない。

8. 最優先Native smoke

  • iOS署名済みbuildでFeliCa entitlement、scan、キャンセル、履歴、Widget App Group。
  • iOS 16.2/17系でWidget target 17.0の仕様を確認。
  • Android NFC ON/OFF、NFC非対応、permission拒否、scan成功/timeout。
  • Android notification permission、Foreground Service開始失敗、process kill、再起動。
  • clean prebuild相当でplugin適用、MainApplication guard、version/permissionが期待値になること。
  • current positionのJST/service dayとiOS/Android/WebView表示が一致すること。