Search code examples
objective-cmacoscocoansurlnsfilemanager

How to determine file equivalency between app sessions prior to OS X 10.10?


I'm making an app that monitors changes to a "hot" folder and uploading new files to a remote server (think one-way Dropbox). The app needs to remember which files were previously uploaded and not re-upload them, even if the user moves them to a different child folder. If I had access to the 10.10 API, I'd just use the NSURLDocumentIdentifierKey property of NSURL and call it a day... but I need to support back to 10.7 (Lion). Here are the approaches I've thought of so far, which all seem somewhat deficient:

  • There is the NSURLFileResourceIdentifierKey but it is not maintained across system boots, so it is ineffective for more than same-session usage.
  • I could compute an MD5/SHA1 hash for each file, but this app is targeted at pro photo users, so the prospect of hashing hundreds of multi-megabyte image files is not appealing.
  • The Alias framework and FSRefs all got deprecated in 10.8, so I'm reluctant to build a solution based on them.

What other approaches am I overlooking?


Solution

  • The solution I eventually settled upon was to assign each file my app touched a UUID that was stored in the file's extended attributes under a key unique to my app. Extended attributes follow a file when it is moved or copied. When reading in a directory structure, I check each file for a UUID and assign one if it is not present. In the event of a UUID collision due to a copy of a file being encountered (I'm keeping a lookup table of encountered UUIDs), I assign a new UUID to the later-encountered file.

    NSHipster's writeup on Extended Attributes

    I encapsulated the messy C interactions with setxattr(), getxattr() and listxattr() in a category on NSURL which lets me easily query/get/set arbitrary text attributes on the file system document pointed to by the URL.