Posts Tagged iPhone Development

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

PhotoBeamer Available in the App Store

A little over a month ago, the appMobi team was sitting outside around a table at our favorite bar/restaurant, enjoying the warm summer weather and a cold drink. We had just finished our last meeting before I headed off to WWDC, and we were sharing pictures on our iPhones by passing them around the table. That was when we realized “there should be an app for this!”

Sure, there are apps that let you upload images to Facebook, Flickr, and all sorts of other places…. Sure, you can email a picture, and with iPhone OS 3.0 coming soon even MMS one (assuming you’re not in the US and don’t care about quality). There are even apps that let you share photos on the spot, phone-to-phone, but only if you are all on the same WiFi network.

We knew that 3.0 would be out soon, possibly as soon as WWDC. We also knew that 3.0 had peer-to-peer Bluetooth networking support through the new GameKit framework. We decided this was a perfect opportunity to take advantage of the new OS.

I went home and got some sleep (long day and Crown don’t make for productive programming), then dived right into GameKit first thing in the morning. By lunch time I was able to share small images reliably, but clearly needed a lot of UI and networking polish. We knew we wouldn’t be the only ones with this idea, and that the quality of the app would be more important than being the first ones to market.

I spent the rest of the week polishing the prototype, and by the time I left for San Francisco had the core user interface pretty solid: translucent autohiding toolbars, a zooming and scrolling image view very much like the native Photos app, support for viewers coming and going mid-session, and more.

During the keynote at WWDC Apple announced that the 3.0 gold master was available immediately to developers. I updated from the Beta I was running and immediately found bugs in my apps. Not so much in PhotoBeamer, but in SpinSlide, which was already in the store with paying customers. I had to put PhotoBeamer aside and work on fixing the bugs in SpinSlide as quickly as possible, while attending 8+ hours of sessions and nearly as many parties through the week.

Once I got back from WWDC I was able to finish up the bug fixes and internationalization work on SpinSlide (now available in Spanish and Japanese!) and get back to work on PhotoBeamer. I updated the networking code to send arbitrary size images reliably, added a camera button to allow taking pictures right in the app, and continued with the visual polish, adding activity spinners and a status view with separate progress bars for each client and a multi-line status area to ensure the user has a chance to read messages as they come up. I created a free version called BeamCatcher and fought through some issues with my build scripts, and added the ability for the clients to save images to their Photo Album, but only if the sender allows.

A few beta test sessions using multiple devices at once uncovered some more bugs that were addressed, and the arrival of the 3GS showed some more room for improvement in both the networking and image display code, thanks to the larger images. Most importantly, I discovered how to detect when Bluetooth is not enabled without using the built-in peer picker controller, which doesn’t fit well with the PhotoBeamer app flow.

After all that, and an unusually long review at Apple (likely due to the massive influx of new and updated apps around 3.0), both PhotoBeamer and BeamCatcher went live June 12th. Get PhotoBeamer to share your pictures. If your friends won’t spring for the full app, they can download BeamCatcher to view for free.

PhotoBeamer MainSender decides if clients can save the shared imagesSender is prompted when a client tries to connectProgress is shown for each clientView in portrait or landscape mode

BeamCatcher is receive-onlyLooking for PhotoBeamers nearbyBeamCatcher receiving the initial imageImage received - save button is now activeAfter a few seconds the UI slides out allowing an unobstructed view

Tags: , ,

What’s New in iPhone OS 3.0, A Developer’s Perspective

WWDC 2009 ended a week ago, the new iPhone 3G S is out, and iPhone OS 3.0 has been available for a couple of days now, so I think it’s finally OK to talk publicly about the 3.0 SDK (after all, you can go get it from Apple for free now).

Last night I gave a talk at the Philly CocoaHeads meeting in an attempt to cover the 1000 or so new APIs in over a dozen functional areas in under an hour. I’m sharing the slides here for all, whether you were able to make it last night or not. We had some great discussions, which unfortunately are not in the slides, but hopefully these will help give you an idea of what is newly possible in iPhone OS, and where to look for more details.

What’s New in iPhone OS 3.0, Philly CocoaHeads June 2009 (pptx, 552kB)

What’s New in iPhone OS 3.0, Philly CocoaHeads June 2009 (pdf, 366kB)

I’d love to hear your thoughts on the new APIs and how you plan to make use of them in your apps.

Tags:

Hidden Elephant Software » Targeting iPhone 2.x on Snow Leopard with Xcode 3.2

Serban Porumbescu, whom I met last week at WWDC, posted instructions for targeting iPhone OS 2.x from XCode 3.2.

There’s not much to add, so I’m just posting to add it to my Google-powered memory.

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