[解決済み】iOSアプリケーションにアプリ内課金を追加する方法は?
質問
iOS アプリにアプリ内課金を追加する方法を教えてください。すべての詳細とサンプル コードはありますか?
これはiOSアプリにアプリ内課金を追加する方法のキャッチオール的な意味です。
どのように解決するのですか?
Swiftユーザ
Swiftユーザは、以下のものをチェックアウトできます。
この質問に対する私のSwiftでの回答
.
または、チェックアウト
Yedidya Reissの回答
このObjective-CのコードをSwiftに翻訳しています。
Objective-Cユーザー
この回答の残りの部分は、Objective-Cで書かれています。
App Storeコネクト
- 移動する appstoreconnect.apple.com にアクセスし、ログインします。
-
クリック
My Apps
をクリックし、購入を追加したいアプリをクリックします。 -
をクリックします。
Features
ヘッダーをクリックし、次にIn-App Purchases
を選択し、左側の -
をクリックします。
+
のアイコンをクリックします。 -
このチュートリアルでは、広告を削除するためにアプリ内課金を追加する予定なので、以下のように選択します。
non-consumable
. ユーザーに物理的なアイテムを送る場合、または複数回購入できるものを提供する場合は、次のように選択します。consumable
. - 参照名には、好きなものを入れてください (ただし、それが何であるかは確認してください)
-
製品IDには
tld.websitename.appname.referencename
これが一番効果的なので、例えばcom.jojodmo.blix.removeads
-
選択する
cleared for sale
で、価格階層を 1 (99¢) と選択します。Tier 2 は $1.99 で、Tier 3 は $2.99 となります。全リストはview pricing matrix
私はあなたが階層1を使用することをお勧めします。それは通常、誰もが今までに広告を削除するために支払うことになる最も高いですから。 -
青い
add language
ボタンをクリックして、情報を入力してください。これはすべてお客様に表示されますので、見られたくないものは記入しないでください。 -
の場合
hosting content with Apple
選ぶ いいえ - レビューノートを空白にすることができます 今すぐ .
-
をスキップして
screenshot for review
今すぐ 私たちが飛ばしたものはすべて戻ってきます。 - 保存」をクリックします。
プロダクトIDが登録されるまでには、数時間かかる場合があります。
App Store Connect
に登録されるまでに数時間かかることがあります。
プロジェクトのセットアップ
App Store Connectでアプリ内課金情報を設定したので、Xcodeプロジェクトに入り、アプリケーションマネージャ(メソッドとヘッダーファイルがある上部にある青いページのようなアイコン)を開き、targets(最初のものであるはず)の下のアプリをクリックして、generalに進みます。一番下にある
linked frameworks and libraries
小さなプラス記号をクリックし、フレームワークを追加します。
StoreKit.framework
これを行わないと、アプリ内課金で
しない
が動作しません!
アプリの言語としてObjective-Cを使用している場合、あなたは は以下の5つのステップをスキップする必要があります。 . そうでない場合は、Swiftを使用している場合、次のようになります。 この質問に対する私のSwiftの回答は、こちら または、アプリ内課金のコードに Objective-C を使用したいが、アプリで Swift を使用している場合、次のようにすることができます。
-
新しい
.h
(ヘッダー) ファイルをFile
>New
>File...
( コマンド ⌘ + N ). このファイルを "あなたの.h
ファイルと呼びます。 -
プロンプトが表示されたら ブリッジングヘッダーの作成 . これがブリッジングヘッダーファイルとなります。もし、あなたが ではなく が表示されたら、ステップ3に進みます。もし は というプロンプトが表示されたら、手順3をスキップして直接手順4へ進みます。
-
別の
.h
という名前のファイルを作成します。Bridge.h
という名前のファイルをメインプロジェクトフォルダに作成し、アプリケーションマネージャ(青いページのようなアイコン)を開き、アプリをTargets
セクションでアプリを選択しBuild Settings
. というオプションを探します。 Swift コンパイラ - コード生成 というオプションを見つけ、そして Objective-C ブリッジヘッダ オプションをBridge.h
-
ブリッジングヘッダーファイルに、以下の行を追加します。
#import "MyObjectiveCHeaderFile.h"
という行を追加してください。MyObjectiveCHeaderFile
は、ステップ1で作成したヘッダーファイルの名前です。ですから、例えば、ヘッダーファイルの名前を InAppPurchase.h と名づけたら、次の行を追加します。#import "InAppPurchase.h"
をブリッジヘッダーファイルに追加します。 -
新しいObjective-Cメソッドを作成します(
.m
) ファイルを作成します。File
>New
>File...
( コマンド ⌘ + N ). 手順1で作成したヘッダーファイルと同じ名前を付けてください。例えば、手順1で作成したファイルの名前を InAppPurchase.h と呼んだ場合、この新しいファイルを呼び出します。 InAppPurchase.m . このファイルは、次のように呼ばれます。.m
ファイル" と呼びます。
コーディング
では、実際のコーディングに入ります。次のコードを
.h
ファイルに追加します。
BOOL areAdsRemoved;
- (IBAction)restore;
- (IBAction)tapsRemoveAds;
次に
StoreKit
フレームワークを
.m
ファイルに追加し、さらに
SKProductsRequestDelegate
と
SKPaymentTransactionObserver
の後に
@interface
宣言の後に
#import <StoreKit/StoreKit.h>
//put the name of your view controller in place of MyViewController
@interface MyViewController() <SKProductsRequestDelegate, SKPaymentTransactionObserver>
@end
@implementation MyViewController //the name of your view controller (same as above)
//the code below will be added here
@end
で、以下を
.m
ファイルに追加します。この部分は複雑になるので、コードのコメントを読むことをお勧めします。
//If you have more than one in-app purchase, you can define both of
//of them here. So, for example, you could define both kRemoveAdsProductIdentifier
//and kBuyCurrencyProductIdentifier with their respective product ids
//
//for this example, we will only use one product
#define kRemoveAdsProductIdentifier @"put your product id (the one that we just made in App Store Connect) in here"
- (IBAction)tapsRemoveAds{
NSLog(@"User requests to remove ads");
if([SKPaymentQueue canMakePayments]){
NSLog(@"User can make payments");
//If you have more than one in-app purchase, and would like
//to have the user purchase a different product, simply define
//another function and replace kRemoveAdsProductIdentifier with
//the identifier for the other product
SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:kRemoveAdsProductIdentifier]];
productsRequest.delegate = self;
[productsRequest start];
}
else{
NSLog(@"User cannot make payments due to parental controls");
//this is called the user cannot make payments, most likely due to parental controls
}
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
SKProduct *validProduct = nil;
int count = [response.products count];
if(count > 0){
validProduct = [response.products objectAtIndex:0];
NSLog(@"Products Available!");
[self purchase:validProduct];
}
else if(!validProduct){
NSLog(@"No products available");
//this is called if your product id is not valid, this shouldn't be called unless that happens.
}
}
- (void)purchase:(SKProduct *)product{
SKPayment *payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
- (IBAction) restore{
//this is called when the user restores purchases, you should hook this up to a button
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
- (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
NSLog(@"received restored transactions: %i", queue.transactions.count);
for(SKPaymentTransaction *transaction in queue.transactions){
if(transaction.transactionState == SKPaymentTransactionStateRestored){
//called when the user successfully restores a purchase
NSLog(@"Transaction state -> Restored");
//if you have more than one in-app purchase product,
//you restore the correct product for the identifier.
//For example, you could use
//if(productID == kRemoveAdsProductIdentifier)
//to get the product identifier for the
//restored purchases, you can use
//
//NSString *productID = transaction.payment.productIdentifier;
[self doRemoveAds];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
}
}
}
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{
for(SKPaymentTransaction *transaction in transactions){
//if you have multiple in app purchases in your app,
//you can get the product identifier of this transaction
//by using transaction.payment.productIdentifier
//
//then, check the identifier against the product IDs
//that you have defined to check which product the user
//just purchased
switch(transaction.transactionState){
case SKPaymentTransactionStatePurchasing: NSLog(@"Transaction state -> Purchasing");
//called when the user is in the process of purchasing, do not add any of your own code here.
break;
case SKPaymentTransactionStatePurchased:
//this is called when the user has successfully purchased the package (Cha-Ching!)
[self doRemoveAds]; //you can add your code for what you want to happen when the user buys the purchase here, for this tutorial we use removing ads
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
NSLog(@"Transaction state -> Purchased");
break;
case SKPaymentTransactionStateRestored:
NSLog(@"Transaction state -> Restored");
//add the same code as you did from SKPaymentTransactionStatePurchased here
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
//called when the transaction does not finish
if(transaction.error.code == SKErrorPaymentCancelled){
NSLog(@"Transaction state -> Cancelled");
//the user cancelled the payment ;(
}
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
}
}
}
ここで、ユーザーがトランザクションを終了したときに発生するコードを追加したいと思います。このチュートリアルでは、追加を削除することを使用します。
- (void)doRemoveAds{
ADBannerView *banner;
[banner setAlpha:0];
areAdsRemoved = YES;
removeAdsButton.hidden = YES;
removeAdsButton.enabled = NO;
[[NSUserDefaults standardUserDefaults] setBool:areAdsRemoved forKey:@"areAdsRemoved"];
//use NSUserDefaults so that you can load whether or not they bought it
//it would be better to use KeyChain access, or something more secure
//to store the user data, because NSUserDefaults can be changed.
//You're average downloader won't be able to change it very easily, but
//it's still best to use something more secure than NSUserDefaults.
//For the purpose of this tutorial, though, we're going to use NSUserDefaults
[[NSUserDefaults standardUserDefaults] synchronize];
}
アプリケーションに広告がない場合は、他のどんなものでも使用できます。例えば、背景の色を青にすることができます。これを行うには、以下を使用したいと思います。
- (void)doRemoveAds{
[self.view setBackgroundColor:[UIColor blueColor]];
areAdsRemoved = YES
//set the bool for whether or not they purchased it to YES, you could use your own boolean here, but you would have to declare it in your .h file
[[NSUserDefaults standardUserDefaults] setBool:areAdsRemoved forKey:@"areAdsRemoved"];
//use NSUserDefaults so that you can load wether or not they bought it
[[NSUserDefaults standardUserDefaults] synchronize];
}
さて、あなたの
viewDidLoad
メソッドのどこかに、次のコードを追加してください。
areAdsRemoved = [[NSUserDefaults standardUserDefaults] boolForKey:@"areAdsRemoved"];
[[NSUserDefaults standardUserDefaults] synchronize];
//this will load wether or not they bought the in-app purchase
if(areAdsRemoved){
[self.view setBackgroundColor:[UIColor blueColor]];
//if they did buy it, set the background to blue, if your using the code above to set the background to blue, if your removing ads, your going to have to make your own code here
}
すべてのコードを追加したら、次に
.xib
または
storyboard
ファイルを作成し、2つのボタン、1つは「購入」、もう1つは「復元」を追加します。このボタンを
tapsRemoveAds
IBAction
を先ほど作成した購入ボタンに、そして
restore
IBAction
をリストアボタンに設定します。は
restore
アクションは、ユーザーが以前にアプリ内課金を購入したことがあるかどうかを確認し、まだ持っていない場合は無料でアプリ内課金を提供します。
レビューに投稿する
次に
App Storeコネクト
をクリックし
Users and Access
をクリックし
Sandbox Testers
ヘッダーをクリックし、次に
+
と書かれている左側の記号をクリックします。
Testers
. 名前と姓は適当に入れてもいいし、Eメールも本物である必要はない。パスワード(これは覚えておく必要があります)を入れて、残りの情報を記入します。私がお勧めするのは
Date of Birth
には、ユーザーを18歳以上にするための日付を入れることをお勧めします。
App Store Territory
HAS
を正しい国に設定してください。次に、既存のiTunesアカウントからログアウトします(このチュートリアルの後にログインし直せます)。
さて、あなたの iOS デバイスでアプリケーションを実行してください。シミュレータで実行してみると、購入が
常に
エラーになります。
しなければならない
をiOSデバイスで実行してください。アプリが起動したら、購入ボタンをタップしてください。iTunesアカウントへのログインを求められるので、先ほど作成したテストユーザーでログインしてください。次に、99¢またはあなたが設定した価格帯の購入を確認するように要求されます。
画面のスナップショットを撮る
これはあなたの
screenshot for review
で使用するものです。これで決済をキャンセルします。
次に
App Storeコネクト
に移動し、次に
My Apps
>
the app you have the In-app purchase on
>
In-App Purchases
. 次に、アプリ内課金をクリックし、アプリ内課金の詳細の下にある編集をクリックします。iPhoneで撮影した写真をパソコンに取り込み、レビュー用のスクリーンショットとしてアップロードし、レビューメモに
テストユーザー
メールアドレスとパスワードを入力してください。これは、レビューの過程でリンゴを助けるでしょう。
テストユーザーのアカウントでログインしたまま、iOSデバイスでアプリケーションに戻り、購入ボタンをクリックしてください。このとき、支払いを確認します。
テストユーザーのアカウントでは、すべてのアプリ内課金を無料で利用できますので、ご安心ください。
支払いを確認した後、ユーザーが製品を購入したときに実際に何が起こるかを確認します。そうでない場合、あなたのアカウントにエラーが発生します。
doRemoveAds
メソッドのエラーになります。アプリ内課金のテストには、背景を青に変更することをお勧めします。すべてうまくいったら完了です。App Store Connectにアップロードする際には、新しいバイナリにアプリ内課金を含めることを確認してください。
よくあるエラーを紹介します。
ログに記録されています。
No Products Available
これは4つのことを意味します。
-
コードに正しいアプリ内課金IDを記述していない(識別子である
kRemoveAdsProductIdentifier
という識別子に対して、上記のコードでは - で販売するアプリ内課金をクリアしていません。 App Storeコネクト
- でアプリ内課金IDが登録されるのを待たずに App Storeコネクト . IDの作成から数時間待てば、問題は解決するはずです。
- 契約書、税金、銀行口座の記入が完了していません。
一回目でうまくいかなくても、イライラしないでください! あきらめないでください! 私は、これが動作するようになるまでに約 5 時間かかり、正しいコードを検索するのに約 10 時間かかりました! 上記のコードを正確に使用すれば、問題なく動作するはずです。もし何か質問があれば、お気軽にコメントください。 すべて .
iOS アプリケーションにアプリ内課金を追加したいと考えているすべての人のお役に立てれば幸いです。乾杯!
関連
-
[解決済み】Xcode - 'NSUnknownKeyException', reason: ... this class is not key value coding-compliant for the key X" エラーの修正方法とは?
-
[解決済み] Objective-C ブロックパラメータ 発行 このブロック宣言はプロトタイプではありません
-
[解決済み] Xcodeで実行ファイルが無効なエンタイトルメントで署名されてしまう
-
[解決済み] キーボードがあるときに、UITextFieldを編集開始時に上に移動させるには?
-
[解決済み] iOSまたはmacOSで、インターネット接続が有効かどうかを確認するにはどうすればよいですか?
-
[解決済み] カスタムオブジェクトを含むNSMutableArrayをソートするにはどうすればよいですか?
-
[解決済み] performSelectorのセレクタが不明なため、リークが発生する可能性があります。
-
[解決済み] App Storeのアプリと連動させる方法
-
[解決済み] アプリのプレビュー用にiOSシミュレータのビデオをキャプチャー
-
[解決済み】iOSアプリの名前を変更する方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】リンカーコマンドが終了コード1で失敗(起動を確認するには-vを使用)、Xcode 8、Swift 3
-
[解決済み] ウィンドウ階層にないビューを持つUIViewControllerでUIViewControllerを表示しようとする
-
[解決済み] EXC_CORPSE_NOTIFY シンボルのクラッシュが発生しました、追跡するには?
-
[解決済み] Int 型のインデックスを持つ [AnyObject]? の値を添え字として使用できません。
-
[解決済み] エラーです。cocoapodsでRestKitをインストール後、「サンドボックスがPodfile.lockと同期していない...」と表示される
-
[解決済み] Xcodeで "No such module "というエラーが出るが、フレームワークはある
-
[解決済み] UTF-8でエンコードされたNSDataをNSStringに変換します。
-
[解決済み] ERROR ITMS-9000: "Redundant Binary Upload. 列車 '1.0' のビルドバージョン '1.0' のバイナリアップロードが既に存在します" と表示されました。
-
[解決済み] WKWebviewにuseragentを設定する
-
[解決済み] Swift の performSegueWithIdentifier が動作しない。