Home > Back-end >  Running reverseGeocodeLocation function create exception in SwiftPlay or return nothing
Running reverseGeocodeLocation function create exception in SwiftPlay or return nothing

Time:11-13

I tried to run the code provided in the answer from this post (Swift - Generate an Address Format from Reverse Geocoding) to get the address information from the latitude and longitude information. When I try to run this in Swift Playground (the standalone one from App Store and the one included with Xcode 14), it doesn't seem to do anything at first run. However, after drilling into it there seems to be a bad exception of some sort.

import CoreLocation

func getAddressFromLatLon(pdblLatitude: String, withLongitude pdblLongitude: String) {
    var center : CLLocationCoordinate2D = CLLocationCoordinate2D()
    let lat: Double = Double("\(pdblLatitude)")!
    //21.228124
    let lon: Double = Double("\(pdblLongitude)")!
    //72.833770
    let ceo: CLGeocoder = CLGeocoder()
    center.latitude = lat
    center.longitude = lon
    
    let loc: CLLocation = CLLocation(latitude:center.latitude, longitude: center.longitude)
    
    
    ceo.reverseGeocodeLocation(loc, completionHandler: { (placemarks, error) in
        if (error != nil)
        {
            print("reverse geodcode fail: \(error!.localizedDescription)")
        }
        let pm = placemarks! as [CLPlacemark]
        
        if pm.count > 0 {
            let pm = placemarks![0]
            print(pm.country)
            print(pm.locality)
            print(pm.subLocality)
            print(pm.thoroughfare)
            print(pm.postalCode)
            print(pm.subThoroughfare)
            var addressString : String = ""
            if pm.subLocality != nil {
                addressString = addressString   pm.subLocality!   ", "
            }
            if pm.thoroughfare != nil {
                addressString = addressString   pm.thoroughfare!   ", "
            }
            if pm.locality != nil {
                addressString = addressString   pm.locality!   ", "
            }
            if pm.country != nil {
                addressString = addressString   pm.country!   ", "
            }
            if pm.postalCode != nil {
                addressString = addressString   pm.postalCode!   " "
            }
            
            print(addressString)
        }
    })
}

getAddressFromLatLon(pdblLatitude: "42.48001070918", withLongitude: "-76.4511703657")

Looking at the error it says:

error: Execution was interrupted, reason: signal SIGABRT. The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.

I'm not following what's going on. If I use this code in a SwiftUI project, I also get bad exception that halts the program. It seems like an issue with the async function reverseGeocodeLocation, but I'm not sure why the error isn't caught even though it should be handling it in the closures.

I also tried using import MapKit instead of import Location. With MapKit, it doesn't error out but the code seems to do nothing. The coordinate should have come up as Lansing, NY. What am I missing here?

CodePudding user response:

After some playing around with the code I found the cause of the error. It is any attempt to create an instance of CLLocationCoordinate2D. Very strange. Since you can easily create the CLLocation instance directly from the lat and lon values you can avoid the error.

Here's a vastly cleaned up version of your code. This code eliminates all forced unwraps. The following runs just fine in an Xcode 14.1 playground.

Besides all of the code cleanup, it's the removal of using CLLocationCoordinate2D that resolved the main issue.

import CoreLocation

func getAddressFromLatLon(pdblLatitude: String, withLongitude pdblLongitude: String) {
    guard let lat = Double(pdblLatitude),
          let lon = Double(pdblLongitude) else { return }

    let loc = CLLocation(latitude: lat, longitude: lon)
    let ceo = CLGeocoder()

    ceo.reverseGeocodeLocation(loc, completionHandler: { (placemarks, error) in
        if let error {
            print("reverse geodcode fail: \(error)")
        } else if let placemarks, let pm = placemarks.first {
            var addressString = ""
            if let val = pm.subLocality {
                addressString  = val   ", "
            }
            if let val = pm.thoroughfare {
                addressString  = val   ", "
            }
            if let val = pm.locality {
                addressString  = val   ", "
            }
            if let val = pm.country {
                addressString  = val   ", "
            }
            if let val = pm.postalCode {
                addressString  = val   " "
            }

            print(addressString)
        }
    })
}

getAddressFromLatLon(pdblLatitude: "42.48001070918", withLongitude: "-76.4511703657")

Even if you create a brand new iOS playground in Xcode 14.1 and enter just the following code it will crash the playground:

import CoreLocation

print("Before")
let center = CLLocationCoordinate2D()
print("After")

Output:

Before
libc abi: terminating with uncaught exception of type NSException

  • Related