1. ホーム
  2. アイオス

[解決済み】iOSアプリケーションにアプリ内課金を追加する方法は?

2022-05-10 14:47:51

質問

iOS アプリにアプリ内課金を追加する方法を教えてください。すべての詳細とサンプル コードはありますか?

これはiOSアプリにアプリ内課金を追加する方法のキャッチオール的な意味です。

どのように解決するのですか?

Swiftユーザ

Swiftユーザは、以下のものをチェックアウトできます。 この質問に対する私のSwiftでの回答 .

または、チェックアウト Yedidya Reissの回答 このObjective-CのコードをSwiftに翻訳しています。

Objective-Cユーザー

この回答の残りの部分は、Objective-Cで書かれています。

App Storeコネクト

  1. 移動する appstoreconnect.apple.com にアクセスし、ログインします。
  2. クリック My Apps をクリックし、購入を追加したいアプリをクリックします。
  3. をクリックします。 Features ヘッダーをクリックし、次に In-App Purchases を選択し、左側の
  4. をクリックします。 + のアイコンをクリックします。
  5. このチュートリアルでは、広告を削除するためにアプリ内課金を追加する予定なので、以下のように選択します。 non-consumable . ユーザーに物理的なアイテムを送る場合、または複数回購入できるものを提供する場合は、次のように選択します。 consumable .
  6. 参照名には、好きなものを入れてください (ただし、それが何であるかは確認してください)
  7. 製品IDには tld.websitename.appname.referencename これが一番効果的なので、例えば com.jojodmo.blix.removeads
  8. 選択する cleared for sale で、価格階層を 1 (99¢) と選択します。Tier 2 は $1.99 で、Tier 3 は $2.99 となります。全リストは view pricing matrix 私はあなたが階層1を使用することをお勧めします。それは通常、誰もが今までに広告を削除するために支払うことになる最も高いですから。
  9. 青い add language ボタンをクリックして、情報を入力してください。これはすべてお客様に表示されますので、見られたくないものは記入しないでください。
  10. の場合 hosting content with Apple 選ぶ いいえ
  11. レビューノートを空白にすることができます 今すぐ .
  12. をスキップして screenshot for review 今すぐ 私たちが飛ばしたものはすべて戻ってきます。
  13. 保存」をクリックします。

プロダクトIDが登録されるまでには、数時間かかる場合があります。 App Store Connect に登録されるまでに数時間かかることがあります。

プロジェクトのセットアップ

App Store Connectでアプリ内課金情報を設定したので、Xcodeプロジェクトに入り、アプリケーションマネージャ(メソッドとヘッダーファイルがある上部にある青いページのようなアイコン)を開き、targets(最初のものであるはず)の下のアプリをクリックして、generalに進みます。一番下にある linked frameworks and libraries 小さなプラス記号をクリックし、フレームワークを追加します。 StoreKit.framework これを行わないと、アプリ内課金で しない が動作しません!

アプリの言語としてObjective-Cを使用している場合、あなたは は以下の5つのステップをスキップする必要があります。 . そうでない場合は、Swiftを使用している場合、次のようになります。 この質問に対する私のSwiftの回答は、こちら または、アプリ内課金のコードに Objective-C を使用したいが、アプリで Swift を使用している場合、次のようにすることができます。

  1. 新しい .h (ヘッダー) ファイルを File > New > File... ( コマンド ⌘ + N ). このファイルを "あなたの .h ファイルと呼びます。

  2. プロンプトが表示されたら ブリッジングヘッダーの作成 . これがブリッジングヘッダーファイルとなります。もし、あなたが ではなく が表示されたら、ステップ3に進みます。もし というプロンプトが表示されたら、手順3をスキップして直接手順4へ進みます。

  3. 別の .h という名前のファイルを作成します。 Bridge.h という名前のファイルをメインプロジェクトフォルダに作成し、アプリケーションマネージャ(青いページのようなアイコン)を開き、アプリを Targets セクションでアプリを選択し Build Settings . というオプションを探します。 Swift コンパイラ - コード生成 というオプションを見つけ、そして Objective-C ブリッジヘッダ オプションを Bridge.h

  4. ブリッジングヘッダーファイルに、以下の行を追加します。 #import "MyObjectiveCHeaderFile.h" という行を追加してください。 MyObjectiveCHeaderFile は、ステップ1で作成したヘッダーファイルの名前です。ですから、例えば、ヘッダーファイルの名前を InAppPurchase.h と名づけたら、次の行を追加します。 #import "InAppPurchase.h" をブリッジヘッダーファイルに追加します。

  5. 新しいObjective-Cメソッドを作成します( .m ) ファイルを作成します。 File > New > File... ( コマンド ⌘ + N ). 手順1で作成したヘッダーファイルと同じ名前を付けてください。例えば、手順1で作成したファイルの名前を InAppPurchase.h と呼んだ場合、この新しいファイルを呼び出します。 InAppPurchase.m . このファイルは、次のように呼ばれます。 .m ファイル" と呼びます。

コーディング

では、実際のコーディングに入ります。次のコードを .h ファイルに追加します。

BOOL areAdsRemoved;

- (IBAction)restore;
- (IBAction)tapsRemoveAds;

次に StoreKit フレームワークを .m ファイルに追加し、さらに SKProductsRequestDelegateSKPaymentTransactionObserver の後に @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 アプリケーションにアプリ内課金を追加したいと考えているすべての人のお役に立てれば幸いです。乾杯!