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: ,