How to Share My Current Location to Uiactivityviewcontroller

How to share longitude and latitude using UIActivityViewController

Here is a complete answer in Swift 3.1 which I put together after getting pieces of information from several places. I hope it helps someone.

    @IBAction func didTapShareLocation(_ sender: UIButton) {
guard let carAddress = self.adressLabel.text, let lat = self.carCoordinates?.latitude, let lon = self.carCoordinates?.longitude else {
return
}

guard CLLocationCoordinate2DIsValid(self.carCoordinates!) else {
print("Location not valid!")
return
}

let carAddressString = "My car is at this address: \n\(carAddress)\n"

let vcardString = [
"BEGIN:VCARD",
"VERSION:3.0",
"N:;Shared Location;;;",
"FN:Shared Location",
"item1.URL;type=pref:http://maps.apple.com/?ll=\(lat),\(lon)",
"item1.X-ABLabel:map url",
"END:VCARD"
].joined(separator: "\n")

let directory = FileManager().urls(for: .cachesDirectory, in: .userDomainMask)

let path = directory.first!.path + "_vcard_for_location_sharing.loc.vcf"
do {
try vcardString.write(toFile: path, atomically: true, encoding: .ascii)
let url = NSURL(fileURLWithPath: path)

let objectsToShare = [url, carAddressString] as [Any]
let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)

activityVC.popoverPresentationController?.sourceView = sender
self.present(activityVC, animated: true, completion: nil)

}
catch {
print("problem saving vcard: \(error.localizedDescription)")
}
}

How to share user location from UIActivityViewController in Xcode

        @IBAction func shareLocation(sender: UIBarButtonItem) {
// print(receivedDictionary)
let postalAdress = CNMutablePostalAddress()
postalAdress.street = receivedDictionary["Name"] as! String
postalAdress.city = receivedDictionary["City"] as! String
postalAdress.state = receivedDictionary["State"] as! String
postalAdress.postalCode = receivedDictionary["ZIP"] as! String
postalAdress.country = receivedDictionary["Country"] as! String
postalAdress.ISOCountryCode = receivedDictionary["CountryCode"] as! String

let streetName = receivedDictionary["Name"] as! String

let urlAddress = receivedDictionary["FormattedAddressLines"] as! [String]
// print(urlAddress)
let postalContact = CNLabeledValue(label: streetName, value: postalAdress)
let urlAddressContact = CNLabeledValue(label: "map url", value: "http://maps.apple.com/maps?address=\(urlAddress.description)")

let contact = CNMutableContact()
contact.contactType = .Organization
contact.organizationName = streetName
contact.departmentName = streetName
contact.postalAddresses = [postalContact]
contact.urlAddresses = [urlAddressContact]

// create path

let directory = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)

let path = directory.first!.path!.stringByAppendingString("/\(streetName).loc.vcf")
// print(path)

do {
let contactData = try CNContactVCardSerialization.dataWithContacts([contact])

contactData.writeToFile(path, atomically: true)

let url = NSURL(fileURLWithPath: path)
// print(url)
let activityViewController = UIActivityViewController(activityItems: [url], applicationActivities: nil)
presentViewController(activityViewController, animated: true, completion: nil)
} catch {
print("CNContactVCardSerialization cannot save address")
}
}

Swift 5 - Sharing location using vCardURL

Forget all this stuff. The only thing you need is to share the Apple Maps URL with the coordinates... That's it! Tested on iOS 14 with UIKit and SwiftUI.

if let url = URL(string: "https://maps.apple.com?ll=\(latitude),\(longitude)") {
let activity = UIActivityViewController(activityItems: [url], applicationActivities: nil)
}

And then show the View Controller...

Converting address to apple maps link to share with others

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



Related Topics



Leave a reply



Submit