1

I am a beginner so sorry for my question.

I have a map and annotations in a Datas file.

Now I would like the user to be able to register an address with a form.

How do I go from a normal address to a

location: CLLocationCoordinate2D(latitude: 48.8566, longitude: 2.3522)

Thanks for your help

jnpdx
  • 45,847
  • 6
  • 64
  • 94
Ryo
  • 15
  • 1
  • 4

1 Answers1

0

Core Location has a "geocoder", which is what would take a street address and convert it to a CLLocationCoordinate2D.

This is from the official Apple documentation (https://developer.apple.com/documentation/corelocation/converting_between_coordinates_and_user-friendly_place_names):

func getCoordinate( addressString : String, 
        completionHandler: @escaping(CLLocationCoordinate2D, NSError?) -> Void ) {
    let geocoder = CLGeocoder()
    geocoder.geocodeAddressString(addressString) { (placemarks, error) in
        if error == nil {
            if let placemark = placemarks?[0] {
                let location = placemark.location!
                    
                completionHandler(location.coordinate, nil)
                return
            }
        }
            
        completionHandler(kCLLocationCoordinate2DInvalid, error as NSError?)
    }
}

Note that the preceding function uses callback functions and is an asynchronous function. That means that it does not return immediately -- instead, it finishes at an indeterminate time in the future and calls the callback function when it is finished.


Since you tagged the question SwiftUI, the following is a trivial example with SwiftUI:

import SwiftUI
import MapKit

class LocationManager : ObservableObject {
    @Published var location : CLLocationCoordinate2D?
    
    func convertAddress(address: String) {
        getCoordinate(addressString: address) { (location, error) in
            if error != nil {
                //handle error
                return
            }
            DispatchQueue.main.async {
                self.location = location
            }
        }
    }
    
    private func getCoordinate(addressString : String,
            completionHandler: @escaping(CLLocationCoordinate2D, NSError?) -> Void ) {
        let geocoder = CLGeocoder()
        geocoder.geocodeAddressString(addressString) { (placemarks, error) in
            if error == nil {
                if let placemark = placemarks?[0] {
                    let location = placemark.location!
                        
                    completionHandler(location.coordinate, nil)
                    return
                }
            }
                
            completionHandler(kCLLocationCoordinate2DInvalid, error as NSError?)
        }
    }
}

struct ContentView: View {
    @State var addressString = "1600 Pennsylvania Ave, Washington D.C."
    @StateObject private var locationManager = LocationManager()
    
    var body: some View {
        VStack {
            Text("Address: \(addressString)")
            if let location = locationManager.location {
                Text("Lat: \(location.latitude) Long: \(location.longitude)")
            }
        }.onAppear {
            locationManager.convertAddress(address: addressString)
        }
    }
}
jnpdx
  • 45,847
  • 6
  • 64
  • 94
  • Thank @jnpdx for your help ! I'm starting to get the hang of it. I'm going to learn about these basics by trying to create an input form for the address and see how to return the value in an object that will appear on the map. – Ryo Mar 25 '21 at 09:13
  • Great. You can mark the answer as accepted by clicking the green check mark. – jnpdx Mar 25 '21 at 13:15
  • Heck of a nightmare for me to implement this. I spent 2 days on it. Finally got some assistance and they helped me refactor. Ultimately it turned out a bit different. Maybe just my particular use of it was odd. At least it eventually got me there. Thank you for the solution as I got a start from it. – Jason Cramer Dec 17 '21 at 06:30