swiftios8nserrordidfailwitherror

Swift: Corelocation handling NSError in didFailWithError


I'm using CoreLocation to successfully determine the user's location. However when i try to use the CLLocationManagerDelegate method:

func locationManager(_ manager: CLLocationManager!, didFailWithError error: NSError!)

I run into problems with the error term.

func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
    println("didFailWithError \(error)")

    if let err = error {
        if err.code == kCLErrorLocationUnknown {
            return
        }
    }
}

This results in a 'Use of unresolved identifier kCLErrorLocationUnknown' error message. I know that the kCLErrors are enums and that they have evolved in Swift but I'm stuck.


Solution

  • Update for Swift 4: The error is now passed to the callback as error: Error which can be cast to an CLError:

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        if let clErr = error as? CLError {
            switch clErr.code {
            case CLError.locationUnknown:
                print("location unknown")
            case CLError.denied:
                print("denied")
            default:
                print("other Core Location error")
            }
        } else {
            print("other error:", error.localizedDescription)
        }
    }
    

    Older answer: The Core Location error codes are defined as

    enum CLError : Int {
        case LocationUnknown // location is currently unknown, but CL will keep trying
        case Denied // Access to location or ranging has been denied by the user
        // ...
    }
    

    and to compare the enumeration value with the integer err.code, toRaw() can be used:

    if err.code == CLError.LocationUnknown.toRaw() { ...
    

    Alternatively, you can create a CLError from the error code and check that for the possible values:

    if let clErr = CLError.fromRaw(err.code) {
        switch clErr {
        case .LocationUnknown:
            println("location unknown")
        case .Denied:
            println("denied")
        default:
            println("unknown Core Location error")
        }
    } else {
        println("other error")
    }
    

    UPDATE: In Xcode 6.1 beta 2, the fromRaw() and toRaw() methods have been replaced by an init?(rawValue:) initializer and a rawValue property, respectively:

    if err.code == CLError.LocationUnknown.rawValue { ... }
    
    if let clErr = CLError(rawValue: code) { ... }