20120219i phonedeveloperworkshoppublished
TRANSCRIPT
StoreKitを使ってマネタイズ計画【再演】
@saku2sakusaku2saku at gmail.com
なぜStoreKitを使うか?有料アプリの販売じゃダメ?アプリダウンロード数的に厳しい市場有料と無料を比較した場合その差【約100倍】
ランキングに載らないと認知すらされないのが現実残り続けるには?デファクトアプリになるプロモーション活動
個人開発における有料アプリは難易度が上がり続ける
挑むのであれば無料アプリ内で課金モデルを確立すること
課金の種類(現実世界)買い切りモデル制限解除型コンテンツダウンロード型一回買ったらコンテンツはユーザのものになる消費アイテムモデル消費を前提としたアイテム(RPGの強い装備等)定期購読型モデル月額課金のような定期的にコンテンツを買うモデル
課金の種類(iTunes Connect上)Non-Consumable買い切りアイテムモデル
Consumable消費アイテムモデル
Auto-Renewable Subscription定期購読モデル(自動更新)
Non-Renewable Subscription定期購読モデル(非自動更新)
Free SubscriptioniOS5 からのNewsstand用、まだ未知数です(知らないw)
購入履歴の管理についてAppleのサーバに保管される/されないものがある
Appleのサーバに履歴が保管されるものNon-ConsumableAuto-Renewable Subscription自前のサーバに保管する必要のあるものConsumableNon-Renewable Subscription
サンプルアプリ
サンプルアプリの概要課金アイテムの一覧取得課金アイテムの購入履歴の表示課金アイテムの購入購入履歴情報の復元
扱うアイテムの種別はFree Subscriptionを除く4つ
テスト用のアプリの作成iTunes Connect にログインDeveloper登録が必須となります適当にアプリを登録します別に既にバイナリがある必要はないアプリができたらManage In-App Purchasesをクリック左上のCreate Newをクリック
テスト用のアプリの作成アイテムの課金タイプの選択画面になります試しに全ての種類の課金アイテムを登録してみるといいと思います
課金アイテムの情報を入力します全ての情報を入力Add Language ボタンを押すと多言語化対応したアイテムの表示名を登録できます右下のSaveボタンを押すとアイテムが登録されます
テスト用のユーザの作成iTunes Connect にログインDeveloper登録が必須となりますManage Usersを選択しますTest Userをさらに選択します左上のAdd New Userをクリック
必要な情報を入力するとAppleからメールがくるのでアカウントをアクティベーションします
操作プロジェクトファイルをダウンロードhttp://workshop.iphonework.biz/files/2012/03/20120219iPhoneDevWS_StoreKit.zipzip ファイルを解凍
プロジェクトを開きますGlobalSetting.h の ITEM_IDENTIFIER の1~5を変更しますビルドして実行しますStoreKitは「設定」->「一般設定」->「機能制限」->「App内での購入」がオンになっている状態でないと動作しません古いiOSシミュレータではシミュレータ内でアプリ課金のテストは行えないので注意してください
操作Item list を選択ネットワークアクセスが起こりアイテムの一覧が表示されるのを確認しますトップに戻るBought item list を選択購入済みアイテムのリストが表示されますこの段階ではまだ全て not yet になっています
操作Item list を選択今度は実際に課金アイテムの購入を行ってみますConsumable と Non-Consumable とAuto-Renewable Subscriptionのアイテムを購入してみましょうBought item list を選択購入済みアイテムのリストが表示されます先程購入したアイテムが bought に変わります
操作購入履歴が復元できるかの確認先程説明をしましたが、Non-Consumable とAuto-Renewable Subscriptionは購入履歴がAppleによって管理され、情報を取得できます一旦インストールされたアプリをシミュレータまたは実機から削除し、再度ビルド&実行します再度起動して Bought item list を見ると、全てnot yet となり購入履歴が消えているのがわかります
操作Restore bought item を選択Apple IDが求められるので以下を入力先程作成したテストユーザのアカウントで認証します
購入履歴の復元成功のアラートが出る再びトップに戻って Bought item list を選択一部 bought に変化しているのを確認しますbought に変化したのは以下の2つのアイテムNon-ConsumableAuto-Renewable Subscription
操作Consumable Item が not yet のままであることを確認します消費型のアイテムについてはAppleのサーバに残らないことがわかります
サンプルコードの説明
課金アイテム情報の取得ItemTableViewController- (void)viewDidLoad {! if ([SKPaymentQueue canMakePayments]) { ・・・・! !! ! NSSet *itemIdentifiersSet = [NSSet setWithObjects:! ! ! ! ! ! ! ! ! ITEM_IDENTIFIER_1,ITEM_IDENTIFIER_2,! ! ! ! ! ! ! ! ! ITEM_IDENTIFIER_3,ITEM_IDENTIFIER_4,! ! ! ! ! ! ! ! ! ITEM_IDENTIFIER_5,! ! ! ! ! ! ! ! ! nil];! ! SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:itemIdentifiersSet];! ! request.delegate = self;! ! [request start];! } else {! ! UIAlertView *alertView = [[[UIAlertView alloc] init] autorelease]; ・・・! ! [alertView show];! }}
課金アイテム情報の取得ItemTableViewControllerリクエスト完了後に呼ばれるデリゲートを実装
#pragma mark -#pragma mark SKProductsRequestDelegate
- (void) productsRequest:(SKProductsRequest *)request! didReceiveResponse:(SKProductsResponse *)response {! for (SKProduct *product in response.products) {! ! [itemIdentifiers addObject:product];! }! [request autorelease];! [loadingView removeFromSuperview];! [self.tableView reloadData];}
課金アイテムの購入iPhoneDevWS_StoreKitAppDelegateProductBuyingObserverメソッドの実装
observer = [[ProductBuyingObserver alloc] init];! [[SKPaymentQueue defaultQueue] addTransactionObserver:observer];
! [[SKPaymentQueue defaultQueue] addTransactionObserver: self];
or
課金アイテムの購入ItemTableViewCellアイテムの購入処理
- (void) pushBuyButton {! LOG_DEBUG(@"buy :%@", itemIdentifier);! SKPayment *payment = [SKPayment paymentWithProductIdentifier:itemIdentifier];! [[SKPaymentQueue defaultQueue] addPayment:payment];}
課金アイテムの購入- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {! for (SKPaymentTransaction *transaction in transactions) {! ! switch (transaction.transactionState) {! ! ! case SKPaymentTransactionStatePurchasing: !//購入中! ! ! ! break;!! ! !! ! ! case SKPaymentTransactionStatePurchased: !//購入完了! ! ! ! break;! ! ! case SKPaymentTransactionStateFailed: !//購入失敗! ! ! ! break;! ! ! case SKPaymentTransactionStateRestored: !//リストア完了! ! ! ! break;! ! ! default:! ! ! ! break;! ! }! }}
課金アイテムの復元RootViewControllerProductBuyingObserverデリゲートの設定とメソッドの実装
! ! case 2:! ! {! ! ! if ([SKPaymentQueue canMakePayments]) {! ! ! ! [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;! ! ! ! [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];! ! ! } else {! ! ! ! UIAlertView *alertView = [[[UIAlertView alloc] init] autorelease]; ・・・! ! ! ! [alertView show];! ! ! }
! ! ! break;! ! }
課金アイテムの復元- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {! for (SKPaymentTransaction *transaction in transactions) {! ! switch (transaction.transactionState) {! ! ! case SKPaymentTransactionStatePurchasing: !//購入中! ! ! ! break;!! ! !! ! ! case SKPaymentTransactionStatePurchased: !//購入完了! ! ! ! break;! ! ! case SKPaymentTransactionStateFailed: !//購入失敗! ! ! ! break;! ! ! case SKPaymentTransactionStateRestored: !//リストア完了! ! ! ! break;! ! ! default:! ! ! ! break;! ! }! }}
課金アイテムの復元復元成功のデリゲート
- (void) paymentQueueRestoreCompletedTransactionsFinished: (SKPaymentQueue *) queue {! [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; ・・・! [alertView show];! LOG_DEBUG(@"method called!");}
復元失敗のデリゲート- (void) paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *) error {! [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; ・・・! [alertView show];! LOG_DEBUG(@"method called!");}
その他TIPS
レシートデータトランザクションにはレシートデータが含まれており、その「purchase-info」をさらにデコードすることで様々なデータを取得できます
{! "signature" = "AkWUo・・・";! "purchase-info" = "ewoJI・・・";! "environment" = "Sandbox";! "pod" = "100";! "signing-status" = "0";}
レシートデータAppleのサーバに保管されないような購入アイテムの記録を取りたい場合にはこのレシートの情報を自分のサーバに保管する必要があります
{! "item-id" = "471702051";! "original-transaction-id" = "1000000010942512";! "purchase-date" = "2011-10-23 07:15:02 Etc/GMT";! "product-id" = "com.comitter.sampleapp.sample3";! "transaction-id" = "1000000010942512";! "quantity" = "1";! "original-purchase-date" = "2011-10-23 07:15:02 Etc/GMT";! "bid" = "com.comitter.sample2";! "bvrs" = "1.0";}
ご清聴ありがとうございました