- 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.
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はping、isAvailable、saveWidgetData、scanを定義し、AndroidはisAvailableとscanが主である。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.TextへallowFontScaling=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変更前にfingerprint、appVersion、custom policyを比較し、選定後も実build/update matrixで確認する。
7. 推奨Development Buildフロー
- Expo Go: 通常の純JS UIと軽いnavigationの確認だけ。
- EAS Development Build: local modules、Widget、FeliCa、Live Activity、Maps等を含む日常開発。
- Local native build: config pluginやSwift/Kotlinの短い反復。
- Preview/internal: storeに近いsigning、push、widget、OTA compatibility確認。
- 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表示が一致すること。