I’ve spend several hours this morning wading through problems with the Mac development environment and Cocoa.
In a nutshell, the available APIs for doing file manipulation could stand some enhancement.
NSFileManager is the predominant way in Cocoa to do file operations. Yet it has many drawbacks including:
- Limited error handling
- Inability to cancel an operation in progress
- Single threaded. If you invoke a length operation from the main thread, your UI will hang (beachball) until the operation is complete.
- Inability to get status information during an operation even if you do run in a secondary thread.
A more flexible approach is available as part of older C based frameworks. I’m not clear its relation to Carbon, but its base of Core Foundation.
There is a file manager service which you can access. An example operation is FSCopyObjectAsync. This function solves all of the issues with NSFileManager. It automatically handles running the copy as part of a run loop you specify (usually the main run loop). It can call back a function you provide allowing you to get status while the operation is going on and allows you to cancel the operation. And it provides richer access to error information.
Drawbacks? It shouldn’t have any, but it does. Being a C function, you are suddenly immersed in a world of Apple specific C data types. A random mishmash of conversion routines. As an example, FSRef is the data type used to reference files. It is an 80 character opaque internal data representation of the file system object identifier. There are functions to convert from a pathname to and from FSRef.
Getting status from the call back involves a CFDictionary which is a C version of a dictionary, not a NSDictionary.
CFNumber is also used. Unlike FSRef, this data type has “toll free bridging”. Essentially meaning that is can be used interchangeably with an NSNumber.
Overall the function is nice but hard to use for the programmer who knows Cocoa but not Core Foundation.
This reminds me of the world of Microsoft. MFC (Microsoft Foundation Classes) are largely object oriented wrappers of non object oriented Windows functions. Much of the class library is fine, but sometimes you see wierd artifacts due to its Windows heritage.
I am surprised that I have not been able to find wrappers for Apple Core Foundation functions. In particular this File Manager service is clearly in need of a Cocoa wrapper to hide the data conversions which are necessary to make it work easily in Cocoa.