Post not yet marked as solved
This is still broken in MacOS 12.2
I see what you mean: If you store the file resource identifier, you can use the identifier from newURL and simply ignore oldURL. You really don't need it. Thanks so much, that is indeed the solution.If I understand you correctly, the solution would be something like this in code.import Cocoa
final class Controller: NSObject, NSFilePresenter {
var presentedItemURL: URL?
var presentedItemOperationQueue: OperationQueue = OperationQueue()
var root: FileNode?
// ...
func presentedSubitem(at oldURL: URL, didMoveTo newURL: URL) {
// Ignore oldURL. Find node based on resource identifier of newURL
guard let node = root?.search(for: newURL) else { return }
// Move node to now location
}
}
final class FileNode: NSObject {
var url: URL
var identifier: NSObjectProtocol?
@objc var children = [FileNode]()
// ...
func search(for target: URL) throws -> FileNode? {
guard let identifier = self.url.identifier, let targetIdentifier = target.identifier else {
throw Error.NoIdentifier
}
if identifier.isEqual(targetIdentifier) {
return self
} else {
// Traverse tree
}
return nil
}
}
extension URL {
var identifier: NSObjectProtocol? {
return (try? resourceValues(forKeys: [.fileResourceIdentifierKey]))?.fileResourceIdentifier
}
}
I've (kind of) solved it by taking the relative paths and check if either's suffix is equal to the other relative path. There are a few edge cases where this doesn't work, so a more solid solution is welcome.static func &=(lhs: URL, rhs: URL) -> Bool {
guard let idl = lhs.identifier, let idr = rhs.identifier else {
if lhs.relativePath.hasSuffix(rhs.relativePath) || rhs.relativePath.hasSuffix(lhs.relativePath) {
return true
} else { return lhs == rhs }
}
return idl.isEqual(idr)
}