应用内购买无法加载产品列表
Posted
技术标签:
【中文标题】应用内购买无法加载产品列表【英文标题】:In-App purchase failing to load list of products 【发布时间】:2014-03-03 12:09:09 【问题描述】:我正在尝试实现一些应用内购买。我遵循了在线教程,我的代码发布在下面。我已将应用内购买添加到我的 iTunes 连接帐户,但是当我运行代码时,它调用了无法加载产品列表的“didfailwitherror”方法。有没有其他人遇到过这个问题并且可能知道解决方案?
#import "IAPHelper.h"
#import <StoreKit/StoreKit.h>
NSString *const IAPHelperProductPurchasedNotification = @"IAPHelperProductPurchasedNotification";
@interface IAPHelper () <SKProductsRequestDelegate, SKPaymentTransactionObserver>
@end
@implementation IAPHelper
SKProductsRequest *_productsRequest;
RequestProductsCompletionHandler _completionHandler;
NSSet * _productIdentifiers;
NSMutableSet * _purchasedProductIdentifiers;
-(id)initWithProductIdentifiers:(NSSet *)productIdentifiers
NSLog(@"get product ids");
if((self=[self init]))
_productIdentifiers = productIdentifiers;
_purchasedProductIdentifiers = [NSMutableSet set];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
for (NSString* productIdentifier in _productIdentifiers)
NSLog(@"product id is %@", productIdentifier);
BOOL productPurchased = [[NSUserDefaults standardUserDefaults] boolForKey:productIdentifier];
if (productPurchased)
[_purchasedProductIdentifiers addObject:productIdentifier];
return self;
-(void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler
NSLog(@"Attempt to complete request for products");
_completionHandler = [completionHandler copy];
_productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:_productIdentifiers];
_productsRequest.delegate=self;
[_productsRequest start];
#pragma mark - SKProductsRequestDelegate
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
NSLog(@"Loaded list of products...");
_productsRequest = nil;
NSArray * skProducts = response.products;
for (SKProduct * skProduct in skProducts)
NSLog(@"Found product: %@ %@ %0.2f",
skProduct.productIdentifier,
skProduct.localizedTitle,
skProduct.price.floatValue);
_completionHandler(YES, skProducts);
_completionHandler = nil;
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error
NSLog(@"Failed to load list of products.");
_productsRequest = nil;
_completionHandler(NO, nil);
_completionHandler = nil;
- (BOOL)productPurchased:(NSString *)productIdentifier
return [_purchasedProductIdentifiers containsObject:productIdentifier];
- (void)buyProduct:(SKProduct *)product
NSLog(@"Buying %@...", product.productIdentifier);
SKPayment * payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addPayment:payment];
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
for (SKPaymentTransaction * transaction in transactions)
switch (transaction.transactionState)
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
[self failedTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
[self restoreTransaction:transaction];
default:
break;
;
- (void)completeTransaction:(SKPaymentTransaction *)transaction
NSLog(@"completeTransaction...");
[self provideContentForProductIdentifier:transaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
- (void)restoreTransaction:(SKPaymentTransaction *)transaction
NSLog(@"restoreTransaction...");
[self provideContentForProductIdentifier:transaction.originalTransaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
- (void)failedTransaction:(SKPaymentTransaction *)transaction
NSLog(@"failedTransaction...");
if (transaction.error.code != SKErrorPaymentCancelled)
NSLog(@"Transaction error: %@", transaction.error.localizedDescription);
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
- (void)provideContentForProductIdentifier:(NSString *)productIdentifier
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
int currentHints = [userDefaults integerForKey:@"hintAmount"];
[_purchasedProductIdentifiers addObject:productIdentifier];
if ([productIdentifier isEqual: @"1"])
[userDefaults setInteger:(currentHints+50) forKey:@"hintAmount"];
else if ([productIdentifier isEqual: @"2"])
[userDefaults setInteger:(currentHints+100) forKey:@"hintAmount"];
else if ([productIdentifier isEqual: @"3"])
[userDefaults setInteger:(currentHints+200) forKey:@"hintAmount"];
else if ([productIdentifier isEqual: @"4"])
[userDefaults setInteger:(currentHints+500) forKey:@"hintAmount"];
[[NSUserDefaults standardUserDefaults] synchronize];
[[NSNotificationCenter defaultCenter] postNotificationName:IAPHelperProductPurchasedNotification object:productIdentifier userInfo:nil];
@end
【问题讨论】:
我认为没有代码问题,因为您没有完成某些步骤,所以您获得了无效的标识符,我提到了一些条件,请这样做 【参考方案1】:仅供参考 - 您必须在设备上运行该应用才能正确获取适用于 IAP 的产品。我遇到的问题是将所有产品标识符吐出为“未购买”,但是当我尝试在表格视图中显示它们时说“无法加载产品列表”。这是在模拟器中运行时。一旦我在设备上运行,就可以完美运行!
我使用本教程获取了完成所有繁重工作的基本帮助文件: http://www.raywenderlich.com/21081/introduction-to-in-app-purchases-in-ios-6-tutorial
【讨论】:
【参考方案2】:满足所有条件
1.您是否为您的 App ID 启用了应用内购买?
2.您是否为您的产品检查过清仓销售?
3.您是否已提交(并可选择拒绝)您的应用程序二进制文件?
4.您项目的 .plist Bundle ID 是否与您的 App ID 匹配?
5.您是否为新的 App ID 生成并安装了新的配置文件?
6.您是否已将项目配置为使用此新的配置文件进行代码签名?
7.您是在为 iPhone OS 3.0 或更高版本构建吗?
8.您在发出 SKProductRequest 时是否使用了完整的产品 ID?
9.您是否在将产品添加到 iTunes Connect 后等待了几个小时?
10.您的银行详细信息在 iTunes Connect 上是否有效? (通过马克)
11.您是否尝试过从设备中删除该应用并重新安装?
如果您对这些问题中的任何一个回答“否”,那就是您的问题。
【讨论】:
我还没有提交我的二进制文件,但是在测试开发中的应用程序时是否需要这样做? 如果您仅出于测试目的实施,则无需提交二进制文件。您是否在控制台中收到无效的产品标识符或空的产品列表?? 也没有,直接跳到失败的错误,不知道如何检查产品id是否有效 NSLog(@"product id is %@", productIdentifier);您从中获得的价值是什么 正在加载产品ID以上是关于应用内购买无法加载产品列表的主要内容,如果未能解决你的问题,请参考以下文章
无法为 iTunes Connect 中的应用内购买上传屏幕截图以供审核