8

我正在使用 StoreKit 进行应用内购买。我发现当用户按下“取消”按钮时,API 的行为很古怪。

例如,如果我在“确认您的应用内购买”屏幕上按取消,我会得到我期望的SKPaymentTransactionStateFailed交易。error.code == SKErrorPaymentCancelled

但如果我按下购买然后按下取消,我会得到一笔Failed交易error.code == 0。这error.localizedDescription是“无法连接到 iTunes Store”,这显然是一个谎言。

将所有Failed交易都视为可忽略的取消是很诱人的,但我也可以清楚地看到,如果设备在飞行模式下处于离线状态,我会得到Failed一笔没有弹出警报的交易;在这种情况下,我真的应该通知用户解释问题。

我注意到MKStoreKit假设所有失败都是取消。MKStoreManagerfailedTransaction方法永远不会被调用;MKStoreObserver总是要求transactionCanceled所有的Failed交易。MKStoreManager.h评论建议没有错误消息,这transactionCanceled是有道理的,但是谁会通知用户有关Failed未取消的交易?

处理这些故障的最佳实践是什么?我应该吞下错误吗?总是显示错误,即使它是多余的?

4

5 回答 5

11

我们有相当大的用户群通过移动连接购买东西,并且只显示警报

code != SKErrorPaymentCancelled && code != SKErrorPaymentNotAllowed

显然,这是你能做的最好的。我还看到了您提到的取消的奇怪行为,据我所知,这是一个框架错误。

于 2011-04-26T10:51:09.300 回答
3

上一个答案非常接近。MKStoreKit 可以自动显示有效错误条件的错误消息,例如打开家长控制等。

尽管如此,为了处理购买取消,我还在 MKStoreKitDelegate 中提供了一个名为 transactionCanceled 的委托(从 v3.5 开始)。

处理该问题并停止视图控制器上进行购买调用的任何活动微调器或进度 hud...

于 2011-04-27T09:33:51.813 回答
0

我只是想补充一点,由于没有互联网连接而导致的错误大多应该在使用 Apple 的可达性类 IMO 进行任何交易之前被捕获。这样,您就不需要依赖 Apple 的 API 来解决直接且常见的错误。

于 2014-10-25T19:20:59.553 回答
0

我认为在哪里显示取消交易的警报是您的责任和决定。但是你一定要完成它,否则它会一直下降到失败。所以应该是这样的:

if (transaction.error.code == SKErrorPaymentCancelled) {
    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
} else {
    [self notifyError:transaction.error];
}

更新:由于iPhone 应用程序开发业务:制作和营销成功的应用程序,我们应该在任何更新到失败状态后完成交易。知道是否存在我们不应该的情况会很有趣。

于 2016-01-26T18:06:51.940 回答
-1

仍然有一个问题...单击购买按钮后,它将显示另一个警报视图并询问帐户信息。

如果我确实在那里取消了,那么它将进入 SKErrorUnknown 的情况:然后 我无法显示这样的消息“您的购买无法完成。请检查您的网络设置,然后再试一次。”

- (void) failedTransaction: (SKPaymentTransaction *)transaction
{   
    switch (transaction.error.code) {
        case SKErrorUnknown:
            NSLog(@"SKErrorUnknown");
            break;
        case SKErrorClientInvalid:
            NSLog(@"SKErrorClientInvalid");
            break;
        case SKErrorPaymentCancelled:
            NSLog(@"SKErrorPaymentCancelled");
        break;
        case SKErrorPaymentInvalid:
            NSLog(@"SKErrorPaymentInvalid");
            break;
        case SKErrorPaymentNotAllowed:
            NSLog(@"SKErrorPaymentNotAllowed");
        break;
        default:
            NSLog(@"No Match Found for error");
            break;
    }
    NSLog(@"transaction.error.code %@",[transaction.error description]);
    if (transaction.error.code == SKErrorPaymentCancelled) {
        [[MKStoreManager sharedManager] transactionCanceled:transaction];
    } else {
        [[MKStoreManager sharedManager] failedTransaction:transaction];
    }
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; 
}
于 2011-05-27T13:38:22.830 回答