Stephen Decker

Read this first

Animating on the Apple Watch

This is a repost of an article I wrote for the company I work at, Tumult.

Subtle animations are a great way to add fun and personality to an Apple Watch App. Whether its a custom loading indicator or part of a game, animations can bring your watch app to the next level. To add an animation you simply need to create a png image sequence and tell an Image or Group to start animating.

Hype can greatly simplify the process of creating image sequences by allowing you to build complex keyframe based animations and export them as image sequences.

When creating an image sequence for a watch app here are a few tips to keep in mind:

  • Apple has strict limits on how large your watch app can be (currently 20 MB), so keep your animations simple and optimize your images (more on this later)
  • Store animations locally on the watch so they load quickly
  • The 38mm and 42mm displays are different sizes...

Continue reading →


Common Leaks when using Xib files

Xib (nib) files in Cocoa make memory leaks super easy, especially if you are coming from iOS Development. In iOS top level objects are autoreleased, but on the Mac it is the responsibility of the file’s owner to release them.

Fun fact if you don’t use something like NSWindowController or NSViewController you need to release all the top level objects in your nib or they will be leaked.

You can either create an outlet to each top level object individually and release them on dealloc or use -[NSNib instantiateNibWithOwner: topLevelObjects:] and keep track of the array of topLevelObjects. Managing the top level objects is not that bad, but something that can be easily forgotten.

Things get a bit trickier when you use ARC (automatic reference counting). Since you are not allowed to call release you either need to not use arc when loading nibs with top level objects or cast objects to a...

Continue reading →


Dealing with Slow Security Scoped Bookmarks

As I mentioned in a previous post I found security scoped bookmarks to be up to 220 times slower than regular bookmarks. Since my application was already using security scoped bookmarks to track many resources this caused major performance regressions after sandboxing my app and switching over to security bookmarks.

To fix this I ended up doing URL resolution on a background thread so that the app stays responsive while taking up to 20 seconds to resolve bookmarks.

I decided to use an NSOperationQueue to manage the operations. So I created a singleton queue to be used exclusively for resolving bookmarks like this:

+ (NSOperationQueue *)bookmarkLoadingQueue {
    static NSOperationQueue *gBookmarkLoadingQueue = nil;
    if (gBookmarkLoadingQueue == nil) {
        gBookmarkLoadingQueue = [[NSOperationQueue alloc] init];
        [gBookmarkLoadingQueue setMaxConcurrentOperationCount:3];
...

Continue reading →


Adding a sandboxed app to an app group

This is a relatively simple task that is complicated by confusing documentation. After viewing the documentation it looked relatively simple to add applications to a group. Just add some magic to the entitlements and use the containerURLForSecurityApplicationGroupIdentifier: method of NSURL. The only problem was that as far as I can tell NSURL does not have a containerURLForSecurityApplicationGroupIdentifier: method.

The key to add looks something like this:

<key>com.apple.security.application-groups</key>
<array>
    <string>DG29478A379Q6483R9214.com.company.whatever</string>
</array>

The random numbers are your development team ID. I believe that can be found by looking at your developer ID certificate in keychain viewer (someone correct me if I am wrong). After the period you can put whatever you want as long as it matches the string in the other applications you want to be part...

Continue reading →


Saving Multiple Related Items (Files) from a Sandboxed Application

On the Mac App Store applications are required to be sandboxed. This means that an application has a restricted set of files that it can access. For most document based applications saving to arbitrary locations is relatively easy because Powerbox requests the save location from the user and then grants the application access to that location.

The problem occurs when a sandboxed application needs to write out more than one file (for example resources associated with the document). The easiest way to resolve this issue is to create a package or at least an enclosing folder. The user can pick the location for the folder and Powerbox will grant the application access to that folder and everything inside it. This way you can write as many files as you want to that folder.

Things can become more difficult if you are required to have more complicated export options. For example if you are...

Continue reading →


Sandboxing Adventures

I recently had the pleasure of sandboxing a Mac application that was written before sandboxing was required on the Mac App Store. I found a lot of good resources (including Apple’s Documentation) that covered the basics of setting up entitlements to give the application access to things that it needed.

However I was surprised to find that there were very few resources about some of the more advanced sandboxing topics. Things like security scoped bookmarks, the related files api, and code signing xpc services had sparse references even in the official sandboxing documentation.

I found these things to be necessary to support many of the existing features in my application but they didn’t seem to be mentioned much on the web.

Especially in the case of the related files API this forced me to use lots of trial and error and reverse engineering the current version of text edit (which has...

Continue reading →