-
Notifications
You must be signed in to change notification settings - Fork 336
12.1 In App Purchase
SKProductsRequest Class Reference
SKPaymentTransaction Class Reference
In-App Purchase を使うとアプリ内から app store を経由してデジタルコンテンツの購入が可能となります。
デジタルコンテンツの種類は以下の用に分類されます。
|型|説明| |---|---| |Consumable|Consumable(消耗型)In-App Purchaseは、ユーザがダウンロードするたび に毎回購入する必要があります。釣りアプリケーションの餌のような一度 限りのサービスは、Consumableとして実装するのが普通です。| |Non-Consumable|Non-consumable(非消耗型)In-App Purchaseは、ユーザが1度だけ購入する 必要があります。ゲームアプリケーションの新しいレーストラックのよう に、使っても無効になったり減ったりしないサービスは、Non-consumable として実装するのが普通です。| |Auto-Renewable Subscriptions|Auto-Renewable Subscription(自動更新購読)を使用すると、ユーザは所定 の期間中に更新や動的なコンテンツを購入できます。雑誌の購読など、購 読はユーザがオプトアウトしない限り自動的に更新されます。| |Free Subscription|Free Subscription(無料購読)は、無料で購読できるコンテンツをデベロッ パがNewsstandに置くための手段です。ユーザは、Free Subscriptionにサイ ンアップすれば、Apple IDに対応するあらゆるデバイス上で購読できるよ うになります。なお、Free Subscriptionは期限切れになることがないこと、 Newsstand対応アプリケーションでのみ購読できることに注意してください。| |Non-Renewing Subscription|Non-Renewing Subscription(非更新購読)では、期間を限定したサービス を販売できます。Non-Renewing Subscriptionsは、静的コンテンツに時間 ベースでアクセスできるIn-App Purchaseに使用する必要があり、iOSアプリ ケーションでの利用できます。| iTunes Connectデベ ロッパガイド より引用
アプリケーション側で配布するプロダクトを管理する方法です。組み込み式は主に Non-Consumable プロダクトを管理するために使われます。
サーバで配布するプロダクトを管理することができます。 メリットとして、アプリの実装を変更せずに課金アイテムの内容を変更することが出来ます。 例えば、85 円でコインを購入できるプロダクトを設定した場合、85 円で購入できるコインの数をサーバで持っておけば、セールなどをするときにアプリの審査無しでフレキシブルに課金コンテンツの内容を変えることが出来ます。
サーバプロダクトタイプの場合、処理のフローが少し増えます。 サーバはアプリから購入するリクエストを受けてコンテンツをレスポンスとして返します。その際にサーバはアプリからのリクエストが本当に app store で購入を終えているのかを確認する必要があります。そのために、サーバはアプリから購入終了したレシートを受け取り、そのレシートが有効なものか apple のサーバに問い合わせ、有効であればアプリにコンテンツを配布するという処理が必要になります。
課金プロダクトを配布するには、iTunes Connect にプロダクトを登録する必要があります。
まず、アプリケーションの管理で Manage In-App Purchase へ遷移します。
その画面で Create New をクリックし、追加画面に遷移します。そこでプロダクトのタイプを選び、プロダクトの ID や値段など必要項目を入力していきます。
各項目の説明です。
|プロパティ|解説| |---|---| |Reference Name|参照名は、iTunes Connectおよび売上/トレンド報告書に表示されます。App Storeには表示されません。参照名は255バイト以内とします。参照名はいつでも編集できます。これはアプリケーション内で一意でなければなりません。| |Product ID|報告に用いる一意的な識別子。英字と数字を組み合わせて指定できます。In-App Purchaseを表す、UTF-8の英数字による一意の識別子です。このプロダクトIDは、当社のシステム中でそのアイテムを一意に識別するために指定す る、任意の英数字による文字列です(例:com.company.app_name.productid)。255文字以下のユニークな文字列を、UTF-8の英数字を使って作成します。 In-App Purchase提出後は、プロダクトIDは編集できません。また、一度任意の In-App Purchaseに使われたプロダクトIDを別のIn-App Purchaseに使用すること はできません。| |Pricing and Availability|In-App Purchaseが購入可能であるかどうか、と価格に関する情報が記載されています。| |Languages|このIn-App Purchaseのローカリゼーション情報。| |Review Notes|テスト用ユーザアカウント名とパスワードなど、Appleによる登録審査に役立 つ可能性があるIn-App Purchaseの追加情報です。Review Notesは4000バイト以 内で記載してください。| |Screenshot|審査用にのみ使われるスクリーンショット。|
開発環境で In-App Purchase をテストしたい場合、iTunes Connect でテストユーザを追加しましょう。そのユーザを使うことで、Sandbox 環境でテストが可能で、課金を行ってもお金のやり取りは発生しません。
追加方法は、まず iTunes Connect の Manage Users を選択します。
そこの Test Users を選んで、ユーザを追加します。
テストユーザを使うことで、自動更新型のコンテンツの有効期限が以下の用に縮まり、テストしやすくなります。
|実際の期間|サンドボックスにおける期間| |---|---| |1週間|3分| |1カ月|5分| |2カ月|10分| |3カ月|15分| |6カ月|30分| |1年|1時間|
ここでは組み込みでプロダクトを管理する方式の実装の流れを説明します。
Build Phases > Link Binary With Libraries から追加してください。
ユーザによっては、Setting.app の機能制限から In-App Purchase の利用を制限している可能性があります。まず、それが有効か確認をしてから購入画面を開きましょう。
MixiViewController.m
#import <StoreKit/StoreKit.h>
- (IBAction)pressLauchStore:(id)sender
{
if([SKPaymentQueue canMakePayments]){
MixiStoreViewController *storeVC = [[MixiStoreViewController alloc] init];
[self presentViewController:storeVC animated:YES completion:nil];
}else{
NSLog(@"設定で off にされてる。");
}
}
iTunes Connect で設定したプロダクトの ID をアプリ側で保持しておいて、その ID に関するプロダクト情報を App Store から取得します。SKProductsRequest, 及び SKProductsRequestDelegate を実装します。
MixiStoreViewController.h
#import <StoreKit/StoreKit.h>
@interface MixiStoreViewController : UIViewController
<SKProductsRequestDelegate>
MixiStoreViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// In-App purchase に登録してあるプロダクト情報を取得するためのリクエスト作成
NSSet *productIDs = [NSSet setWithObjects:kMixiStoreProductCosumable1ID, kMixiStoreProductNonConsumable1ID, nil];
SKProductsRequest *request= [[SKProductsRequest alloc] initWithProductIdentifiers:productIDs];
request.delegate = self;
[request start];
// 通信中のインジケータなどの実装
}
#pragma mark - SKProductRequestDelegate methods
- (void)productsRequest:(SKProductsRequest *)request
didReceiveResponse:(SKProductsResponse *)response
{
// products 情報の参照を保持
_products = response.products;
// products の内容を表示する実装
}
サンプルプロジェクトでは consumable なプロダクトと non-consumable プロダクトを一つずつ登録し、プロダクトのタイトルをボタンに表示するように実装しています。
SKPaymentTransactionObserver を実装する必要があります。まず header で protocol を採用しましょう。
MixiStoreViewController.h
#import <StoreKit/StoreKit.h>
@interface MixiStoreViewController : UIViewController
<SKProductsRequestDelegate,
SKPaymentTransactionObserver>
次に購入処理の進行状態の通知を受けるための設定をします。ここでは viewController 自身を通知先として設定しています。
MixiStoreViewController.m
//transaction の observer として登録
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
購入ボタンを押した場合、SKPaymentQueue に購入する queue を追加します。queue に追加するものは、SKProductRequestDelegate で受け取った product をもとに生成した SKpayment クラスのインスタンスです。
MixiStoreViewController.m
-(void) purchaseProduct:(SKProduct *)product
{
SKPayment *payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
最後に、transaction の状態の通知を実装します。
MixiStoreViewController.m
#pragma mark - SKPaymentTransactionOvserver methods
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for (SKPaymentTransaction *transaction in transactions){
switch (transaction.transactionState){
// 購入中
case SKPaymentTransactionStatePurchasing:
//do something
break;
// 購入完了
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
break;
// 購入失敗
case SKPaymentTransactionStateFailed:
[self failedTransaction:transaction];
break;
// リストア完了
case SKPaymentTransactionStateRestored:
[self restoreTransaction:transaction];
break;
default:
break;
}
}
}
ボタンを押すと以下のような遷移になります。
non-consumable プロダクトは一度購入すると購入された履歴が Apple ID とひも付き、アプリを再インストールした際にそのデータを復元することが出来ます。
MixiStoreViewController.m
- (IBAction)pressRestoreButton:(id)sender
{
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
購入処理が何らかの形で終了した場合、SKPaymentQueue に終了した購入処理を知らせる必要があります。これは正常に購入できた場合、キャンセルなどで購入に失敗した場合、リストアした場合の全てを含みます。これをしない限り、アプリ起動毎に購入処理が走るバグが発生するので必ず行いましょう。
MixiStoreViewController.m
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
はじめに
-
導入
-
1.3 UIViewController1 UIViewController のカスタマイズ(xib, autoresizing)
-
UIKit 1 - container, rotate-
-
UIKit 2- UIView -
-
UIKit 3 - table view -
-
UIKit 4 - image and text -
-
ネットワーク処理
-
ローカルキャッシュと通知
-
Blocks, GCD
-
設計とデザインパターン
-
開発ツール
-
テスト
-
In-App Purchase
-
付録