I want to share some files I have locally in my app using Share Sheet functionality on iPhone. I display the file in a UIWebView
and when the user clicks the share sheet, I want to show options (email, WhatsApp, etc. ) to share the file displayed on the UIWebView
. I know that we can use
func displayShareSheet(shareContent:String) { let activityViewController = UIActivityViewController(activityItems: [shareContent as NSString], applicationActivities: nil) presentViewController(activityViewController, animated: true, completion: {}) }
to share a string for example. How do I change this code to share documents?
Touch and hold the file, then tap Share. Tip: To send a smaller version of the file, tap Compress before you tap Share. Then touch and hold the compressed version of the file (identified as a zip file), and tap Share. Choose an option for sending (for example, AirDrop, Messages, or Mail), then tap Send.
iCloud Drive lets you securely access all of your documents from your iPhone, iPad, iPod touch, Mac, or PC. No matter which device you're using, you'll always have the most up to date documents when and where you need them.
Swift 4.2 and Swift 5
If you already have a file in a directory and want to share it, just add it's URL into activityItems
:
let fileURL = NSURL(fileURLWithPath: "The path where the file you want to share is located") // Create the Array which includes the files you want to share var filesToShare = [Any]() // Add the path of the file to the Array filesToShare.append(fileURL) // Make the activityViewContoller which shows the share-view let activityViewController = UIActivityViewController(activityItems: filesToShare, applicationActivities: nil) // Show the share-view self.present(activityViewController, animated: true, completion: nil)
If you need to make the file:
I'm using this extension to make files from Data
(read the comments in the code for explanation how it works):
As in the typedef's answer, get the current documents directory:
/// Get the current directory /// /// - Returns: the Current directory in NSURL func getDocumentsDirectory() -> NSString { let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) let documentsDirectory = paths[0] return documentsDirectory as NSString }
Extension for Data
:
extension Data { /// Data into file /// /// - Parameters: /// - fileName: the Name of the file you want to write /// - Returns: Returns the URL where the new file is located in NSURL func dataToFile(fileName: String) -> NSURL? { // Make a constant from the data let data = self // Make the file path (with the filename) where the file will be loacated after it is created let filePath = getDocumentsDirectory().appendingPathComponent(fileName) do { // Write the file from data into the filepath (if there will be an error, the code jumps to the catch block below) try data.write(to: URL(fileURLWithPath: filePath)) // Returns the URL where the new file is located in NSURL return NSURL(fileURLWithPath: filePath) } catch { // Prints the localized description of the error from the do block print("Error writing the file: \(error.localizedDescription)") } // Returns nil if there was an error in the do-catch -block return nil } }
Examples how to use:
Share image-files:
// Your image let yourImage = UIImage()
in png-file
// Convert the image into png image data let pngImageData = yourImage.pngData() // Write the png image into a filepath and return the filepath in NSURL let pngImageURL = pngImageData?.dataToFile(fileName: "nameOfYourImageFile.png") // Create the Array which includes the files you want to share var filesToShare = [Any]() // Add the path of png image to the Array filesToShare.append(pngImageURL!) // Make the activityViewContoller which shows the share-view let activityViewController = UIActivityViewController(activityItems: filesToShare, applicationActivities: nil) // Show the share-view self.present(activityViewController, animated: true, completion: nil)
in jpg-file
// Convert the image into jpeg image data. compressionQuality is the quality-compression ratio in % (from 0.0 (0%) to 1.0 (100%)); 1 is the best quality but have bigger filesize let jpgImageData = yourImage.jpegData(compressionQuality: 1.0) // Write the jpg image into a filepath and return the filepath in NSURL let jpgImageURL = jpgImageData?.dataToFile(fileName: "nameOfYourImageFile.jpg") // Create the Array which includes the files you want to share var filesToShare = [Any]() // Add the path of jpg image to the Array filesToShare.append(jpgImageURL!) // Make the activityViewContoller which shows the share-view let activityViewController = UIActivityViewController(activityItems: filesToShare, applicationActivities: nil) // Show the share-view self.present(activityViewController, animated: true, completion: nil)
Share text-files:
// Your String including the text you want share in a file let text = "yourText" // Convert the String into Data let textData = text.data(using: .utf8) // Write the text into a filepath and return the filepath in NSURL // Specify the file type you want the file be by changing the end of the filename (.txt, .json, .pdf...) let textURL = textData?.dataToFile(fileName: "nameOfYourFile.txt") // Create the Array which includes the files you want to share var filesToShare = [Any]() // Add the path of the text file to the Array filesToShare.append(textURL!) // Make the activityViewContoller which shows the share-view let activityViewController = UIActivityViewController(activityItems: filesToShare, applicationActivities: nil) // Show the share-view self.present(activityViewController, animated: true, completion: nil)
Other files:
You can make a file from anything which is in Data
format and as far as I know, almost everything in Swift can be converted into Data
like String
, Int
, Double
, Any
...:
// the Data you want to share as a file let data = Data() // Write the data into a filepath and return the filepath in NSURL // Change the file-extension to specify the filetype (.txt, .json, .pdf, .png, .jpg, .tiff...) let fileURL = data.dataToFile(fileName: "nameOfYourFile.extension") // Create the Array which includes the files you want to share var filesToShare = [Any]() // Add the path of the file to the Array filesToShare.append(fileURL!) // Make the activityViewContoller which shows the share-view let activityViewController = UIActivityViewController(activityItems: filesToShare, applicationActivities: nil) // Show the share-view self.present(activityViewController, animated: true, completion: nil)
I want to share my solution of UIActivityViewController and sharing text as a image file. This solution works for sharing via Mail and even Save to Dropbox.
@IBAction func shareCsv(sender: AnyObject) { //Your CSV text let str = self.descriptionText.text! filename = getDocumentsDirectory().stringByAppendingPathComponent("file.png") do { try str.writeToFile(filename!, atomically: true, encoding: NSUTF8StringEncoding) let fileURL = NSURL(fileURLWithPath: filename!) let objectsToShare = [fileURL] let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil) self.presentViewController(activityVC, animated: true, completion: nil) } catch { print("cannot write file") // failed to write file – bad permissions, bad filename, missing permissions, or more likely it can't be converted to the encoding } } func getDocumentsDirectory() -> NSString { let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) let documentsDirectory = paths[0] return documentsDirectory }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With