How to share longitude and latitude using UIActivityViewController - ios

I'm trying to share a (longitude, latitude) associated with your's location in a UIActivityViewController so that the user can share the location in an SMS with someone else and it shows up as a clickable little map as shown below.
I know how to share an address as a text. Here is my code for sharing the address:
#IBAction func didTapShareLocation(_ sender: UIButton) {
guard let carAddress = self.adressLabel.text else {
return
}
let textToShare = "My car is at this address: \(carAddress)"
let objectsToShare = [textToShare] as [Any]
let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
activityVC.popoverPresentationController?.sourceView = sender
myParentVC?.present(activityVC, animated: true, completion: nil)
}

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)")
}
}

Related

Share Image Via URL

I am creating Images app from my WordPress website with json and i am using swift, i want to share image on Social Networks from my app , currently i tried this code it works but only with image name i want to share image from image url, is that possible ?
this is my code
let myWebsite = NSURL(string: "nice")
let img: UIImage = UIImage(named:"splash")!
guard let url = myWebsite else {
print("nothing found")
return
}
let shareItems:Array = [img,url]
let activityViewController:UIActivityViewController = UIActivityViewController(activityItems: shareItems, applicationActivities: nil)
activityViewController.excludedActivityTypes = [UIActivity.ActivityType.print, UIActivity.ActivityType.postToWeibo, UIActivity.ActivityType.copyToPasteboard, UIActivity.ActivityType.addToReadingList, UIActivity.ActivityType.postToVimeo]
self!.present(activityViewController, animated: true, completion: nil)
If you need to download an image and then share you should do that separately, there is no single method that does that for you. Here is how:
func shareImageFromUrl(_ string: String) {
guard let myUrl = URL(string: string) else {
print("Invalid url!")
return
}
URLSession.shared.dataTask(with: myUrl) { (data, _, _) in
guard let data = data,
let image = UIImage(data: data) else
{ return }
let activityViewController:UIActivityViewController = UIActivityViewController(activityItems: [image], applicationActivities: nil)
activityViewController.excludedActivityTypes = [UIActivity.ActivityType.print, UIActivity.ActivityType.postToWeibo, UIActivity.ActivityType.copyToPasteboard, UIActivity.ActivityType.addToReadingList, UIActivity.ActivityType.postToVimeo]
DispatchQueue.main.async {
self.present(activityViewController, animated: true, completion: nil)
}
}.resume()
}

share pdf file using UIActivityViewController in Swift 4

I am using UIActivityViewController to share a PDF file:
let pdfFilePath = URL(string: "https://www.tutorialspoint.com/swift/swift_tutorial.pdf")
let pdfData = NSData(contentsOf: pdfFilePath!)
let activityVC = UIActivityViewController(activityItems: [pdfData!], applicationActivities: nil)
present(activityVC, animated: true, completion: nil)
The below result is displayed:
What I want is to display more features like "copy to Books" and "Add to Notes" like the following:
If you want to share your pdf file which is on the server and you have a URL. Then first you download that file in your device and then share that file to any other person.
If you using Alamofire in your code then there is code.
Stape 1
import Alamofire
Stape 2
Add this function in your class:-
func downloadPdf(downloadUrl : String, fileName: String, completionHandler:#escaping(String, Bool)->()){
let destinationPath: DownloadRequest.DownloadFileDestination = { _, _ in
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0];
let fileURL = documentsURL.appendingPathComponent("\(fileName).pdf")
return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
}
print(downloadUrl)
Alamofire.download(downloadUrl, to: destinationPath)
.downloadProgress { progress in
}
.responseData { response in
print("response: \(response)")
switch response.result{
case .success:
if response.destinationURL != nil, let filePath = response.destinationURL?.absoluteString {
completionHandler(filePath, true)
}
break
case .failure:
completionHandler("", false)
break
}
}
}
Stape 3
Add this action on your share button
#IBAction func btnShareAction(_ sender: UIButton) {
let myURL = "http://www.demo.com/demo.pdf" // change this with your URL
self.downloadPdf(downloadUrl : myURL, fileName: "invoice") { (localFileUrl, bool) in
let fileURL = NSURL(fileURLWithPath: localFileUrl)
let activityViewController = UIActivityViewController(activityItems: [fileURL], applicationActivities: nil)
self.present(activityViewController, animated: true, completion: nil)
}
}
Simple Steps! Copy paste the give code
#objc private func btnShareTapped(_ sender: UIButton) {
guard let urlString = strURL,
let url = URL(string: urlString),
let docPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last else {
return
}
let actualPath = docPath.appendingPathComponent("Statement.pdf")
let pdfData = try? Data.init(contentsOf: url)
do {
try pdfData?.write(to: actualPath, options: .atomic)
let fileURL = URL(fileURLWithPath: actualPath.absoluteString)
let activityVC = UIActivityViewController(activityItems: [fileURL],
applicationActivities: nil)
present(activityVC, animated: true)
} catch {
debugPrint("Pdf could not be saved")
}
}

