Tag Archives: code

Giving Back

A few years ago I was very much “into” the whole open source movement. I read LWN (still do, actually). I bought a copy of The Cathedral and the Bazaar.

But one thing I never really did was contribute to open source projects. I never really had much need. They largely did what I wanted and when they didn’t, well, the modifications were too big to consider attempting in my spare time.

And now I have a couple of applications in Apple’s App Store. I get the impression that a lot of apps you see there these days are mainly collections of open source code bundled together with some glue code and some new graphics. I know it sounds bad when you phrase it like that, but I don’t mean it that way. When you’re coding to a deadline and to cost this is a perfectly valid way of doing things.

But neither Yummy nor www.cut are like that. They are almost entirely my own code. Why? Two main reasons.

The first is historical: Yummy was initially developed when the now infamous NDA was in place. Developers couldn’t share code even if they wanted to.

Secondly, I like to minimise external dependencies. The iOS platform changes fast enough as it is without having to wait for other developers to update code as well. Of course, open source means that I could fix it myself but that probably means looking at code I’m not completely familiar with and that takes time. The desire to remove third party code led me to remove AdMob in Yummy Browser and www.cut and replace with Apple’s iAd, even knowing that the fill rate was very low1.

Ultimately, however, there’s too much great code out there to avoid it altogether. The current, shipping version of Yummy has two open source components and I have just released a (tiny) third one.

First is the Facebook Connect SDK. I have not made any modifications to this.

Second is InAppSettingsKit. This some software that duplicates the Settings screen and allows them to be included within the app as well as in the Settings.app. I made some minor fixes so that it works on the iPad (independently fixed and pushed upstream) and I added a “Log in to Facebook” cell. I’m not sure how common a requirement this is likely to be, so I’ve not pushed it back to the maintainers but I have made it available in a separate branch:

InAppSettingsKit

Third is something that should really be included in iOS itself. Apple’s guidelines say that when your app is sent into the background it should close any menus that are open. In “iPhone Speak” these are called UIAlertView (dialog in the middle of the screen) and UIActionSheet (menu from the bottom of the screen).

In addition, the iPad had a further requirement: there should be only one menu open at any given time.

I created UIViewAutoDismiss to help:

UIViewAutoDismiss

This code is inspired by a question and answer on Stackoverflow.

  1. Early indications are that, even with the lower fill rate, income is not vastly different, and this is with only two countries active at the moment with iAds. []

iPhone Dev: Saving State

I see every now and again that Apple needs to make it easier to allow developers to save the state of their application so that they open up exactly as they were when they were shut down.

Obviously I’m all for Apple making my life easy, but that’s not going to happen for a while yet so I thought I’d share how I implemented it in Yummy.

The key is this simple protocol:


@protocol SaveState
- (NSData*) saveState;
- (id) initWithSaveState:(NSData*)data;
@end

This is what I have in my applicationWillTerminate: method:


NSMutableArray* vcList = [NSMutableArray arrayWithCapacity:3];
for (UIViewController* vc in self.navigationController.viewControllers) {
    // Classes that don't implement the SaveState protocol will be ignored
    if ([vc conformsToProtocol:@protocol(SaveState)]) {
        NSArray* state = [NSArray arrayWithObjects:NSStringFromClass([vc class]),
                                                                     [(UIViewController*)vc saveState],
                                                                     nil];
        [vcList addObject:state];
    }
}

This is in the applicationDidFinishLaunching::


for (NSArray* screen in screenList) {
    UIViewController* next =
                [[NSClassFromString([screen objectAtIndex:0]) alloc]
                                   initWithSaveState:([screen count] == 2) ?
                                   [screen objectAtIndex:1] : nil];
    if (next != nil) {
        [[self navigationController] pushViewController:next animated:NO];
        [next release];
    }
}

So a simple example, for a view controller that needed to be remembered but didn’t need to store any extra state, would be:


- (NSData*) saveState {
    return nil;
}
- (id) initWithSaveState:(NSData*)data {
    return [self init];
}

But you can initialise each view controller with anything that can be converted into an NSData. (I picked NSData rather than, say, id because an NSData can always be serialised. Made sense to make that assumption.)

One weakness is that it doesn’t cope with the situation where a modal view is on top but that should be pretty easy to implement if it’s important (it generally isn’t in Yummy).