2016-08-02 61 views
47

Xcode 8 beta 4中的新增功能,NSError桥接到Swift Error协议类型。这在处理失败的SKPaymentTransaction时会影响StoreKit。您应该检查以确保没有发生错误,因为事务被取消以知道是否向用户显示错误消息。您通过检查错误的code来执行此操作。但用Error而不是NSError,没有定义code。我一直无法弄清楚如何从Error正确获取错误代码。在Swift 3中访问代码错误

这曾在以前的版本雨燕3:

func failedTransaction(_ transaction: SKPaymentTransaction) { 
    if let transactionError = transaction.error { 
     if transactionError.code != SKErrorCode.paymentCancelled.rawValue { 
      //show error to user 
     } 
    } 
    ... 
} 

现在errorErrorNSErrorcode不是成员。

+1

尝试'如果(transaction.error作为NSError).code!= SKErrorCode.PaymentCancelled {' –

+1

这是行之有效的,只是把它作为'NSError',谢谢@LeoDabus – Joey

回答

28

铸造到SKError似乎在Xcode 8和斯威夫特3是为我工作...

guard let error = transaction.error as? SKError else {return} 
    switch error.code { // https://developer.apple.com/reference/storekit/skerror.code 
    case .unknown: break 
    case .paymentCancelled: break 
    case .clientInvalid: break 
    case .paymentInvalid: break 
    case .paymentNotAllowed: break 
    case .cloudServiceNetworkConnectionFailed: break 
    case .cloudServicePermissionDenied: break 
    case .storeProductNotAvailable: break 
    } 

无需rawValue

+0

更正了正确的答案,因为它是最正确的。更喜欢这样做,而不是投射到“NSError”。证实它有效。 – Joey

+0

这不是很好吗?我有同样的问题,但在ALAssets。但是在那里似乎没有SKError等价物 –

85

另一种选择访问斯威夫特3错误类型的代码和域的属性是其扩展如下:

extension Error { 
    var code: Int { return (self as NSError).code } 
    var domain: String { return (self as NSError).domain } 
} 
+0

@Joey对不起,我在我的手机上,所以我无法检查正确的语法。 –

+2

查看@ murray-sagal的答案,最好使用新提供的SKError,而不是切换回Objective-C对象。 – o15a3d4l11s2

33

现在在Xcode 8和迅速3有条件的演员阵容总是成功,所以你需要做以下几点:

let code = (error as NSError).code 

并检查code您的需要。希望这有助于

+0

谢谢!这解决了我的问题 – xyzpatience

7

这是正确的(苹果公司自己的测试使用此方法):

if error._code == SKError.code.paymentCancelled.rawValue { ... } 

在另一方面,铸造NSError将可能很快被弃用:

let code = (error as NSError).code // CODE SMELL!! 
if code == SKError.code.paymentCancelled.rawValue { ... } 
+0

是否有链接到苹果自己的测试使用的方法? –

+0

那么,@AndrewPaulSimmons那里没有一个很好的干净的链接,但如果你检查出Apple的Swift的Git仓库,然后搜索“_code”,你可以看到他们所有的测试,他们以这种方式处理Error对象。检查出来:https://github.com/apple/swift/search?utf8=%E2%9C%93&q=_code – Rob

+3

你认为铸造到正确的类代码气味,但外部访问下划线的成员是好的?当然,你应该在'if let'或'guard let'中访问'.code',而不是盲目地假设演员工作。 – devios1