I have content stored in String variable in my app and I want to save it as a file to the Files app. Well, it's easy and described for example here Save document to "Files" App in swift but I'm wondering whether is it possible to assign custom name to the file. iOS assigns implicit name Text.txt. Thanks.
Asked
Active
Viewed 3,459 times
1
-
Pass the URL to your file in the activity items array parameter in the constructor. – joeybladb Jan 03 '19 at 17:21
-
I do not have file yet. I have just file content programatically generated to String variable. let sharing = UIActivityViewController(activityItems: [export], applicationActivities: nil) where export is String var – Dawy Jan 03 '19 at 17:26
-
Break it into separate tasks: take your String and Convert it to Data using a UTF8 encoding. Figure our where in your file system you want to save the data -- I suggest the temporary directory -- and make a URL. Use a method on Data to write the data to that URL. Hand that URL to UIActivityViewController. You should be able to find examples of how to do each of these steps by googling around. Good luck! – joeybladb Jan 03 '19 at 23:00
-
Thanks I did it this way. Little struggled with deletion of the temp file only after UIActivityViewController disappearing but finally solved with defining of completionWithItemsHandler. I'll put my code below for others reference. Maybe not perfect but it works for me. – Dawy Jan 03 '19 at 23:45
1 Answers
2
@IBAction func btnExportData(_ sender: Any) {
let prompt = UIAlertController(title: "Export data for counter", message: "Provide file name:", preferredStyle: .alert)
prompt.addTextField {(textField) in textField.text = ""}
prompt.addAction(UIAlertAction(title: "Export", style: .default, handler: {
(_) in
do {
let export = try self.objMeasurements.exportData(forCounterID: self.counterID)
let fm = FileManager.default
let fileFolder = fm.urls(for: .documentDirectory, in: .userDomainMask).first!
let fileURL = fileFolder.appendingPathComponent(prompt.textFields![0].text! + ".csv")
do {
try export.write(to: fileURL, atomically: true, encoding: String.Encoding.utf8)
} catch {
self.showOkAlert(messageTitle: "File " + fileURL.absoluteString + " can't be created.", messageText: "Method: btnExportData", okText: "OK", {})
}
let sharing = UIActivityViewController(activityItems: [fileURL], applicationActivities: nil)
sharing.completionWithItemsHandler = {
(type, completed, items, error) in
do {
try fm.removeItem(at: fileURL)
self.showOkAlert(messageTitle: "Temporary file was successfully deleted.", messageText: fileURL.absoluteString, okText: "OK", {})
} catch {
self.showOkAlert(messageTitle: "File " + fileURL.absoluteString + " can't be deleted.", messageText: "Method: btnExportData", okText: "OK", {})
}
}
sharing.popoverPresentationController?.barButtonItem = self.navigationItem.rightBarButtonItems?.first
self.present(sharing, animated: true, completion: nil)
} catch measurementErrors.measurementGetFailed(let message) {
self.showOkAlert(messageTitle: message[0], messageText: message[1], okText: "OK", {})
} catch counterErrors.counterGetFailed(let message) {
self.showOkAlert(messageTitle: message[0], messageText: message[1], okText: "OK", {})
} catch elementErrors.elementGetFailed(let message) {
self.showOkAlert(messageTitle: message[0], messageText: message[1], okText: "OK", {})
} catch {
self.showOkAlert(messageTitle: "Unknown error during data export", messageText: "Method: btnExportData", okText: "OK", {})
}
}))
prompt.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
present(prompt, animated: true, completion: nil)
}

Dawy
- 770
- 6
- 23
-
1Note that completionWithItemsHandler may be called several times and you can end up deleting the file too early. – algrid Dec 23 '20 at 19:01