Icon: Google's Update Engine LogoIf you’re developing an OS X application or preference pane, you probably want to think about how you’re going to push out updates, bug fixes, etc. Google’s Mac shop released an open source library called “Update Engine” that you can use to add this functionality to your app.

From the Update Engine project site:

Update Engine is a flexible Mac OS X framework that can help developers keep their products up-to-date. It can update nearly any type of software, including Cocoa apps, screen savers, and preference panes. It can even update kernel extensions, regular files, and root-owned applications. Update Engine can even update multiple products just as easily as it can update one.

Icon: Xcode LogoIf you’re an experienced iPhone developer, you already know and love the collection of sample projects that come with Xcode–a veritable treasure trove of information. If you’re new, one of the first things you should do is learn how to find them and then actually run each one; it’s the kind of time investment that will pay off in the future (e.g., “How do I do X? Oh wait, I think I remember seeing something like that in one of the sample code apps…“).

Open up your Xcode “Documentation” window and click on the “iPhone OS 2.x Library” doc set on the left-hand side of the window. Then scroll down to the “Resource Types” section and click on the “Sample Code” link.

If you’ve developed an iPhone/iPod Touch app and people are using it, you really want an easy way to get information about crashes when they occur. Apple does provide a mechanism for doing this: the iPhone OS records crash logs for on the device and when you sync it with iTunes the logs are copied to the user’s computer. (Apple has published an official document explaining all this in more detail.)

The problem with Apple’s mechanism is that you either need the user to manually dig up the files and send them to you (after they’ve done an iTunes sync, of course), or you need to write an OS X program to do it for them. Ugh. Fortunately, there are some alternatives.

I recently came across a great blog post by Christopher Atlan explaining how you can register your own “crash reporting” function that can, for example, upload a stack trace to a web server in between the time when you app barfs and when the iPhone OS shuts it down.

Another, perhaps slicker, option is to use Landon Fuller’s open-source library called “Plausible CrashReporter“, which not only creates a crash log for you, but also makes it easy to tell the user about it the next time they start the app, and ask them if they’d like to email or upload the report back to the developer. Slick.

Erica Sadun wrote an excellent article summarizing PLCrashReporter for Ars Technica. If you’re curious, here’s a code sample provided by the developer on one of his blog posts:

// from UIApplicationDelegate protocol
- (void) applicationDidFinishLaunching: (UIApplication *) application {
    PLCrashReporter *crashReporter = [PLCrashReporter sharedReporter];
    NSError *error;

    /* Check if we previously crashed */
    if ([crashReporter hasPendingCrashReport])
        [self handleCrashReport];

    /* Enable the Crash Reporter */
    if (![crashReporter enableCrashReporterAndReturnError: &error])
        NSLog(@"Warning: Could not enable crash reporter: %@", error);

    ...
}

/**
 * Called to handle a pending crash report.
 */
- (void) handleCrashReport {
    PLCrashReporter *crashReporter = [PLCrashReporter sharedReporter];
    NSData *crashData;
    NSError *error;

    /* Try loading the crash report */
    crashData = [crashReporter loadPendingCrashReportDataAndReturnError: &error];
    if (crashData == nil) {
        NSLog(@"Could not load crash report: %@", error);
        goto finish;
    }

    /* We could send the report from here, but we'll just print out
     * some debugging info instead */
    PLCrashReport *report = [[[PLCrashReport alloc] initWithData: crashData error: &error] autorelease];
    if (report == nil) {
        NSLog(@"Could not parse crash report");
        goto finish;
    }

    NSLog(@"Crashed on %@", report.systemInfo.timestamp);
    NSLog(@"Crashed with signal %@ (code %@, address=0x%" PRIx64 ")", report.signalInfo.name,
          report.signalInfo.code, report.signalInfo.address);

    /* Purge the report */
finish:
    [crashReporter purgePendingCrashReport];
    return;
}

Icon: Byline iPhone Application IconIf you’re a Google Reader fan and you have an iPhone or iPod Touch, Byline is well worth the $5. In a nutshell, it syncs with Google Reader, allowing you to carry all your RSS feeds around in your pocket. But it’s super-awesome in two ways: 1) it caches the feeds locally so that you can read stuff offline, and 2) it downloads a copy of the original web page for each post. That second feature–which Byline calls “archiving”–is killer, since many sites only publish a summary or abreviated version of each page in their RSS feed. Awesome.

Tip: Getting “Friends shared items” to Appear in Byline

Screenshot: Byline iPhone AppWhen I first started using Byline, I immediately wondered why I couldn’t see posts that other Google Reader users had shared with me. These typically appear under the “Friends shared items” section in Google Reader. The solution is to add each “Friends shared items” feed to a folder in Google Reader; Byline will see the folder and start downloading those posts. For example:

  1. Click on the “Friends shared items” feed from one of your friends.
  2. Click on the “Feed Settings” button that appears above the feed’s main window.
  3. The drop-down menu will allow you to add the feed to an existing folder (or create a new one).

Note that if you add your friend’s shared items to a folder that has other items (e.g., a common “Stuff Shared by Friends” folder) you won’t know which friend shared each post. If this info is important to you, add each feed to its own folder with a descriptive name (e.g., “Shared by Mike”, etc.).

As I Java developer I’ve occasionally needed to “disassemble” a .class file and reveal the method signatures and instance variables of the class(es) inside it, typically using the javap tool. As one would expect, a similar tool exist in the Objective-C world: class-dump. You pass the class-dump executable Mach object files (e.g., *.o, *.exe, etc.) and it spits out interface declarations in Objective-C. Handy.

As an example, let’s use class-dump to analyze itself (note all the goodies it generates: structs, protocols, interfaces, ivars…):

$ ./class-dump ./class-dump
/*
 *     Generated by class-dump 3.1.2.
 *
 *     class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2007 by Steve Nygard.
 */

struct dylib {
    union lc_str name;
    unsigned int timestamp;
    unsigned int current_version;
    unsigned int compatibility_version;
};

@protocol CDStructureRegistration
- (void)phase1RegisterStructure:(id)fp8;
- (BOOL)phase2RegisterStructure:(id)fp8 usedInMethod:(BOOL)fp12 countReferences:(BOOL)fp16;
@end

@interface CDOCCategory : CDOCProtocol
{
    NSString *className;
}
- (void)dealloc;
- (id)className;
- (void)setClassName:(id)fp8;
- (id)sortableName;
- (id)findTag:(id)fp8;
- (void)recursivelyVisit:(id)fp8;
- (id)identifier;
- (id)dependancies;
@end