macFSRef, what's the deal?

Ok I’ve got an application which maintains links to a large number of files (several thousand). I’ve been experimenting with using macFSRef rather than paths to store the links. The advantage to me is if the user moves or renames a file or folder then creating a folderitem from FSRef still references the file i.e. the link is not lost (Which is very useful to me).

I’m assuming this is a wrapper for FSRef
The thing is I’ve read a lot of conflicting information about this.

  1. FSRef doesn’t persist or work outside of the context in which it was created.
    (Well I’ve been experimenting with stuffing them in sqlite blobs, closing the app renaming files and then reloading from the stored data … Hey presto … Can create working folderitems from the stored data with … So far … No issues)

  2. I’ve read FSRefs are deprecated … Is this true … Do they have longevity? And will they fail Apple’s API check?

I’d be really grateful if anyone can clarify the situation (or laugh in my face of you prefer)

Why not just use folderitem save info ?
It will do that as well since its basically an alias record

FSRef is deprecated by Apple. You can still use it for Mac App Store.

I would also recommend to either keep FolderItems (which internally use whatever is appropriated) or to store saveInfo to get an alias.

AFAIK they haven’t been removed and are not barred from the App Store, however with 10.10 we saw the start of bugs creeping in to certain FSRef functions that will never ever get fixed.

Apple’s replacement is “bookmarks”, which can be created with security scoping (for working in a Sandboxed application). However they’re horrible horrible things and should be avoided at all costs.

If you’re not shipping on the Mac App Store, use the Xojo folderitem.getsaveinfo functions. If you’re shipping on the App Store, you need to consider what you’re doing with these files. For instance you can see if the files exist and even use Quicklook to get a preview of the contents, however you can’t open them, get their modified date or even the file length without a Security-Scoped Bodgemark (this is of course after the application has been re-opened).

Bookmarks are more akin to alias records or save info data. File reference URLs are the direct replacement for FSRefs.

Huh… I find that NSURLs can easily be broken when the file is moved. Perhaps it’s the way I create NSURLs then (as there’s many different mechanisms for creating a NSURL). Currently I’m using.

+ (NSURL *)fileURLWithPath:(NSString *)path isDirectory:(BOOL)isDir
Bodgemarks seem to work as long as you resolve them every time you need them.

Many thanks guys that’s been a great help.

Norman: Your suggestion crossed my mind but as I thought I understood FSRef I did that :slight_smile: … I will try your suggestion many thanks.

Sam: I am shipping on the app store (thanks to app wrapper :slight_smile: ) and I do security scoped bookmarks at the folder level and recurse the content. I didn’t think it would be feasible to obtain a bookmark for every file (but I’m more than happy to be corrected on that :))

MBS Plugins have a CFBookmarkMBS module to make the new bookmarks.
http://www.monkeybreadsoftware.net/module-cfbookmarkmbs.shtml

and we have a Mac Alias class:
http://www.monkeybreadsoftware.net/class-macaliasmbs.shtml

but for most people the SaveInfo feature in Xojo is enough.

Yeah, +[NSURL fileURLWithPath:isDirectory:] creates a URL that represents a fixed path. A file reference URL can be created from it via -[NSURL fileReferenceURL]. The resulting URL will behave similarly to an FSRef and track the file as it moves within its current volume.

FYI, the FSRefs won’t probably go away any time soon as too many apps rely on them. But Apple deprecated them because they’re inefficient, making it difficult for OSX to determine how long an FSRef is in use, as they’re no ref counting for them. So OSX has to cache them, which is not optimal. The newer URL based file ops are better because they have a ref counter, solving this problem.

Okay cool, no your method of storing a root folder and recursing through is probably the best approach. SSBs are expensive to create and resolve, not to mention that you must request/relinquish access for each bookmark you resolve at the time you need it.

Ah, excellent as always Joe, thanks for putting me back on the right track.

[quote=281491:@Norman Palardy]Why not just use folderitem save info ?
It will do that as well since its basically an alias record[/quote]

Be careful, on Windows calling FolderItem.GetSaveInfo can raise a runtime error and stop your app dead cold. See my Feedback report #44488 - Windows Runtime Error QuickStableVS

It doesn’t cause a problem on all Windows machines, just on lots of them. Removing .GetSaveInfo from my code has solved the problem for those users.