在我以前的应用程序中,只有一个 IAP,所以我没有意识到我的代码有问题。今天我有一个包含多个 IAP 产品的应用程序,我发现了问题。
我遵循了Troy 的 IAP 教程,并且几乎复制了他的代码。这对我以前的应用程序很有效,因为每个应用程序中只有一个 IAP 产品。本教程也使用一个 IAP 产品作为示例。我试图在他的博客上发帖问我的问题,但是我的帖子太长而且没有格式,而且我认为这里的专家可以帮助我了解更多,并检查我是否误解了某些内容或遗漏了某些内容。
现在有两件事我必须处理(除非我错过了,本教程没有提到多个 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。这对于单 IAP 产品应用程序来说一切都很好,因为产品 ID 是固定的,并且可以在应用程序开始运行时调用 loadStore。实际上, loadStore 可能必须在运行应用程序的开始时运行,因为这是第二个问题。
2、如果 loadStore 在用户想要购买 IAP 的时候运行,而不是在应用程序开始时运行,那么问题是当 [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];
}
这将运行并返回产品响应。然后我需要开始付款,但我不确定 HRER 应该如何调用以下方法。这是启动 IAP 付款的方法。正如我所提到的,一旦 loadStore 在应用程序的开头运行,productRequest..response 方法(右上方)有“充足”的时间来完成并发送回通知,因为用户点击这里和那里一秒钟。正如我所说,对于单一 IAP 产品应用程序,这很好,我可以在开头指定产品 ID。现在对于具有多个 IAP 产品的应用程序,我需要向用户展示多个产品,并且用户选择其中一个。在此之后,我需要按顺序做两件事:A,通过 loadStore -> productRequest 方法(右上方)指定哪个 IAP 产品,以及 B,调用以下方法来发起付款。
- (void)purchaseProUpgrade
{
SKPayment *payment = [SKPayment paymentWithProductIdentifier:kInAppPurchaseProUpgradeProductId];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
但是,在我调用付款发起方法时,productRequest.....response 方法可能还没有返回。我将无法开始付款。我想在大约一秒钟之间放置一个延迟功能,但我认为这种方法从根本上是错误的。然而,如何解决问题?
有人可以在这里帮忙吗?