1

以前のアプリでは、IAP が 1 つしかないため、コードに問題があることに気づきませんでした。今日、私は複数の IAP 製品を含むアプリを持っており、問題を発見しました。

Troy の IAP チュートリアルに従い、彼のコードをほとんどコピーしました。以前のアプリでは、それぞれのアプリに IAP プロダクトが 1 つしかなかったため、これでうまくいきました。このチュートリアルでは、例として 1 つの IAP 製品も使用しています。私は質問をするために彼のブログに投稿しようとしていましたが、私の投稿は長すぎて書式設定されていません。さらに、ここの専門家は、私が何かを誤解したり見逃したりしたかどうかをより理解し、確認するのに役立つと思います.

ここで、処理しなければならないことが 2 つあります (見落としていない限り、チュートリアルでは複数の IAP 製品のケースについて言及していませんでした)。

1、勘違いかどうか分かりませんが、チュートリアルにloadStoreメソッドのコメントがありました、このように

//
// call this method once on startup
//
- (void)loadStore {
    // restarts any purchases if they were interrupted last time the app was open
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];

    // get the product description (defined in early sections)
    [self requestProUpgradeProductData];
}

そのため、ViewController.m ファイルでアプリの開始時にこのメソッドを呼び出します。私の理解では、このメソッドは、以前のトランザクションがそこにかかっていないかどうかを確認する必要があり、アプリの再起動時にそれを処理する必要があるということです。これが、この loadStore メソッドの最初のステートメントです。このメソッドは、次のような requestProUpgradeProductData を呼び出し続けます。

- (void)requestProUpgradeProductData {
   NSSet *productIdentifiers = [NSSet setWithObject:@"com.runmonster.runmonsterfree.upgradetopro" ];
    productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
    productsRequest.delegate = self;
    [productsRequest start];

    // we will release the request object in the delegate callback
}

このメソッドの最初のステートメントは、IAP 製品 ID を取得することです。プロダクト ID が固定されているため、IAP プロダクトが 1 つのアプリの場合はこれで問題ありません。また、アプリの実行の開始時に loadStore を呼び出してもかまいません。実際には、アプリケーションの実行の最初に loadStore を実行する必要があると思われます。これが 2 つ目の問題です。

2. アプリの開始時ではなく、ユーザーが IAP を購入したいときに loadStore が実行される場合、キャッチは [productRequest start] の実行時であり、次のメソッドが実行されます。

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
    NSArray *products = response.products;
    proUpgradeProduct = [products count] == 1 ? [[products firstObject] retain] : nil;
    if (proUpgradeProduct)
    {
    NSLog(@"Product title: %@" , proUpgradeProduct.localizedTitle);
    NSLog(@"Product description: %@" , proUpgradeProduct.localizedDescription);
    NSLog(@"Product price: %@" , proUpgradeProduct.price);
    NSLog(@"Product id: %@" , proUpgradeProduct.productIdentifier);
    }

    for (NSString *invalidProductId in response.invalidProductIdentifiers)
    {
    NSLog(@"Invalid product id: %@" , invalidProductId);
    }

   // finally release the reqest we alloc/init’ed in requestProUpgradeProductData
   [productsRequest release]; //I didn't do this because of ARC

    [[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseManagerProductsFetchedNotification object:self userInfo:nil];
}

これが実行され、製品で応答が返されます。次に、支払いを開始する必要がありますが、人事担当者が次の方法をどのように呼び出すべきかわかりません。これは、IAP 支払いを開始する方法です。前述したように、アプリの開始時に loadStore が実行されると、productRequest.... 応答メソッド (右上) が完了して通知を送り返すための「十分な」時間があります。前述したように、IAP プロダクトが 1 つのアプリの場合は、最初にプロダクト ID を指定できます。複数の IAP 製品を使用するアプリの場合、複数の製品をユーザーに提示する必要があり、ユーザーはその中から 1 つを選択します。この直後に、次の 2 つのことが必要です。A、loadStore -> productRequest メソッド (右上) を使用して、どの IAP 製品を指定するか、B、次のメソッドを呼び出して支払いを開始します。

- (void)purchaseProUpgrade
{
    SKPayment *payment = [SKPayment paymentWithProductIdentifier:kInAppPurchaseProUpgradeProductId];
    [[SKPaymentQueue defaultQueue] addPayment:payment];
}

ただし、支払い開始メソッドを呼び出した時点では、まだ productRequest.....response メソッドが返されない場合があります。支払いを開始できません。間に1秒程度の遅延機能を入れようと思っていたのですが、根本的に間違っていると思います。しかし、問題を解決する方法は?

誰でもここで助けることができますか?

4

1 に答える 1

1

重要なことは、productsRequest. まず、initWithProductIdentifiers:一連の識別子を取得します。したがって、アプリの起動時または購入オプションをユーザーに提示する前の任意の時点で、ユーザーが購入できるすべての製品の識別子/sku を使用して呼び出します。起動時に呼び出すのは無駄に思えますが、それも機能するはずであり、一部のアプリでは唯一のオプションかもしれません.

製品オブジェクトを含むコールバックを取得した後でのみproductsRequest:didReceiveResponse:、ユーザーがクリック/タッチするか、その製品の購入アクションを呼び出すことができます。ユーザーが購入を試行できるようにする前に、応答を確認して製品が存在することを確認する必要があります。購入画面があり、ユーザーがそれを入力productsRequestすると、アプリケーションの現在の状態に関連するすべての製品で を呼び出します (たとえば、既に購入したアイテムを省略したり、レベルごとに製品を制限したりします)。購入画面も作成しますが、商品は入れていません。応答デリゲートでは、購入可能なオブジェクトを実際に画面に入力します。そうすれば、ユーザーは無効な製品を購入しようとすることができなくなります。

ユーザーがクリック/タップすると、応答からの製品オブジェクトを使用して、次を使用して支払いオブジェクトを作成します。

[SKPayment paymentWithProduct:product]

これはpaymentWithProductIdentifier:、非推奨の方法を使用する現在の設定からの変更であることに注意してください。

于 2013-02-14T17:39:27.217 に答える