A Great Way to Do Framework Initialization

After I have developed several iOS and Mac apps, I started to realize the need to write some sharable code that can be used not just in multiple apps on the same platform (iOS or Mac), but also across platforms (iOS and Mac). I will talk about one of the best ways to do framework initialization, why and how. I also wrote an ebook on creating iOS universal framework. You can download it for free.

Less is more

When it comes to writing any kind of library code that is meant to be reused by me or by others, I believe there should be as little framework initialization code as possible. There are 2 reasons:

  1. I will likely forget how the library works internally or its configuration options after one month or longer. If there is a lot of setup in order to use the shared code, it takes a varying degree of context switch.
  2. Others who use your code doesn’t want to know how you implement it. If they do, they would have done it themselves. They have a problem to solve and want a quick, frictionless solution to solve that problem so that they can move on to develop for their own apps.

One way of achieving this is to run your framework initialization code automatically without requiring the user of that code to initialize objects of your library that may not necessarily need to be exposed.

A Simple Loader Class

First, I like to create a new class for just this purpose. I usually name it XXXLoader because we will be using NSObject‘s load class method. Here are the header and implementation for a class named DevNewsLoader that is extracted from my DevNewsLetter project at GitHub. DevNewsLetter demonstrates how to build an universal framework that can be used for iOS and Mac apps to allow your app users to sign up for your email newsletter.

#import "DevNews.h"
#import "DevNewsLoader.h"
@implementation DevNewsLoader
+ (void)load
    [[NSNotificationCenter defaultCenter] addObserver:[self class] selector:@selector(applicationDidBecomeActive:) name:@"UIApplicationDidFinishLaunchingNotification" object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:[self class] selector:@selector(applicationDidBecomeActive:) name:@"NSApplicationDidFinishLaunchingNotification" object:nil];
+ (void)applicationDidBecomeActive:(NSNotification *)notification
    /* Put any initialization code here like reading apiKey or listID from a property list */
    [DevNews devNewsWithAPIKey:apiKey listID:listID];

When DevNewsLoader is loaded when the app runs, its load method is called (hence the name Loader). I use the preprocessor directives TARGET_OS_IPHONE to determine if this code is being run in an iOS or Mac app. This method simply registers DevNewsLoader as an observer of the UIApplicationDidFinishLaunchingNotification or NSApplicationDidFinishLaunchingNotification notification, depending on the platform.

When the notification is received, the applicationDidBecomeActive method is called. You can then run any framework initialization code you need for your framework/library/shared code. In DevNewsLoader‘s case, it reads the API key and list ID from a property list file and then initializes the DevNews singleton object. DevNews is now ready to be used by other developers.

One more thing

In addition to the UIApplicationDidFinishLaunchingNotification and NSApplicationDidFinishLaunchingNotification notifications, you can also observe other notifications as listed in the UIApplication Class Reference and NSApplication Class Reference. You can automatically run your framework initialization code when the app goes to the background, comes back to the foreground, or terminates.

This is a series of posts related to building frameworks for iOS and Mac. I talked in length about how to build an universal framework that you can use for both iOS and Mac apps. Are you able to use this tip to improved your shared code? I would love to hear what you think or other tips you have related to framework initialization. Just give it a shout.