StoreKitと闘う

iOSアプリの売り上げの72%はアプリ内課金から来ている」(このタイトルは若干誇張されていて、正確には「iOSアプリの売り上げの72%はアプリ内課金を搭載したアプリから発生したもの」です)というニュースがあるほど、近年アプリ内課金の存在は大きなものとなってきました。iOSの場合は規約の関係からアプリ内課金を実現する場合にはStoreKitを使うことになりますが、このStoreKitがなかなかの曲者で、僕は未だに取り扱いに苦労しています。

StoreKitの概要

  1. iOSアプリでアプリ内課金を実現するための唯一のフレームワーク
  2. iOS 3.0で初登場
  3. OS X 10.7 LionからMacでも使えるようになった

ポイントは1で、AppStoreの規約上iOSアプリでアプリ内課金を実現する方法は事実上StoreKitを使う以外にありません。iOS 3.0で登場し、現在はOS X 10.7 Lion以降であればMacアプリでも使えます(ただし、Mac App Storeで配信してるアプリのみ)。

StoreKitの特徴

  1. Apple IDの認証(ダイアログ表示したり諸々)をやってくれる
  2. 購入のトランザクションを管理してくれる
  3. アプリと別のサイクルで動作する
  4. ブロック構文ではなくデリゲートを使ったやり取り
  5. 結構ブラックボックスな部分が大きい

お金が絡む重要な機能なので、不正が起きないように、情報が漏洩しないように、またトランザクションが途中で失敗したりしないように、という部分の面倒を見てくれることは、自前でこれらの対策を考えてゼロから実装することに比べれば喜ばしいことです。厄介なのは3以降の特徴です。
StoreKitの実際の決済等の処理は、アプリケーションの外側(おそらく別のプロセス上)で行われるようです。試しに、アプリケーションからプロダクト購入のリクエストを出して、決済手続きが始まった状態でアプリケーションを終了すると、アプリケーションが終了した後にも関わらず購入確認のダイアログが表示されることで確認できます。これはトランザクションが途中で失敗してしまった場合のことを考えれば当然だとは思うのですが、アプリケーション側ではこの点を十分に注意していないと実装していかないと少し困った事になります。(後で詳しく検証していきます)
StoreKitはアプリケーションとは別に動作するし、そもそも購入手続きはサーバーとの通信を伴うものなので、StoreKitのAPIも必然的に非同期のものが主となります。iOS 4.0でブロック構文が登場して以降、非同期的な処理を含む様々なOSフレームワークのAPIがブロック構文に対応し、非常に便利になってきたのですが、なぜかStoreKitはブロック構文には対応していません。OS XのLionでStoreKitが搭載されるというニュースがあったときに「いよいよブロック対応するか」と期待していたのですが、残念ながらそのままでした。これも後ほど検証していきますが、StoreKitはデリゲート故に扱いに注意しなければいけない部分があります。
一番厄介な部分は最後の項目です。StoreKitはAPIが少なく、また公式ドキュメントも分量がそこまで多いものではないため、細かい部分の仕様や内部的な挙動がよくわからない時が時々あります。公開されている情報が少ないのはセキュリティ的な都合があるのかもしれませんが、特に異常系の実装をするにあたって、仕様/挙動がわからなくて奔走してしまうことがよくあります。
ネット上の情報をあたっていると、同じようにStoreKitで苦労している人は多いみたいなので、ここ1年くらいで自分が学んだ情報やテクニックを少し書いておこうと思います。
まずは、StoreKitを使った基本的な決済の流れの確認から。

Pocket

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です