Repository navigation
feat: iOS版の「使い方」にバージョンを表示し、PNG・PDFの保存後にApp Storeの評価を依頼する - #121
Conversation
…xports iOS版の「使い方」の末尾に、Info.plistから渡したバージョンとビルド番号を表示する。 PNG・PDFの保存・共有を終えた区切りでだけ、条件を満たすとStoreKitのシステムの 依頼画面で評価を依頼する。条件はios/docs/NATIVE_BRIDGE.mdに書いた。 Refs #84 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
K0mork
left a comment
There was a problem hiding this comment.
レビュー(CIの結果と確認したこと)
CI(run 37465916953、head 043767f)
すべて成功し、ci-gate も成功しました(web は Web 版の変更が無いため skip)。
ios (iPhone 17)・ios (iPad (A16)): 単体テスト46件(既存の機内モード用1件 skip)、UIテスト18件(既存の5件 skip)が成功。手元で通せなかったtestGuideNavigationReturnsToUsableEditorは両端末で passed で、追加したバージョン表示の確認も通っています。追加したReviewRequestPolicyTests(8件)・ReviewRequestTrackerTests(8件)・AppVersionInfoTests(4件)も両端末で成功。app_update (iPhone 17)・app_update (iPad (A16))・release_archive(Release Archive とcheck-release-assets.sh)・ios_web・app_store_docs・changes・CodeQL: 成功。
確かめて問題が無かった点
- バージョン・ビルド番号は Info.plist から読み、JSON として
WKUserScript(文書の読み込み開始時・メインフレームだけ)で渡しており、通信なしで表示できる。ページ側はtextContentで表示し、値が無い・不正なときはhiddenのまま。Web 版(Pages)の使い方ページは変わっていない。 - 評価の依頼は
AppStore.requestReview(in:)だけを使い、独自の評価ダイアログやボタンは無い(App Review Guidelines 5.6.1 に沿う)。iOS 17 以上の対象なので API の可用性も問題ない。 - 判定は Document Picker の保存完了と共有シートの
completed == trueでだけ行われ、取り消し・.knit(application/gzip)・編集途中・起動直後(初回起動から3日未満)は対象外。待機後に再判定し、前面で他の画面が出ていないことも確かめている。 - UIテストは PNG・PDF の書き出しを警告の「キャンセル」で閉じるため回数が増えず、UIテストの保存操作を邪魔しない(PR本文の懸念は CI では起きない)。
project.pbxprojはxcodegen generateの出力と一致(差分なし)。docs/dev-log/のエントリは書式どおりで、件数(Swift 20件など)も CI の結果と合っている。差分・PR本文・コミットメッセージに App ID やチームIDなどの機密情報は無く、Refs #84とenhancementラベルがある。
直すべき点
-
【高】Privacy Manifest に UserDefaults の利用理由が無い: このPRで初めてアプリが
UserDefaultsを使うようになりましたが、ios/App/PrivacyInfo.xcprivacyのNSPrivacyAccessedAPITypesは空のままです。UserDefaultsは Apple の「理由の申告が必要な API」に当たり、申告が無いと App Store Connect へのアップロード時に ITMS-91053(Missing API declaration)となり受け付けられません。CI の Archive は署名・アップロードをしないため検出できていません。次の項目を足してください。<key>NSPrivacyAccessedAPITypes</key> <array> <dict> <key>NSPrivacyAccessedAPIType</key> <string>NSPrivacyAccessedAPICategoryUserDefaults</string> <key>NSPrivacyAccessedAPITypeReasons</key> <array><string>CA92.1</string></array> </dict> </array>
あわせて dev-log に追記し、可能なら
check-app-bundle.shなどで「UserDefaultsを使うなら申告がある」ことを検査すると再発を防げます。 -
【低】公開のプライバシーポリシーとの整合: アプリ内の「使い方」には評価の依頼について追記されましたが、
ios/docs/PRIVACY_POLICY.md(「端末内での保存」)には、評価の依頼の判定のために書き出しの回数と日時を端末内に記録すること(外部へは送らない)が書かれていません。App Store に登録するポリシーと内容を揃えるため、一文足すことを勧めます。
利用者の判断が必要な点
- #84 の残り(「使い方」に App Store のレビューを書くページへのリンクを置くか)は App ID が決まるまで未決定です。このため
ClosesではなくRefsのままで妥当です。 - 依頼画面が実際に表示されることの確認(開発ビルドの Simulator で
reviewRequest.firstLaunchDateを3日以上前にして PNG・PDF を3回保存)はまだ行われていません。TestFlight では表示されないため、確認するなら Simulator か開発ビルドの実機で行う必要があります。
マージはしていません。
…reason APIs 評価の依頼の判定で使うUserDefaultsを、Privacy Manifestに理由CA92.1で申告する。 check-app-bundle.shで、アプリが使う理由の申告が必要なAPIに申告があることを検査する。 プライバシーポリシーに、評価の依頼のための記録を端末内にだけ置くことを足す。 Refs #84 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
レビュー指摘の修正(
|
…ew-request Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep both sides in WebViewContainer.swift: the launch colors and loading style from #118, and the menu command state and native UI flag from #125. The share sheet completion now clears the native UI flag and reports the finished export for the review request (#121). Regenerate project.pbxproj with XcodeGen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
マージ後の確認です。
|
変更内容
Info.plistのCFBundleShortVersionString・CFBundleVersionを読み(ios/App/AppVersionInfo.swift)、WKUserScriptでwindow.knittingEditorAppInfoとして同梱ページへ渡します。通信せずに表示でき、Web資産へバージョンを書き込まないので、MARKETING_VERSION・CURRENT_PROJECT_VERSIONを上げるだけで表示も変わります。値が無いとき(ブラウザで開いたときなど)は欄を隠したままにします。「サポート」に、不具合の報告へバージョンを添えるよう一文を足しました。AppStore.requestReview(in:))だけを使います(ios/App/ReviewRequest.swift)。PNG・PDFを「ファイルに保存」で保存し終えたとき、または共有シートで共有を終えたときにだけ判定し、条件を満たすと1秒待ってから依頼します。条件はios/docs/NATIVE_BRIDGE.mdの「App Storeの評価の依頼」に書きました。「プライバシー」に、評価の依頼が出ることがあり編み図は送られない旨を足しました。決めたこと
Issueの本文とAppleのガイドライン(App Review Guidelines 5.6.1、システムの依頼画面を作業の区切りで出す)に沿って、控えめな条件にしました。
.knitの書き出し、編集の途中、起動直後には出さないUserDefaults(reviewRequest.で始まるキー)だけに置きます。https://apps.apple.com/app/id<App ID>?action=write-review)へのリンクは、App IDがリポジトリや公開情報から確定できないため置いていません。[P1] アプリ内にバージョンを表示し、App Storeの評価を依頼する #84 にコメントで残しました。このためClosesではなくRefsにしています。実行した確認
tsc -p tsconfig.app.json --noEmit)とテスト(vitest run --config vite.config.ts、4ファイル13件。guideVersion.test.tsを追加): 成功npm run typecheck、npm test(26ファイル159件): 成功ios/scripts/check-app-store-docs.sh: 成功xcodegen generate --spec ios/project.yml、Xcode 27.0でSimulator向けbuild-for-testing: 警告なしで成功。できたアプリにios/scripts/check-app-bundle.sh: 成功ReviewRequestPolicyTests・ReviewRequestTrackerTests・AppVersionInfoTestsの20件: 成功guide/index.htmlにwindow.knittingEditorAppInfoを与え、PlaywrightのWebKitで幅390px・1024pxに表示して、フッターに「バージョン 1.0(ビルド 1)」が出て横にはみ出さないことを確認できなかった確認
testGuideNavigationReturnsToUsableEditor(使い方ページの末尾のバージョン表示の確認を追加)は手元で通せていません。手元の負荷が非常に高く、1回目は「使い方」のタップで画面が切り替わらず、追加した確認より前の待ち合わせで失敗し、2回目はテストランナーが起動中に停止しました。このUIテストとSimulatorの一式(iPhone・iPad)、アプリ更新テスト、Release ArchiveはこのPRのCIで確かめます。reviewRequest.firstLaunchDateを3日以上前に書き換えてPNGかPDFを3回保存すると確認できます。TestFlightでは表示されません。npm run build・npm run check:dist・npm run test:e2eは実行していません。手元のNode.jsは26(指定は24)です。懸念
reviewRequest.firstLaunchDateが3日以上前になると、XCUITestで何度もPNG・PDFを保存するうちに開発ビルドの依頼画面が出て、UIテストの邪魔をするおそれがあります。CIは毎回新しいSimulatorなので出ません。WebViewContainer.swiftとproject.pbxprojを変えています。後から入る側でxcodegen generateの再実行が必要になる場合があります。レビューでの修正(2026-10-07)
UserDefaultsを使うため、ios/App/PrivacyInfo.xcprivacyのNSPrivacyAccessedAPITypesにNSPrivacyAccessedAPICategoryUserDefaults(理由CA92.1)を足しました。ios/AppのSwiftを調べ、ほかの申告対象(ファイルのタイムスタンプ、起動時刻、ディスク容量、有効なキーボード)は使っていないことを確かめました。ios/scripts/check-app-bundle.shが、アプリの実行ファイル(Debugでは*.debug.dylibも)の取り込むシンボルと文字列から申告対象のAPIの利用を調べ、理由つきの申告が無ければ失敗するようにしました。CIのiosジョブと、check-release-assets.sh経由でrelease_archiveジョブで動きます。ios/docs/PRIVACY_POLICY.mdの「端末内での保存」に、評価の依頼の時期を判断するための記録(初めて起動した日時、PNG・PDFを保存・共有した回数、最後に依頼した日時とバージョン)を端末内にだけ置き、外部へ送らないことを足し、改定日を更新しました。ios/docs/APP_STORE_CHECKLIST.mdにも申告と検査を書きました。plutil -lint、xcodegen generate(project.pbxprojに差分なし)、Xcode 27.0でのSimulator向けbuild-for-testingとcheck-app-bundle.sh、Release構成の署名なしArchiveとcheck-release-assets.shが成功。Privacy Manifestを修正前の空のもの・理由が空のもの・別の種類だけのものに差し替えたアプリでは、どちらの検査もUserDefaultsの申告漏れとして失敗することを確かめました。check-app-store-docs.shも成功。Simulatorのテスト一式はCIで確かめます。Refs #84
🤖 Generated with Claude Code