Getting the files your app stores on the device back out so you can look at them for debugging or similar is not as easy as it could be. There’s a number of filebrowser libraries out there, but it’s a bit overkill or occasional use and probrably not something you want to ship with your app either. Here’s how to create a zip file from any directory and move it off the device using the share sheet (UIActivityViewController).
I wrote this in a hurry, so there’s lots of force unwrapping. Fine for development, but if you intend to ship this, make sure you deal with potential errors properly.
let fm = FileManager.default
let baseDirectoryUrl = fm.urls(for: .documentDirectory, in: .userDomainMask).first!
// populate the app's documents directory with some example files
for i in 1...10 {
let fileUrl = baseDirectoryUrl.appendingPathComponent("\(i).txt")
let str = "\(i)"
try! str.write(to: fileUrl, atomically: true, encoding: .utf8)
}
// this will hold the URL of the zip file
var archiveUrl: URL?
// if we encounter an error, store it here
var error: NSError?
let coordinator = NSFileCoordinator()
// zip up the documents directory
// this method is synchronous and the block will be executed before it returns
// if the method fails, the block will not be executed though
// if you expect the archiving process to take long, execute it on another queue
coordinator.coordinate(readingItemAt: baseDirectoryUrl, options: [.forUploading], error: &error) { (zipUrl) in
// zipUrl points to the zip file created by the coordinator
// zipUrl is valid only until the end of this block, so we move the file to a temporary folder
let tmpUrl = try! fm.url(
for: .itemReplacementDirectory,
in: .userDomainMask,
appropriateFor: zipUrl,
create: true
).appendingPathComponent("archive.zip")
try! fm.moveItem(at: zipUrl, to: tmpUrl)
// store the URL so we can use it outside the block
archiveUrl = tmpUrl
}
if let archiveUrl = archiveUrl {
// bring up the share sheet so we can send the archive with AirDrop for example
let avc = UIActivityViewController(activityItems: [archiveUrl], applicationActivities: nil)
present(avc, animated: true)
} else {
print(error)
}