Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

日経電子版のStoreKit2フルリニューアル

Go Takagi
November 21, 2024

 日経電子版のStoreKit2フルリニューアル

Go Takagi

November 21, 2024
Tweet

More Decks by Go Takagi

Other Decks in Technology

Transcript

  1. Me ( Go Takagi ) ‣ID • bento.me/shimastripe ‣Work •

    日 本経済新聞社 アプリチーム ‣ 日 経電 子 版 ・ 紙 面 ビューアーアプリを中 心 にリード ‣Like • Swift / 自 動化 / 柴 犬 2 #nikkei_tech_talk
  2. Agenda ‣アプリ内課 金 、StoreKit 2 移 行 した話 • 日

    経アプリのサブスクリプションでできるようになったこと • より正確に!柔軟に!課 金 ステータスを反映! ‣iOSDC で話しきれなかったエピソードを中 心 • iOSDC ではバックエンド及び ID システムとの連携を話しました • 今回は特にクライアント編です • 結構にっちな問題もせっかくなので共有します 3 #nikkei_tech_talk
  3. アプリ内課 金 ‣StoreKit SDK • クライアントアプリで課 金 を実 行 できる

    SDK • V 1 / V 2 (iOS 15 +) があり、V 1 の API が 2024年6 月 deprecated に • 5 https://developer.apple.com/jp/videos/play/wwdc 2 02 4 / 1 0 0 62 / #nikkei_tech_talk
  4. App Store Server API ‣App Store Server API • ユーザーの課

    金 情報をバックエンドで取得できる API ‣App Store Server Noti fi cations • 課 金 情報の Update が App Store から届くリアルタイムプッシュ通知 6 https://developer.apple.com/jp/videos/play/wwdc 2 02 4 / 1 0 0 62 / #nikkei_tech_talk
  5. V 2 は個別にアップデート可能 7 V 1 V 2 Client StoreKit

    StoreKit 2 Backend App Store Receipts API App Store Server API Backend App Store Server Noti fi cation V 1 App Store Server Noti fi cation V 2 #nikkei_tech_talk
  6. V 2 は個別にアップデート可能 8 V 1 V 2 Client StoreKit

    StoreKit 2 Backend App Store Receipts API App Store Server API Backend App Store Server Noti fi cation V 1 App Store Server Noti fi cation V 2 #nikkei_tech_talk
  7. V 2 は個別にアップデート可能 9 V 1 V 2 Client StoreKit

    StoreKit 2 Backend App Store Receipts API App Store Server API Backend App Store Server Noti fi cation V 1 App Store Server Noti fi cation V 2 #nikkei_tech_talk
  8. V 2 は個別にアップデート可能 1 0 V 1 V 2 Client

    StoreKit StoreKit 2 Backend App Store Receipts API App Store Server API Backend App Store Server Noti fi cation V 1 App Store Server Noti fi cation V 2 #nikkei_tech_talk
  9. 横向きに共存する購 入 フローは避ける 1 1 V 1 V 2 Client

    StoreKit StoreKit 2 Backend App Store Receipts API App Store Server API Backend App Store Server Noti fi cation V 1 App Store Server Noti fi cation V 2 #nikkei_tech_talk
  10. iOSDC 20 24 ‣StoreKit 2 + App Store Server API

    + Noti fi cationsを学ぶ • 動画をチェック!▶ 1 2 https://speakerdeck.com/shimastripe/inapppurchase https://www.youtube.com/watch?v=c 3 Lob-XDwHM #nikkei_tech_talk
  11. トークして...... ‣嬉しいフィードバックをたくさんいただけた • バックエンド側を加味した話はほとんどなくて助かった! • クライアント側の対策も何したかやっぱり聞きたい • ただの移 行 だと...

    工 数を取れなくて...という話も😭 ‣みなさまの StoreKit 2 移 行 を促進できるように 💪 • クライアント側の移 行 話やビジネス的にも嬉しい改善等を話します 1 3 #nikkei_tech_talk
  12. StoreKit 2 (iOS 1 5 +) ‣iOS 15 + から

    V 2 に • 2024年6 月 V 1 の API が deprecated に ‣API が 一 新 • 非 同期処理の刷新。Observer パターン → Swift Concurrency に • API 刷新に伴い、アプリ内課 金 と外部導線経由の課 金 が明確に区別できるように ‣JWS Transaction を 用 いた改ざん検証 方 法に刷新 • 従来のレシートを 用 いた verifyReceipt() は deprecated • 現在の課 金 状態や有効 Transaction の取得を端末で好きなタイミングで可能に 1 5 #nikkei_tech_talk
  13. API の変化 ‣StoreKit 1 • Observer パターン • Transaction の更新通知を購読してハンドリング

    • Transaction の情報と前後のコンテキストで状況を判断 1 6 extension TransactionObserver: SKPaymentTransactionObserver { func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { // ౉ͬͯ͘Δ transactions ͷঢ়ଶΛݟ֤ͯछϋϯυϦϯάΛߦ͏ } } #nikkei_tech_talk
  14. StoreKit 2 の場合 ‣ユーザーの直接操作による購読 • await してそのまま取得可能 ‣ユーザーの直接操作でない 外部起因の継続的なUpdateEvent •

    AsyncSequence を購読 • サブスクリプションの更新 • オファーコード • 他端末経由の購 入 etc... 1 7 let result = try await product.purchase() switch result { case let .success(verificationResult): switch verificationResult { case .verified(let signedType): // վ͟Μ͞Ε͍ͯͳ͍͜ͱΛ֬ೝ case let .unverified(_, verificationError): } case .pending, .userCancelled: } Task { for await verificationResult in Transaction.updates { switch verificationResult { ... } } }
  15. 改善: 課 金 状態の 自 動復元 ‣課 金 状態のリフレッシュを好きな時にできる •

    機種変 ・ 別端末での購 入・ アプリ再インストールからの復帰 等 • (外部動線購 入 後の) アプリ 立 ち上げ時 • オファーコードを利 用 した AppStore の購 入 • V 1 は基本復元操作の実 行 が求められた..... • V 2 からは柔軟かつ安全に取得可能 • 他の決済 手 段との 二 重課 金 防 止 にも繋げられる • 二 重課 金 発 生 時の特定や通知も可能 1 9 #nikkei_tech_talk 自 動復元されてほとんど使 用 されなくなる
  16. 改善: お試しオファーの利 用 資格を正確に提 示 ‣ Product.SubscriptionInfo.isEligibleForIntroO ff er(for:groupID) •

    お試し体験資格の有無で表 示 を変える • お試し体験済みユーザーの意図せぬ再購 入 を防 止 する 2 0 #nikkei_tech_talk OSの購 入 ダイアログにも明記されて いるが 見 落としやすい 初回お試し可能 お試し済みで有料スタート
  17. オファーキャンペーン ‣サブスクリプションオファー • アプリ内で提 示 するパターン • AppStore 経由で適 用

    するパターン ‣アプリ外購 入 ハンドリングが簡単に • 外部経由の購 入 の通知受信 • アプリ起動時に課 金 機能の 自 動復元 • 従来は復元操作の説明等必要だった 2 1 #nikkei_tech_talk
  18. 他にも: 新機能は StoreKit 2 に整備されていく ‣新しいオファーキャンペーンの提供 • Win-back o ff

    er (iOS 1 8 +) • 過去に購読して退会したユーザーを条件指定して出せるオファー ‣購 入 画 面 を SwiftUI で 高 速実装 (StoreKit views) • StoreView: 複数商品 • ProductView: 単 一 商品 • SubscriptionStoreView: サブスクリプション 2 2 #nikkei_tech_talk https://developer.apple.com/jp/videos/play/wwdc 2 02 4 / 1 0 1 10
  19. 最も重要: Test fl ight で動作確認を必ずする ‣本番になるべく近い状態のバイナリで 見 ておく • ローカルビルドと

    Test fl ight (+ Store) で振る舞いがそこそこ違う... 2 5 #nikkei_tech_talk 検証設定 StoreKit Con fi guration ローカルビルド TestFlight (審査提出ビルド) AppStore (Production) 課 金 機能の Environment Xcode Sandbox Sandbox Production 署名 方 法 Xcode AppStore AppStore AppStore https://developer.apple.com/jp/documentation/storekit/in-app_purchase/testing_at_all_stages_of_development_with_xcode_and_sandbox/
  20. V 1 →V 2 切り替え直後 課 金 状態の復元(currentEntitlement) が反映されない ‣有料ユーザーが無料状態になってしまうユーザーが出現

    • AppStore.sync() 等しても解決しない...... • アプリを 一 度 立 ち上げ直したりすると取得できたり、( 一 応) 短期的な事象 ‣再現 方 法 • Test fl ight アプリで V 1 課 金 した状態で V 2 にアップデートする • 復元して課 金 状態を維持しようとしてみると商品を取得できない ‣対策 • V 2 で復元できないが、V 1 のレシートが存在する場合は V 1 の fl ow に Fallback した • 共存 自 体はあくまで、V 1 と V 2 の API で独 立 させたフローになっていれば問題ない 2 6 Test fl ight Problem https://developer.apple.com/documentation/storekit/appstore/ 3 791 9 06 -sync
  21. 課 金 前は Un fi nished Transaction を 明 示

    的に確認しておく ‣Transaction.updates を購読して対処はしているが...... • 降ってこないまま Un fi nished Transaction が残る挙動が発 生 ‣購 入 API (purchase) は Un fi nished Transactionをまず返す • 本来: 購 入 ダイアログが出て → 承認 → 有効な Transaction を受け取る想定 • Un fi nished でも有効なものなら再度連携できる • が、既にExpiredされてる古い Transaction が降ってきて、失敗...も起こってしまう • 購 入 に進む画 面 表 示 時、適宜 Transaction.un fi nished を確認 • 直前にチェックしておくタイミングがあると予期せぬ挙動を減らせる 2 7 Test fl ight Problem
  22. オファーコードの受信は遅いことがある ‣オファーコードは外部経由の課 金 • AppStore で購 入 してからアプリに来るため、課 金 復元して通知したい

    • アプリ内でコード 入 力 シートを出せるが、あくまで外部扱いで降ってくる • Transaction.updates に通知される ‣購 入 直後、即座にイベントが降ってくるときもあれば、遅い時も...... • 遅い場合は課 金 の復元を実 行 すれば解決する • アプリ内で利 用 する場合は、引き続き「復元押してね」の説明はした 方 がいい • Store 版でしか検証できないため、なかなか 大 変でした...... 2 8 Store Only https://developer.apple.com/documentation/storekit/appstore/ 3 954 4 31 -presento ff ercoderedeemsheet
  23. 課 金 管理シートを利 用 して、課 金 の向き先を確認 ‣アプリ内でサブスクの管理が可能になる Sheet API

    • 本来の 用 途はユーザー向けだが、開発でも有 用 • 今のバイナリが向いている環境の購読状態を表 示・ 管理可能! 3 1 #nikkei_tech_talk https://developer.apple.com/documentation/storekit/appstore/ 3 80 3 19 8 -showmanagesubscriptions
  24. StoreKit Views を利 用 して爆速動作確認 ‣怪しい振る舞いの検算に利 用 • 簡素な実装で課 金

    シールドを実装 • 動作確認に 十 分使える • 新規実装の場合は最初からこれで! 3 2 #nikkei_tech_talk https://developer.apple.com/jp/videos/play/wwdc 2 0 24 / 1 0 06 1
  25. Transaction.updates は遠隔制御できるように ‣課 金 の問題はリリースなしで対処したい • 特に不安だったのが Transaction.updates の予期せぬ振る舞い •

    緊急時遠隔でハンドリングするか調整できるように • 自 社の API や Firebase Remote Con fi g あたりを検討 • 想定していないタイミングで受信していないか • トランザクションマネージャー通りに来るのか • どうイベントを分けたか • 種類: PURCHASE / RENEWAL • 状態: ACTIVE / EXPIRED / REVOKE 3 3 #nikkei_tech_talk
  26. StoreKit Con fi guration を 用 いたローカル課 金 ‣AppStoreConnect の設定なしで課

    金 できる。便利! • AppStoreServerLibraryの改ざん検証に Xcode Environment を指定 • ただし、これは内部的には検証無しで Pass しているだけに注意 • バックエンドに送る場合は扱いに気を付ける 3 4 App Store Server Library https://developer.apple.com/jp/documentation/storekit/in-app_purchase/testing_at_all_stages_of_development_with_xcode_and_sandbox/
  27. StoreKit Test と swift-testing の相性が悪い ‣SKTestSession を複数スレッドや連続実 行 すると頻繁に内部クラッシュ •

    testing はデフォルト並 行 テスト • パラメタライズテストも書きやすく、結果フレークな失敗が増加します ‣対策 • Test に関する並 行 実 行 • testing に @Suite(.serialized) を指定することで直列実 行 にできる • API に関する連続実 行 • 意図的に SKTestSession の各種 API 実 行 後 wait をつけて物理的な対策で対処... • Qiita に詳細な調査知 見 が共有されています • 「StoreKitTest によるアプリ内課 金 テストの連続実 行 で失敗するケースの検証」 3 5 #nikkei_tech_talk https://developer.apple.com/jp/xcode/swift-testing https://qiita.com/manicmaniac/items/ec 1 9 fb 83 1 7 2ff2 fd 16 d 7
  28. まとめ ‣ 日 経電 子 版のアプリ内課 金 フルリプレース • 移

    行方 針に加えて、改善された UX 周りも紹介 • こういう改善はAPI に精通しているエンジニア側から積極的に働きかけています ‣アプリ内課 金 は集合知の積み重ね • 要件に合わせて「 自 分たちはこうした」知 見 の共有の重要性 • 特に知 見 がなくて困った要素を中 心 に紹介しました! • みんなでStoreKit 2 にいきましょう! • 発表以外にも困ったらぜひ相談してください。わかる範囲で答えます 3 7 #nikkei_tech_talk