Lion’s sandboxing deadline may have been pushed back, but News Anchor came through and met the original date. Bringing News Anchor into the sandbox cost me one of the two precious DTS tickets in my quota, due to the difficulties in getting the PubSub framework to function in the environment. I’d figured I ought to write this out to contribute back to the Mac Developer community.
News Anchor is our news reader for the Mac. As a news feed reader, it relies heavily on Apple’s PubSub (Publication Subscription) framework to parse the various news feed formats that are available (mostly RSS or ATOM, but since the standards are a bit lax, various websites tend to provide their content in ever-so-slightly different formats). The application is available both at the Mac App Store and direct-download from us. The Mac App Store version has been sandboxed since release 2.4.4 and its corresponding direct-download version was released at the same time to support the changes in the MAS version. This is so that MAS customers can also use the direct-download version, achieved via a clever licensing scheme first described by Daniel Jalkut.
The challenge around sandboxing an app that uses the PubSub Framework primarily stems from the way it uses a shared database file that is shared among all applications. Fortunately, it is not system-wide — every user has her own instance of the file placed in the
~/Library directory. Another issue is that the framework uses some mach ports for inter-process communication, but this was pretty straightforward to solve since it shows immediately as sandbox violation messages in the system log.
File access issues
When you sandbox a Mac application that uses the PubSub framework right off the bat, chances are PubSub framework couldn’t parse any RSS feed that you throw at it. Furthermore you’re likely to see these errors in your console log:
These warning messages sounds like the PubSub framework couldn’t find the path to its shared database directory. Why? Because by being in a sandbox, the application gets its own home directory that is several levels down from the user’s own directory. Since the home folder have moved (at least from the application’s point of view) the PubSub Framework then couldn’t locate its database that is normally found in
~/Library/PubSub and simply fail without throwing any exception on to the Objective-C side.
To regain access to the PubSub database, you will need to add read/write access entitlements to your application and add a symbolic link so that the PubSub framework can access it from within your application’s home directory. Adding an entitlement alone is not enough since the application’s view of the home directory have changed and some Unix-trickery is required to locate the file.
Add these read/write entitlements to your application do that it can access PubSub’s database
Adding file access entitlements only gives your application the ablility to read/write those files, but doesn’t help much on finding those files. Remember that a sandboxed application has its own home directory that is separated from the user’s normal home directory. Then how the sandboxed application can access shared files? By providing symbolic links from the sandbox to the files real positions.
Apple themselves also do this. When a sandbox directory is initialized, its Library directory is pre-populated with symbolic links of a number of important subdirectories that points to their respective true locations inside the user’s library folder. Take a look at the following sample Library folder in a sandbox:
From the above example, you can see for yourself that these subdirectories are links to their real ones in
~/Library four levels up. Unfortunately adding a directory entitlements for additional subdirectories inside
~/Library does not imply that the necesssary symbolic links will be created for you, at least not as of Mac OS X 10.7.2. You’ll need to create those links yourself via the
symlink() function call.
Fortunately for linking to PubSub’s database folder you can use this function that I’ve written originally for News Anchor:
You should find it easy to adapt the function above to create symbolic links for accessing other shared files inside
Last but not least you should add IPC exceptions needed by the PubSub framework. You probably saw these sandbox violation messages in the console log the moment you enable sandboxing for your app:
To solve this, simply add these two exceptions to your application’s entitlements:
The first entitlement I found out myself whereas the second security exception for com.apple.pubsub.ipc came from the DTS ticket resolution. Since it came from Apple, it’s probably wise to just include the exception.
You can download the sample project here. This contains the
BSCreatePubSubSymlink() function as well as all the entitlements needed to get PubSub ready to parse your news feeds.
So thats about it. Apple may be too rushing to enforce sandboxing to the Mac App Store, with brings up issues such as this one and probably many more that others have experienced. But as Mac devs, especially indie devs, we should band together and do our best for everyone involved in the ecosystem, users and devs alike.
Thanks for reading and until next time…
Do you enjoy this post? Enter your e-mail address below to receive articles like this one in your mailbox.