Accessing code in Swift 3 Error

SwiftSwift3

Swift Problem Overview


New in Xcode 8 beta 4, NSError is bridged to the Swift Error protocol type. This affects StoreKit when dealing with failed SKPaymentTransactions. You ought to check to be sure the error didn't occur because the transaction was cancelled to know whether or not to show an error message to the user. You do this by examining the error's code. But with Error instead of NSError, there is no code defined. I haven't been able to figure out how to properly get the error code from Error.

This worked in the previous version of Swift 3:

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

Now that error is an Error not NSError, code is not a member.

Swift Solutions


Solution 1 - Swift

Another option to access code and domain properties in Swift 3 Error types is extending it as follow:

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

Solution 2 - Swift

Now in Xcode 8 and swift 3 the conditional cast is always succeeds, so you need do following:

let code = (error as NSError).code

and check the code for your needs. Hope this helps

Solution 3 - Swift

Casting to SKError seems to be working for me in xCode 8 and 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
    }

No need for rawValue.

Solution 4 - Swift

This is correct (Apple's own tests use this approach):

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

On the other hand, casting to NSError will probably be deprecated soon:

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

Solution 5 - Swift

Use

> error._code == NSURLErrorCancelled

to match the error code.

Solution 6 - Swift

A lot is changing. Here's update for Xcode 11.

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

Solution 7 - Swift

enum CheckValidAge : Error{
    case overrage
    case underage
}

func checkValidAgeForGovernmentJob(age:Int)throws -> Bool{
    if age < 18{
        throw CheckValidAge.underage
    }else  if age > 25{
        throw  CheckValidAge.overrage
    }else{
        return true
    }
}

do {
    try checkValidAgeForGovernmentJob(age: 17)
    print("You are valid for government job ")
}catch CheckValidAge.underage{
    print("You are underage for government job ")
}catch CheckValidAge.overrage{
    print("You are overrage for government job ")
}

try checkValidAgeForGovernmentJob(age: 17) OutPut : You are underage for government job

try checkValidAgeForGovernmentJob(age: 26) OutPut : You are overrage for government job

try checkValidAgeForGovernmentJob(age: 18) OutPut : You are valid for government job

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJordan HView Question on Stackoverflow
Solution 1 - SwiftLeo DabusView Answer on Stackoverflow
Solution 2 - SwiftAndrey M.View Answer on Stackoverflow
Solution 3 - SwiftMurray SagalView Answer on Stackoverflow
Solution 4 - SwiftRobView Answer on Stackoverflow
Solution 5 - SwiftGurjit SinghView Answer on Stackoverflow
Solution 6 - SwiftCodetardView Answer on Stackoverflow
Solution 7 - SwiftPavnesh SinghView Answer on Stackoverflow