53
53

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

アプリ内課金のレシートは1つのバイナリになる

Last updated at Posted at 2013-12-10

最近気づいたんだけど、iOSで使われるアプリ内課金(In-App Purchase)では複数の課金をしてもそれぞれにレシートのバイナリができるわけではなく、複数まとめて1つのバイナリになっている。

もしかしたら同じような勘違いをしている人もいるかもしれない。そうするとサンプルコードが全然違って見えるよという話です。

Appleの公式リファレンスであるレシート検証プログラミングガイド PDFによるとレシートの構造はこんな感じらしい。

レシートの構造.jpg

(ちなみにこの図のタイトルはレシートの構造のはずなのに後続と訳されていた)

iOS7より前ではtransactionReceiptがNSDataで取得できるので、アイテムごとにレシートが作られているのかと思っていた。コードとしては次のような感じ

//このメソッドはオリジナルで
- (void)finishTransaction:(SKPaymentTransaction *)transaction
{
    //iOS6など
    //NSData *receiptData = transaction.transactionDate; //非推奨になった

    //iOS7から
    NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
    NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
   
   //...ここでレシートの検証やコンテンツの適用などを行う...//
}

iOS7のやり方ではローカルの場所をURLとして取得するだけで、その場所はトランザクションごとに変わっているわけでもない。うちの実機だと下記のような場所がURLとなる。

file:///var/mobile/Applications/<何かのUUID>/StoreKit/receipt

おそらくiOS7からレシートのバイナリが一つになったわけではないんだろうけど、iOS6以前はtransactionに対してレシートデータが取得できるおかげで変な勘違いをしていた。

ただ、iOS7からレシートはappStoreReceiptURLメソッドで取得できるので、ローカル検証したいときなど特にSKPaymentTransaction経由で取得しなくて良くなったよってことなんだろう(おそらくローカル検証自体もiOS7より前でも出来る、はず)。

日本語に訳されたドキュメントを読んでもイマイチぴんとこなかったんだけど、プロパティを非推奨にしてくれたおかげで勘違いから解放された。

53
53
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
53
53

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?