how to share QR created image swift 4

I am creating QR code in swift and assigning it to an imageView
when I try to share that image with generated code, it does not shares that image,
func createCode()
{
let text = email
let data = text.data(using: .ascii, allowLossyConversion: false)
fillter = CIFilter(name: "CIQRCodeGenerator")
fillter.setValue(data, forKey: "inputMessage")
let transform = CGAffineTransform(scaleX: 5.0, y: 5.0)
CreatedImage = UIImage(ciImage: (fillter.outputImage?.transformed(by: transform))!)
imageCode.image = CreatedImage as UIImage
}
and this is share button
#IBAction func shareButtonPressed(_ sender: Any)
{
let activityItem: [UIImage] = [imageCode.image!]
let activity = UIActivityViewController(activityItems: activityItem as [UIImage], applicationActivities: [])
activity.popoverPresentationController?.sourceView = self.view
self.present(activity, animated: true, completion: nil)
}
it shows like it has nothing to share, it does not pick any bit of image
Have you created a variable to store the image somewhere e.g.
var generatedImage: UIImage?
Assuming then, that I have read your question correctly, in your creation function you can cast the image at the end of the function e.g:
generatedImage = imageCode.image
Then in your share function you could say:
guard let validQR = generatedImage else { return }
let activityItem: [UIImage] = [validQR]
let activity = UIActivityViewController(activityItems: activityItem as [UIImage], applicationActivities: [])
activity.popoverPresentationController?.sourceView = self.view
self.present(activity, animated: true, completion: nil)
I tested with an image from my Bundle e.g:
generatedImage = UIImage(named: "SCNPyramid")
And I was able to share the image :)
after searching all..
I cam I to know that make a programmatically screen shot of desired view, that is sent..
I have been having the same problem and solved it by first saving the generated qr code image to a file and then sharing the file url.
private func shareQRCode() {
guard let qrcode = self.qrCodeImage,
let data = qrcode.pngData(),
let url = self.saveInCache(data: data, fileName: "QRCode.png") else { return }
// set up activity view controller
let imageToShare = [url]
let activityViewController = UIActivityViewController(activityItems: imageToShare, applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view // so that iPads won't crash
// work around to prevent dismissing current view after saving image
let tempController = TransparentViewController()
tempController.modalPresentationStyle = .overFullScreen
activityViewController.completionWithItemsHandler = { [weak tempController] _, _, _, _ in
if let presentingViewController = tempController?.presentingViewController {
presentingViewController.dismiss(animated: false, completion: nil)
} else {
tempController?.dismiss(animated: false, completion: nil)
}
}
present(tempController, animated: true) { [weak tempController] in
tempController?.present(activityViewController, animated: true, completion: nil)
}
}
Here is the code for saveInCache function:
private func saveInCache(data: Data, fileName: String) -> URL? {
let paths = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)
let path = paths[0]
let fileUrl = path.appendingPathComponent(fileName)
let fileManager = FileManager.default
if self.pathExists(fileUrl) {
do {
try fileManager.removeItem(at: fileUrl)
} catch { return fileUrl }
}
guard fileManager.createFile(atPath: fileUrl.path, contents: data, attributes: nil) else {
return nil
}
return fileUrl
}
private func pathExists(_ path: URL) -> Bool {
let fileManager = FileManager.default
var isDir: ObjCBool = false
if fileManager.fileExists(atPath: path.path, isDirectory: &isDir) {
if isDir.boolValue {
// file exists and is a directory
return true
} else {
// file exists and is not a directory
return true
}
} else {
// file does not exist
return false
}
}
And here a simple Transparent View Controller for ActivityViewController work around:
final class TransparentViewController: UIViewController {
override func viewDidLoad() {
self.view.backgroundColor = .clear
}
}

