Search code examples
iosswiftcllocationeventkit

CLGeocoder always returns nil for latitude / longitude


I'm trying to get latitude/longitude coordinates to use with location based reminders (Eventkit) The address is valid and is sent to the function correctly, if I provide an optional for the coordinates it is returned by the function ok, so the function seems to work but the geocoder is not converting the address as expected. I can't see why it won't.

var lat: Double?
var lon: Double?

func getLocation(address: String)  -> CLLocation {
    let geocoder = CLGeocoder()
    geocoder.geocodeAddressString(address) { placemarks, error in
        guard let placemark = placemarks?.first else { return }
        
        let coordinate = placemark.location?.coordinate
        lat = coordinate?.latitude //Is always nil
        lon = coordinate?.longitude //Is always nil
        
    }
    // Note: providing ?? sample coordinates in the return below works

    return CLLocation(latitude: lat!, longitude: lon!)
}

if self.locationChoice == "Dog's Home" {
    
    let address = "\(self.dog.addressLine1),\(self.dog.town),\(self.dog.postcode)"
    let structuredLocation = EKStructuredLocation(title: address)
    
    structuredLocation.geoLocation = getLocation(address: address)// asking for CLLocation
    structuredLocation.radius = 500
    let alarm = EKAlarm()
    if self.whenArrivingOrLeaving == 0 {
        alarm.proximity = EKAlarmProximity.enter
    }else {
        alarm.proximity = EKAlarmProximity.leave
    }
    alarm.structuredLocation = structuredLocation
    newReminder.addAlarm(alarm)
}

Solution

  • It's not nil you return a value from an asynchnous method you should use a completion

    func getLocation(address: String,completion:@escaping(CLLocation? -> ())) {
         let geocoder = CLGeocoder()
         geocoder.geocodeAddressString(address) { placemarks, error in
               guard let placemark = placemarks?.first else { return } 
               completion(placemark.location)
         }
    
    }
    

    Call

    getLocation(address: address) { loc in 
       // embed all code here 
    }