Archive for category Programming

Detecting when Bluetooth is disabled with GKSession

Edit: As noted in the comments, this technique no longer works in iPhone OS 3.1.

If you are writing an iPhone GameKit app without using GKPeerPickerController (as I did in PhotoBeamer), you need to detect when Bluetooth is disabled and ask the user to turn it on in the settings app. Apple doesn’t provide a way for a developer to enable Bluetooth other than through GKPeerPickerController.

This is pretty easy to do. First, create your GKSession and set it to be available:

    session = [[GKSession alloc] initWithSessionID:kMyAppSessionID
                                       displayName:nil
                                       sessionMode:GKSessionModeClient];
    session.delegate = self;
    [session setDataReceiveHandler:self withContext:nil];
    session.available = YES;

Next, set up your - (void)session:(GKSession *)session didFailWithError:(NSError *)error delegate method to detect when Bluetooth is not available and alert the user:

// GKSessionErrorDomain causes link error (rdar://problem/7014349)
#if 0
#define kGKSessionErrorDomain GKSessionErrorDomain
#else
#define kGKSessionErrorDomain @"com.apple.gamekit.GKSessionErrorDomain"
#endif
 
- (void)session:(GKSession *)session didFailWithError:(NSError *)error {
    if ([[error domain] isEqual:kGKSessionErrorDomain] &&
        ([error code] == GKSessionCannotEnableError))
    {
        // Bluetooth disabled, prompt the user to turn it on
    } else {
        // Some other error, get the description from the NSError object
    }
 
    // destroy the GKSession and clean up
}

The GKSessionErrorDomain symbol causes a link error for me, so I’m temporarily using the constant string instead. When Apple fixes the SDK, I’ll change that #if 0 to use the official symbolic name.

Note that this error will sometimes occur on a reconnection attempt even when Bluetooth is enabled, presumably because the old session is still partially active.

It would be nice to have a more user-friendly way to turn on Bluetooth without leaving the app and without using the full GKPeerPickerController UI. I’ve filed a bug report (rdar://problem/7061502) asking for this functionality. You should file one too.

Tags: ,

iPhone Application Packaging

When developing for the iPhone it’s often necessary to build the application in a form that can be easily installed by collaborators and testers. For ease of installation, the app should be distributed as a .ipa (iPhone Application) file. Unfortunately, XCode does not include a way to do this, so I wrote a bash script to automate the process.

Additionally, in any build that leaves the developer’s desk it is especially important to include version information so that bug reports can be traced back to the correct version of the source, and to ensure that any distributed version can be located in the version control system. I use git for source control (installed with MacPorts), though the script should be easily adaptible to CVS or SVN.

The goals for this script were:

  • Automatically tag the project with a unique build number before each build.
  • Build all supported configurations with a single command. Sometimes compiler errors or warnings are only revealed with certain preprocessor flags or optimization settings.
  • Ensure any build created for distribution is cleanly committed to version control and tagged.
  • Name tags so that they can be easily correlated to user-visible version information.

Read the rest of this entry »

Tags: , , ,

Balsamiq Mockups

I’ve heard good things about Balsamiq Mockups so I thought I’d give it a try. The desktop version is currently just $79, and installs in moments from the Mockups site. The app is based on Adobe Air, so if you don’t have Air installed already, you’ll need to do that first. Mockups runs on OS X, Windows, and Linux. There is also a web version. This review uses the OS X desktop version. You can try out the desktop version for free, but to save or export designs you’ll need a license key.

Read the rest of this entry »

Tags:

A Not Entirely Accurate History of Programming Languages

James Iry has posted A Brief, Incomplete, and Mostly Wrong History of Programming Languages, a hilarious look at the development of programming languages over the years.

Some of my favorites:

On C:

“1972 - Dennis Ritchie invents a powerful gun that shoots both forward and backward simultaneously. Not satisfied with the number of deaths and permanent maimings from that invention he invents C and Unix.”
~ James Iry A Brief, Incomplete, and Mostly Wrong History of Programming Languages

On Objective-C:

“1986 - Brad Cox and Tom Love create Objective-C, announcing "this language has all the memory safety of C combined with all the blazing speed of Smalltalk." Modern historians suspect the two were dyslexic.”
~ James Iry A Brief, Incomplete, and Mostly Wrong History of Programming Languages

On LiveScript/JavaScript/ECMAScript:

“1995 - Brendan Eich reads up on every mistake ever made in designing a programming language, invents a few more, and creates... JavaScript”
~ James Iry A Brief, Incomplete, and Mostly Wrong History of Programming Languages

Visit his blog to read more.

Detecting Memory Leaks in the iPhone Simulator

Selecting executable in XCode
There are a number of useful debug flags for the iPhone that can be set in the environment. To access these settings, select your executable from the Groups & Files pane in XCode, then press ?I or select Get Info from the context menu.

Go to the Arguments tab and add the following entries into the “Variables to be set in the environment” box:

  • NSAutoreleaseFreedObjectCheckEnabled
  • NSDebugEnabled
  • NSZombieEnabled

Set the value for all each to YES.

Your settings should now look like:

Executable arguments settings

You may also want to set NSHangOnUncaughtException=YES. Additional useful debugging tips can be found in this thread.

Edit: CocoaDev has additional NSZombieEnabled tips, and notes that you may not want to leave this enabled all the time, especially if your application churns through a lot of objects, as the memory never gets freed. The fact that your code is running on a desktop or laptop system instead of the phone helps a lot here, so this is probably a lot less of a concern than for a desktop application. They also provide instructions for setting these flags in your .gdbinit using:

set env NSAutoreleaseFreedObjectCheckEnabled=YES
set env NSDebugEnabled=YES
set env NSZombieEnabled=YES

Tags: