22

Seems like when converting our old code to beta 4, I keep casting Error to NSError. That will even lead sometimes to a warning "conditional cast from 'Error' to 'NSError' always succeeds". I feel like I'm not understanding how best to use Error. I want to get to thinks like error.code, error.localizedDescription... Is there good documentation or tutorials that explains these Error changes?

For example:

func webView(_ webView: UIWebView, didFailLoadWithError error: Error) { 

Right now I'm doing something like:

if let error = error as? NSError {
 if error.code == NSURLErrorCancelled {

But that gives the warning "Conditional cast from 'Error' to 'NSError' always succeeds"

Jason Hocker
  • 6,879
  • 9
  • 46
  • 79

3 Answers3

35

Error is bridgeable to NSError in the same way that String is bridgeable to NSString. I.e (error as NSError) would work.

if  (error as NSError).code == NSURLErrorCancelled { 
    // code
}
DerrickHo328
  • 4,664
  • 7
  • 29
  • 50
  • 9
    FYI: just tried to cast my own `enum MyError : Error { case test }`. The result: `nsError.code` prints `0`, `nsError.domain` prints `MyError`, `nsError.localizedDescription` prints `The operation couldn’t be completed. (MyError error 0.)` – Oleksii Nezhyborets Jan 09 '17 at 14:01
22

Do this:

Swift 3.0 and Swift 4.0

if error._code == NSURLErrorCancelled { }
Van Du Tran
  • 6,736
  • 11
  • 45
  • 55
4

Error catching in Swift 3 has changed. Search for NSError in Release Notes. Quote:

Additionally, error types imported from Cocoa and Cocoa Touch maintain all of the information in the corresponding NSError, so it is no longer necessary to catch let as NSError to extract (for example) the user-info dictionary. Specific error types also contain typed accessors for their common user-info keys. For example:

do {
    let regex = try NSRegularExpression(pattern: "(", options: [])
} catch {
    // error is of type NSError already
    print(error.localizedDescription)
}
Valeriy Van
  • 1,851
  • 16
  • 19
Code Different
  • 90,614
  • 16
  • 144
  • 163
  • How would I deal with this? func webView(_ webView: UIWebView, didFailLoadWithError error: Error) { Right now I'm doing something like if let error = error as? NSError { if error.code == NSURLErrorCancelled { But that gives the warning "Conditional cast from 'Error' to 'NSError' always succeeds" – Jason Hocker Aug 03 '16 at 13:17
  • 1
    I'm not sure if this is accurate. `error.code` is still not accessible, and alt-clicking `error` will show you that it's still inferred to be of the `Error` type. – Craig McMahon Sep 23 '16 at 12:21
  • @Jason the issue you're having is using `error as? NSError` instead of `error as NSError`. Error can always be casted to NSError so you don't need to use a conditional cast (i.e. `as?`) because it will always succeed (which is exactly what the error is telling you). – Ben Baron Nov 05 '16 at 14:38