SKPaymentQueue finishTransaction:在网络完成块内?

时间:2012-05-23 15:00:20

标签: objective-c ios xcode in-app-purchase

这个问题让我头疼了一段时间。

我的应用以自动续订订阅模式运行。我有一个SKPaymentQueue transactionObserver,当通过Apple成功完成购买时会通知我,此时我将Apple收据发送到我的服务器以验证我的结果。一旦我验证它,我就会向我的应用程序发送一个成功回调,该应用程序向用户提供内容,然后调用finishTransaction:on the transaction(according to the docs是正确的操作过程)。

问题是,我害怕等待这么长时间才能调用finishTransaction:Apple预计它被调用(3-4秒)后禁止交易实际上“完成”。如果我在我的应用程序中成功购买(并且已经调用了completeTransaction:),然后终止我的应用程序(在Xcode中“停止”)并再次运行它,立即启动时会有一个,两个,三个,有时四个在UI甚至加载之前,SKPaymentQueue中有五个事务。

以下是对我的服务器的调用,该调用是在Apple完成交易后发生的 :

-(void)completeTransaction:(SKPaymentTransaction *)transaction
{
    NSLog(@"complete transaction");
    [self sendReceiptToServer:transaction];
}

-(void)sendReceiptToServer:(SKPaymentTransaction*)transaction
{
    NSString *rawReceiptData = [[NSString alloc] initWithData:transaction.transactionReceipt encoding:NSUTF8StringEncoding];
    NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:rawReceiptData, @"receipt", [[UserSingleton sharedInstance] memberID], @"member", nil];

    NSMutableURLRequest *request = [[HTTPRequestSingleton sharedClient] requestWithMethod:@"POST" path:cFunctionAddCredits parameters:params];   
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {

        NSLog(@"%@", JSON);
        NSString *creditsString = [JSON valueForKey:@"limit"];
        int numberOfCredits = [creditsString intValue];
        [self provideContent:transaction.payment.productIdentifier withNumberOfCredits:numberOfCredits];
        [[SKPaymentQueue defaultQueue] finishTransaction:transaction];

    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
        NSLog(@"failed to send receipt to server");  
        [[NSNotificationCenter defaultCenter] postNotificationName:cFailedToSendReceiptToServer object:transaction];
        [[SKPaymentQueue defaultQueue] finishTransaction:transaction];

    }];

    [operation start];
}

如您所见,[[SKPaymentQueue defaultQueue] finishTransaction:transaction];在我的服务器请求的成功或失败块中被调用。这会有问题吗?

*的 修改 * 如果我在将收据发送到我的服务器进行验证之前调用SKPaymentQueue:finishTransaction:,似乎不会发生此问题,这使我相信在网络请求块中调用它确实会导致问题。但这不是处理事情的正确方法,所以我仍然陷入困境。

* 编辑2 * 事实证明,即使我在将收据发送到我的服务器之前进行finishTransaction:调用,有时在启动应用程序时仍会“恢复”交易。发生了什么事?

2 个答案:

答案 0 :(得分:3)

经过数周的“幻影”购买,我终于意识到发生了什么。这不是finishTransaction:或AFNetworking的错误。

应用程序启动时发生的交易实际上是Apple正在执行的自动续订过程的一部分。 life of a 1 month subscription in the Apple Sandbox is 5 minutes,因此我在启动应用程序时会在队列中有1,2或3个事务,具体取决于自上次启动它以来是否已经过了5分钟,10分钟或15分钟。

我不得不调整一些服务器端设置,以确保续订不被视为与新订阅相同。

答案 1 :(得分:0)

完成交易需要多长时间并不重要..您需要调用[[SKPaymentQueue defaultQueue] finishTransaction:transaction];以防万一您将内容发送给用户(在您成功完成订阅的情况下)。< / p>