以前のアプリでは、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秒程度の遅延機能を入れようと思っていたのですが、根本的に間違っていると思います。しかし、問題を解決する方法は?
誰でもここで助けることができますか?