在Swift 3错误中访问代码


73

Xcode 8 beta 4中的新增NSError功能桥接到SwiftError协议类型。处理失败SKPaymentTransaction的时,这会影响StoreKit 。您应该检查以确保没有发生错误,因为交易被取消了才知道是否向用户显示错误消息。您可以通过检查错误的完成此操作code。但是使用Error代替NSError,没有code定义。我还无法弄清楚如何从中正确获取错误代码Error

这在Swift 3的先前版本中有效:

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

现在error是一个Errornot NSErrorcode不是成员。


1
试试if (transaction.error as NSError).code != SKErrorCode.PaymentCancelled {
Leo Dabus

1
那行得通,只是将其转换为NSError,谢谢@LeoDabus
Jordan H

Answers:


41

SKError在xCode 8和Swift 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


更新此答案的正确答案,因为它是最正确的。非常愿意这样做而不是强制转换为NSError。确认有效。
约旦H

那不是很好吗?我在ALAssets中有同样的问题。但是那里似乎没有等效的SKError
Anton Tropashko '17

@Joey Apple已从Xcode 9 beta 1和2的iOS 11公共API中删除了SKError。这是Xcode 9 beta 3已修复的错误。现在必须使用“ SwiftyStoreKit”!
Anirudha Mahale

140

在Swift 3错误类型中访问代码和域属性的另一种方法是将其扩展如下:

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

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

56

现在,在Xcode 8和Swift 3中,条件转换始终成功,因此您需要执行以下操作:

let code = (error as NSError).code

并检查code您的需求。希望这可以帮助


11

这是正确的(Apple自己的测试使用此方法):

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

另一方面,转换为NSError可能很快就会被弃用:

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

苹果自己的测试所使用的方法是否存在链接?
安德鲁·保罗·西蒙斯

好吧,@ AndrewPaulSimmons没有一个很好的干净链接,但是如果您查看Apple的Swift Git存储库,然后搜索“ _code”,则可以看到他们自己的所有测试,它们以这种方式处理Error对象。看看:github.com/apple/swift/search?utf8=%E2%9C%93&q=_code
Rob

8
您考虑将代码气味转换为正确的类,但是从外部访问带下划线的成员很好吗?当然,您应该.codeif let或中访问guard let,而不只是盲目地假设强制转换成功。
devios1 2013年

您说得对,@ devios1。“代码气味”是一种愚蠢的表达方式。
罗布

1

采用

error._code == NSURLErrorCancelled

匹配错误代码。


您在哪里找到这种方式...?这是工作!但我想知道你认识的地方。
Yodagama '20

我只是探索Xcode中的Error协议,是在哪里找到的。
古吉特·辛格

我没得到 您能否解释一下。在错误协议定义中,我什至找不到一个单词Error._code。
Yodagama

1

很多变化。这是Xcode 11的更新。

if let skError = transaction.error as? SKError, skError.code == .paymentCancelled { print("Cancelled") }

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.