iOS 应用内购买:Objective-c

iOS In App Purchases: Objective-c

我设置了应用内购买,在 buySubscriptionAction 方法后出现以下错误:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid product identifier: (null)'

这是我的应用内购买代码:

在 .h 文件中

SKProductsRequest *productsRequest;
NSArray *validProducts;
@property (nonatomic, strong) SKProduct *product;
@property (nonatomic, strong) NSString *productID;

在 .m 文件中

-(void) startInAppPurchase {
    self.productID = @"1year";
    [self getProductID];
    [self buySubscriptionAction];
}

// called FIRST
-(void) getProductID {

    if ([SKPaymentQueue canMakePayments]) {
        SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:self.productID]];
        request.delegate = self;
        [request start];
    } else {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Please enable in app purchases in your settings" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
        [alert show];
    }
}

// called SECOND
-(void) buySubscriptionAction {

    SKPayment *payment = [SKPayment paymentWithProduct:self.product];
    [[SKPaymentQueue defaultQueue] addPayment:payment];
}

buySubscriptionAction 方法后应用崩溃。

我试过 self.productID 作为 com.companyName.appname.year1year1。有谁知道可能导致此崩溃和错误消息的原因吗?

注:

从未调用此方法:

- (void) productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
    NSArray *products = response.products;
    NSLog(@"products: %@",products);

    if (products.count != 0) {
        self.product = products[0];
        productName = self.product.localizedTitle;
        productDescription = self.product.localizedDescription;
    } else {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Product Not Found" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
        [alert show];
    }

    products = response.invalidProductIdentifiers;

    for (SKProduct *prod in products) {
        NSLog(@"Product not found: %@",prod);
    }
}

因此,self.products 在 buySubscriptionAction 中为空。

在 .h 中我包含了 <SKProductsRequestDelegate, SKPaymentTransactionObserver>

尽管您分配了 delegate = self,但您的委托方法没有被调用。

想想为什么会这样。 SKProductsRequest 承诺在请求完成或超时时调用单个委托方法。由于这没有发生,您可以假设 1) 系统错误 2) SKProductsRequest 正在以某种方式消失。

1) 这绝不是框架错误。

2) 所以 SKProductsRequest 消失了。仔细想想。您的方法结束,您希望 SKProductsRequest 实例 继续 运行。但是,您现在 离开了方法作用域 而没有告诉编译器您希望 SKProductsRequest 保持活动状态。系统假定您已完成 SKProductsRequest 实例并将其销毁。

您的问题是您未能确保 SKProductsRequest 实例在您离开方法范围后继续存在。

创建一个 strong 属性 并用它来存储请求。这将明确告诉编译器在离开 class 上下文之前不要处理 SKProductsRequest 对象。问题应该解决了。