新規利用登録停止のお知らせ
平素よりSamurai Smartphone Servicesをご利用いただき、誠にありがとうございます。
この度誠に勝手ながら、事業の運営見直しにより、
Samurai Smartphone Servicesは新規利用登録を停止しております。
今後の詳細につきましては追ってご連絡いたします。
ご迷惑をおかけしますが、ご理解いただきますようお願い致します。
- 2013年05月20日
- SamuraiSmartphoneServices, 未分類
HOME > CONIT Labs.
平素よりSamurai Smartphone Servicesをご利用いただき、誠にありがとうございます。
この度誠に勝手ながら、事業の運営見直しにより、
Samurai Smartphone Servicesは新規利用登録を停止しております。
今後の詳細につきましては追ってご連絡いたします。
ご迷惑をおかけしますが、ご理解いただきますようお願い致します。
こんにちは、いちかわです。
前回のエントリで少し書いたサンプルをgithubに公開しました。
注)
最低限の目的を達成するだけのものなので、レシートの検証とか、大事なことが色々抜けています。
あくまで参考程度として見てもらえればと思います。
サンプルアプリは、
の2つの画面で構成されています。
iTunes Connectに登録したプロダクトIDの一覧を取得するようなAPIが見当たらなかったので、プロダクトの情報をplistに登録してその内容を表示することで画面を作成しています。
随時プロダクトが追加されるようなアプリの場合、プロダクト一覧をサーバから配信するようにしないと、コンテンツが増えるたびにアプリのアップデートが必要になりそうですね。
一覧で選択されたプロダクトの情報を、AppStoreから取得して表示します。
「購入」ボタンをタプすると、購入処理が行われ、プロダクトをダウンロードして、画面の下部に表示します。
「購入」ボタンをタップすると、SKPaymentQueueのaddPaymentで購入の手続きが開始されます。
1 2 3 4 5 6 |
// オブザーバ登録
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
// 購入リクエスト
SKPayment *payment = [SKPayment paymentWithProduct:<SKProduct>];
[[SKPaymentQueue defaultQueue] addPayment:payment]; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
// 購入処理オブザーバ
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for (SKPaymentTransaction *transaction in transactions) {
switch (transaction.transactionState) {
// 購入成功
case SKPaymentTransactionStatePurchased: {
[self successPayment:transaction.payment.productIdentifier receipt:transaction.transactionReceipt];
if (transaction.downloads && transaction.downloads.count > 0) {
// コンテンツのダウンロード有り
[[SKPaymentQueue defaultQueue] startDownloads:transaction.downloads];
}
else {
[queue finishTransaction:transaction];
}
break;
}
// 購入失敗(キャンセル含む)
case SKPaymentTransactionStateFailed: {
[self failedPayment:transaction];
[queue finishTransaction:transaction];
break;
}
// 購入履歴復元
case SKPaymentTransactionStateRestored: {
if (transaction.downloads && transaction.downloads.count > 0) {
// コンテンツのダウンロード有り
[self restoreItem:transaction.payment.productIdentifier receipt:transaction.transactionReceipt];
[[SKPaymentQueue defaultQueue] startDownloads:transaction.downloads];
}
else {
[queue finishTransaction:transaction];
}
break;
}
}
}
} |
transactionStateが SKPaymentTransactionStatePurchased(購入成功)となったら、トランザクションのdownloadプロパティにダウンロード可能なプロダクトの情報が含まれているので、13行目のSKPaymentQueueのstartDownloadsメソッドに情報を渡してダウンロードを実行します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
- (void)paymentQueue:(SKPaymentQueue *)queue updatedDownloads:(NSArray *)downloads
{
for (SKDownload *downloadItem in downloads) {
switch (downloadItem.downloadState) {
case SKDownloadStateWaiting: {
NSLog(@"Download is inactive, waiting to be downloaded");
break;
}
case SKDownloadStateActive: {
NSLog(@"Download progress:%f", downloadItem.progress);
NSLog(@"Download timeRemaining:%f", downloadItem.timeRemaining);
break;
}
case SKDownloadStatePaused: {
NSLog(@"Download was paused by the user");
break;
}
case SKDownloadStateFinished: {
// ダウンロード完了を通知
[self downloadFinished:[downloadItem.contentURL path]];
[queue finishTransaction:downloadItem.transaction];
break;
}
case SKDownloadStateFailed: {
NSLog(@"error:%@", [downloadItem.error localizedDescription]);
break;
}
case SKDownloadStateCancelled: {
NSLog(@"Download was cancelled");
break;
}
}
}
} |
ダウンロード中はdownloadStateが SKDownloadStateActiveの状態ですので、進捗状況などをSKDownloadのprogressやtimeRemainingプロパティーから取得して、呼び出し元のデリゲートに渡してあげれば、プログレスバーの表示に使えます。
ダウンロードが完了すると、downloadStateはSKDownloadStateFinishedとなり、SKDownloadのcontentURLにダウンロードされたプロダクトのパスが取得できます。
この時プロダクトがダウンロードされる先は「/Library/Caches」になります。
Cache直下に作成される上記の0E6966〜の部分は同じコンテンツをダウンロードしても毎回変わるようです。
また、ディレクトリ名が~.zipになっていて、最初はzip形式なのかと騙されてしまった。。実際は展開済みとなっています。
ちなみに、プロダクト用のプロジェクトを作成した際に、ファイルの格納先を変えていたのですが、ダウンロードされたパッケージはすべてContentsの中に含まれるようです。
(それらしいドキュメントは見当たらないですが、試してみた限りでは)
こんな感じで、Appleに預けたコンテンツは取得できます。
すごく簡単です。。。
こんにちは、いちかわです。
ついに、iPhone5とiOS6がでましたね!
弊社でも早速iPhone5を手に入れましたが、AUのLTEの速さにびっくりしました。
iOS6ベータが提供された時から、気になっていたというか、Samurai Purchaseの競合じゃねーか!と戦々恐々していた、アプリ内課金のコンテンツをAppleさんがホスティングしてくれる機能について調べてみました。
今までのアプリ内課金では、ダウンロード型のコンテンツを提供する場合は、自分でサーバを立ててコンテンツをダウンロードできるようにする必要がありました。
Samurai Purchaseでは、開発期間の短縮や運用コストを削減するのに貢献できるよう、コンテンツの管理&配信をASPとして提供してます。
今回Appleから提供されたコンテンツ(プロダクト)のホスティングは、どんなものかと簡単に説明すると以下のように感じとなります。
Appleのドキュメントを見ると「Hosting Non-Consumable Purchases」のところに書かれていて、「Apple can host your non-consumable purchases〜」と説明されているように、非消耗品タイプの課金アイテムだけが登録できます。
iTunes Connectでプロダクトが登録されている状態
登録できるファイルはパッケージ(pkg)だけで、このパッケージを作るためにXcode4.5では、In-App-Purchase用のテンプレートが用意されています。
このテンプレートでプロジェクトを作成し、必要なファイルを格納して、パッケージを作成します。
SKPaymentQueueに新しく
– startDownloads:
– cancelDownloads:
– pauseDownloads:
– resumeDownloads:
とメソッドが追加され、startDownloadsを呼び出すとダウンロードが実行されます。
SKPaymentTransactionObserverのpaymentQueue:updatedDownloads:実装することで、ダウンロードのステータスをウォッチすることが出来、実際にダウンロードされたプロダクトの情報を含むSKDownloadを取得できます。
SKDownloadのcontentURLプロパティーで、ダウンロードされたコンテンツのパスが取得できますので、格納されているコンテンツを取り出すことができます。
順を追って説明すると
となります。
(サンプルソースは近日公開します)
以上が、Appleにプロダクトをアップロードした場合の購入〜ダウンロードの流れとなります。
アプリに組み込む場合は、アプリ内課金を実装したことがある人であればそれほど難しくはないと思います。
では、Samurai Purchaseとの違いはと言いますと
と言ったところでしょうか。
逆にSamurai Purchaseを使うメリットは、
となります。
実際にアプリを作成する際の企画によって、メリットデメリットがあるので、アプリに必要な機能を満たしている方(自作も含め)選ぶのが良いと思います。