How can I share location from my app to WhatsApp in Swift 3

I'm trying to share a location from my iOS app to WhatsApp and I want it to look like this:
What I'm doing is sending vCard with this code :
func vCardURL(from coordinate: CLLocationCoordinate2D, with name: String?) -> URL {
let vCardFileURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("Shared Location.loc.vcf")
let vCardString = [
"BEGIN:VCARD",
"VERSION:3.0",
//"PRODID:-//Apple Inc.//iPhone OS 10.3.2//EN",
"N:;My Location;;;",
"FN:My Location",
"item1.URL;type=pref:https://maps.apple.com/?ll=50.359890\\,12.934560&q=My%20Location&t=m",
"item1.X-ABLabel:map url",
"END:VCARD"
].joined(separator: "\n")
do {
try vCardString.write(toFile: vCardFileURL.path, atomically: true, encoding: .utf8)
} catch let error {
print("Error, \(error.localizedDescription), saving vCard: \(vCardString) to file path: \(vCardFileURL.path).")
}
print(vCardString)
return vCardFileURL
} // end of function
// calling the methood above
let vURL = LocationVCard.vCardURL(from: self.newLocation.coordinate, with: "Berlin")
let activityViewController = UIActivityViewController(activityItems: [vURL], applicationActivities: nil)
self.present(activityViewController, animated: true, completion: nil)
But I always end up with this style instead of what I want:
No need to save the vCard string to a file, just convert it to Data and wrap it with NSItemProvider with the correct type identifier public.vcard, and it'll work just fine:
let data = vCardString.data(using: .utf8)! as NSData
let item = NSItemProvider(item: data, typeIdentifier: "public.vcard")
let activityViewController = UIActivityViewController(activityItems: [item], applicationActivities: nil)

Ios Swift Sharing on WhatsApp and FB

I am experiencing a few issue with the Share option in iOS8.
With the below code I am able to correctly share by Email and Text(SMS) including my text strings and my image.
But when I try to share to Facebook, the generated post only includes my image (skipping the text strings) while if I try to share on WhatsApp, the image is skipped and only the text strings are passed.
Does anybody have any suggestion?
My code:
#IBAction func shareButtonClicked(sender: UIBarButtonItem) {
var kidToShare1 : String? = noKids
if selectedKid == nil {
kidToShare1 = noKids
println("kid is nil")
} else {
kidToShare1 = selectedKid!.kidName
}
let kidToShare = NSLocalizedString("Kid: ", comment:"Kid to share") + kidToShare1!
let imageToShare = photo! ?? noPhoto!
let textToShare = NSLocalizedString("Event Description: ", comment:"Text to share") + descriptionText as NSString
let dateToShare = NSLocalizedString("Event Date: ", comment: "Date to share") + formatDate(date) as NSString
let message = NSLocalizedString("My App", comment: "Main sharing message")
let objectsToShare = [message, dateToShare, kidToShare, textToShare, imageToShare]
let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
activityVC.excludedActivityTypes = [UIActivityTypeAirDrop, UIActivityTypeAirDrop, UIActivityTypeAssignToContact, UIActivityTypeAddToReadingList,UIActivityTypeCopyToPasteboard,UIActivityTypeSaveToCameraRoll,UIActivityTypePrint]
self.presentViewController(activityVC, animated: true, completion: nil)
}
}

Resources