Reputation: 1726
Summary:
Mail appears to flatten document packages when sending them.
Background:
I'm using subclassed UIDocument and FileWrappers to provide a document package for storing metadata, data and a thumbnail preview for my documents. I've made the necessary UTI incantations to get the document packages working locally.
I've added sharing support via UIActivityViewController. I'm sending the document using its fileURL. In testing with round-tripping my document package everything seems to be working well: export and import work great... almost.
Problem:
With Mail attachments, the document package arrives in a semi-flattened state (import no longer sees it as the document package). On examination of the document (on my Mac in TextWrangler) there is still directory structure and I can see the metadata, data, thumbnail but FileManager doesn't see it.
I've tried sharing the Mail attachment back to my app (via Copy to App) before the email is sent and that works fine.
Question:
Is Mail doing something unusual when moving the document package across a mail server?
I'm hoping to eventually support Open in Place and Files so I don't really want to get into wrapping shared documents in a Data blob etc. Does anyone know what's happening here and how to handle it while keeping my document a package?
Update: I've confirmed that Apple Mail is zipping the package but not changing the extension. So the file received is a zip of the original. How can I make sure Apple Mail sees this as a package and doesn't zip? And, if I can't, how can I recognize the file being imported is a zip without the zip extension?
Upvotes: 2
Views: 443
Reputation: 1726
Answer:
Mail is indeed zipping the document package.
According to my research, we don't need to alter the document-package approach (i.e. not have a flattened special export type). On import, we test if it's a directory. If it's not a directory then we try unzipping it from its source url instead of just copying it. It should be noted that unzipping needs to be handled through a third-party library.
I wish there was a built-in API for handling this but this seems to be the way to deal with it.
(Inelegant) example code:
// Check if directory
if let _ = try? FileManager.default.contentsOfDirectory(atPath: url.path) {
// It is - try copying to the documents url
do {
try FileManager.default.copyItem(at: url, to: destination)
} catch {
self.delegate?.documentFileManagerDidFail(error: NSLocalizedString("Failed to copy file: \(error)", comment: "Document failure message"))
return
}
} else {
// It's not - try unzipping to the documents url
do {
try FileManager.default.unzipItem(at: url, to: destination)
} catch {
self.delegate?.documentFileManagerDidFail(error: NSLocalizedString("Failed to unzip file: \(error)", comment: "Document failure message"))
return
}
}
Upvotes: 1