Is there a foolproof way of saving the URL of a UIDocument so an application can resume editing the document on next launch?
I have tried various ways of saving the URL, but sometimes the document URL will slightly differ from what is expected.
For example, the following code:
var scoresURL = FileManager.default.urls(for: .documentDirectory,
in: .userDomainMask).first!
might return this:
file:///var/mobile/Containers/Data/Application/50E947C1-7A30-40A0-8BB6-1C3BB41A1218/Documents
But a documented loaded using UIDocumentBrowserViewController might set the fileURL path of the UIDocument to this:
file:///private/var/mobile/Containers/Data/Application/50E947C1-7A30-40A0-8BB6-1C3BB41A1218/Documents
It is these slight differences that make me wonder if I am simply doing the wrong thing by maintaining a MRU list.
These issues appear only on an actual device. The simulator is paths are stable, at least until the arbitrary times the simulator decides to reset its state.
CodePudding user response:
You could check which one is the last modified one:
var scoresURL = FileManager.default.urls(for: .documentDirectory,
in: .userDomainMask)
let modificationDatesAndURL: (Date, URL) = scoresURL.compactMap { filePathURL in
let attributes = FileManager.default.attributesOfItem(atPath: urlPath.path)
if let modificationDate = attributes?[.modificationDate] as? Date {
return (modificationDate, filePathURL)
} else {
return nil
}
}
/// Sort tuples by date
let lastModifiedScoreDateAndURL = modificationDatesAndURL.sorted(by: { $0.0 < $1.0 }).first
let lastModifiedURL = lastModifiedScoreDateAndURL.1
CodePudding user response:
I think that bookmarkData
is what you may be looking for.
The docs don't say much but the general idea is that you persist the bookmark data using this method
func bookmarkData(
options: URL.BookmarkCreationOptions = [],
includingResourceValuesForKeys keys: Set<URLResourceKey>? = nil,
relativeTo url: URL? = nil
) throws -> Data
and then recreate the URL using this initializer:
init(
resolvingBookmarkData data: Data,
options: URL.BookmarkResolutionOptions = [],
relativeTo url: URL? = nil,
bookmarkDataIsStale: inout Bool
) throws
Personally I haven't run into any issues with it, since I'm referencing directories rather than single files, but found cautionary articles (like this one) - to quote its conclusion :
Rules of URL bookmarks
- Always check if bookmark data is stale (bookmarkDataIsStale)
- if data is stale, update ALL bookmark data - including all the bookmarks possibly stored elsewhere.
- be careful with atomic updates - need discipline to not use it.
- If need persistence and atomic writes better use something else - updating stored bookmark after every save is cumbersome and error prone.