17

我如何检查用户是否点击了取消按钮(当他被问到是否要购买时,或者如果他已经购买了这个 SKProduct 是否要下载它)?

现在,我只在用户点击取消按钮后和例如没有互联网时在 paymentQueue:updatedTransactions: 方法中收到 SKPaymentTransactionStateFailed。有什么方法可以区分这两种情况吗?

4

7 回答 7

23

这段代码对我有用:

if (transaction.error.code != SKErrorPaymentCancelled) {
    NSLog(@"Other error");
} else {
    NSLog(@"User canceled");
}
于 2013-03-08T15:14:17.383 回答
15

艾伦的回答是完美的。以防万一有人想知道其他情况

switch (transaction.error.code) {
   case SKErrorUnknown:
       //Unknown error
       break;
   case SKErrorClientInvalid:
       // client is not allowed to issue the request, etc.
       break;
   case SKErrorPaymentCancelled:
       // user cancelled the request, etc.
       break;
   case SKErrorPaymentInvalid:
       // purchase identifier was invalid, etc.
       break;
   case SKErrorPaymentNotAllowed:
       // this device is not allowed to make the payment
       break;
   default:
       break;
}
于 2015-01-08T15:09:49.070 回答
11

斯威夫特版本:

if let error = transaction.error as? NSError {
    if error.domain == SKErrorDomain {
        // handle all possible errors
        switch (error.code) {
        case SKError.unknown.rawValue:
            print("Unknown error")
        case SKError.clientInvalid.rawValue:
            print("client is not allowed to issue the request")
        case SKError.paymentCancelled.rawValue:
            print("user cancelled the request")
        case SKError.paymentInvalid.rawValue:
            print("purchase identifier was invalid")
        case SKError.paymentNotAllowed.rawValue:
            print("this device is not allowed to make the payment")
        default:
            break;
        }
    }
}
于 2016-11-30T14:36:40.403 回答
2

斯威夫特 2.2

如果您在 中得到.Failed响应paymentQueue,最好处理所有可以处理的错误。

if let error = transaction.error {
    if error.domain == SKErrorDomain {
        // handle all possible errors
        switch (error.code) {
        case SKErrorCode.Unknown.rawValue:
            print("Unknown error")
            break;
        case SKErrorCode.ClientInvalid.rawValue:
            print("client is not allowed to issue the request")
            break;
        case SKErrorCode.PaymentCancelled.rawValue:
            print("user cancelled the request")
            break;
        case SKErrorCode.PaymentInvalid.rawValue:
            print("purchase identifier was invalid")
            break;
        case SKErrorCode.PaymentNotAllowed.rawValue:
            print("this device is not allowed to make the payment")
            break;
        default:
            break;
        }
    }
}
于 2016-10-08T14:13:13.283 回答
2

斯威夫特 4.2

if let error = transaction.error,
 (error as? SKError)?.code != SKError.paymentCancelled {
 // Here it is failed for sure!
}
于 2019-01-29T11:08:48.997 回答
1

检查设置的 SKPaymentTransactionerror属性。

@property(nonatomic, readonly) NSError *error

描述在处理事务时发生的错误的对象。(只读)

错误属性未定义,除非 transactionState 设置为 SKPaymentTransactionStateFailed。您的应用程序可以读取错误属性以确定事务失败的原因。

此外,您可能希望使用 Apple 的 Reachability 类来确定在开始交易之前 Internet 是否可用。

于 2012-11-26T18:49:32.010 回答
1

也许您正在使用 Ray Wunderlich 的应用程序购买教程代码。那里的守则说:

- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers {

if ((self = [super init])) {

    // Store product identifiers
    _productIdentifiers = productIdentifiers;

    // Check for previously purchased products
    _purchasedProductIdentifiers = [NSMutableSet set];
    for (NSString * productIdentifier in _productIdentifiers) {
        BOOL productPurchased = [[NSUserDefaults standardUserDefaults] boolForKey:productIdentifier];
        if (productPurchased) {
            [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; // CHECK THIS
            [_purchasedProductIdentifiers addObject:productIdentifier];
            NSLog(@"Previously purchased: %@", productIdentifier);
        } else {
            NSLog(@"Not purchased: %@", productIdentifier);
        }
    }

在那里你可以看到,只有在 Product 已经被购买的情况下才会调用 addTransactionObserver。如果将这行代码移到 if 查询前面,您将获得所需的结果。

[[SKPaymentQueue defaultQueue] addTransactionObserver:self]; // MOVE HERE
if (productPurchased) {
    [_purchasedProductIdentifiers addObject:productIdentifier];
    NSLog(@"Previously purchased: %@", productIdentifier);
} else {
    NSLog(@"Not purchased: %@", productIdentifier);
}                

现在在 failedTransaction 方法中,您可以调用

 [[NSNotificationCenter defaultCenter] postNotificationName:IAPHelperProductPurchasedNotification object:nil userInfo:nil];

现在您可以在当前视图中检查 Notification 发送的 nil 值

于 2013-01-21T13:41:23.867 回答