Search code examples
iosswiftuiactivityviewcontrollerapple-maps

Converting address to apple maps link to share with others


I would like to convert an address into an apple maps link and send it to someone with UIActivityViewController. I know about CLGeocoder, and I know how to convert string to coordinates and vice versa, but I don't know how this would be useful. Specifically, I would like to be able to generate the apple maps link so that I could share it with UIActivityViewController. Here is the activityViewController code I have so far:

@IBAction func sendAddress(_ sender: UIButton) {
    // how to generate something like this link below, except in apple maps???
    let text = URL(string:"https://www.google.com/maps/@42.585444,13.007813,6z")
    
    // making activity view controller
    let textToShare = [ text ]
    let activityViewController = UIActivityViewController(activityItems: textToShare as [Any], applicationActivities: nil)
    activityViewController.popoverPresentationController?.sourceView = self.view // so that iPads won't crash
    
    // present
    self.present(activityViewController, animated: true, completion: nil)
    
}

All I need is how to create the link either from coordinates, or an address, because I am pretty sure you can share the URL as a clickable link with messages, as I tested it with reminders which is built into the iOS simulator.

Thanks


Solution

  • You need to do 2 things

    1. Get current location
    2. use the lat, long to open the UIActivityController

    To get the current location as lat, long you can use CLCoordinate

    First add these to your info.plist you can modify the text as your will

     <key>NSLocationAlwaysUsageDescription</key>
    <string>Will you allow this app to always know your location?</string>
    <key>NSLocationWhenInUseUsageDescription</key>
    <string>Do you allow this app to know your current location?</string>
    <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
    <string>Do you allow this app to know your current location?</string>
    

    Now in your class create an object of CLLocationManager and implement it's delegate, since CLLocationManager is in CoreLocation we need to import it

    import CoreLocation
    

    Now create an object of locationManager

    let locationManager = CLLocationManager()
    

    Now in viewDidload or you may even create a separate method add the below code to setup locationManager

        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestAlwaysAuthorization()
    
        if CLLocationManager.locationServicesEnabled(){
            locationManager.startUpdatingLocation()
        }
    

    Now implements its delegate and get the coordinate

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let userLocation :CLLocation = locations[0] as CLLocation
        let coordinates = userLocation!.coordinate
        print("locations = \(coordinates.latitude) \(coordinates.longitude)")
        }
    
    

    Now you can invoke the below function to open action Sheet

    if let shareObject = self.activityItems(latitude: lat, longitude: long) {
           //open UIActivityViewController 
    }
    

    Use this method to construct vCard to share

    func activityItems(latitude: Double, longitude: Double) -> [AnyObject]? {
        var items = [AnyObject]()
    
        let locationTitle = "Shared Location"
        let URLString = "https://maps.apple.com?ll=\(latitude),\(longitude)"
    
        if let url = NSURL(string: URLString) {
            items.append(url)
        }
    
        let locationVCardString = [
            "BEGIN:VCARD",
            "VERSION:3.0",
            "PRODID:-//Joseph Duffy//Blog Post Example//EN",
            "N:;\(locationTitle);;;",
            "FN:\(locationTitle)",
            "item1.URL;type=pref:\(URLString)",
            "item1.X-ABLabel:map url",
            "END:VCARD"
            ].joinWithSeparator("\n")
    
        guard let vCardData = locationVCardString.dataUsingEncoding(NSUTF8StringEncoding) else {
            return nil
        }
    
        let vCardActivity = NSItemProvider(item: vCardData, typeIdentifier: kUTTypeVCard as String)
    
        items.append(vCardActivity)
    
        items.append(locationTitle)
    
        return items
    }
    

    Reference link: https://josephduffy.co.uk/posts/ios-share-sheets-the-proper-way-locations