Archive for January 2013

A better way to launch the Maps app for navigation on iOS 6

Back in the days when Google actually ruled Maps on the iOS platform (5.x and older), you had to push a URL through UIApplication’s sharedApplication object, and the system would see the ¬†Google maps URL and intercept it, sending the data to Maps instead of Safari.

Well this kind of works in iOS 6 as well, substituting maps.apple.com for maps.google.com. But alas, there is a better way.

Here is the code that I am now using to launch Maps, and it works in both iOS 6 and iOS 5.

- (void)launchMaps:(NSString *)serviceAddress
{
    NSString *currentLocation = @"Current+Location";
 
    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0"))
    {
        // use MapKit to handle launching Maps app instead of pushing a URL
        CLGeocoder *geocoder = [[CLGeocoder alloc] init];
        [geocoder geocodeAddressString:serviceAddress completionHandler:^(NSArray *placemarks, NSError *error) {
            if (error)
            {
                NSLog(@"Geocode failed with error: %@", error.localizedDescription);
                return;
            }
 
            if (placemarks && placemarks.count > 0)
            {
                CLPlacemark *pl = placemarks[0];
                CLLocation *loc = pl.location;
                NSLog(@"Geocoded latitude: %f; longitude: %f", loc.coordinate.latitude, loc.coordinate.longitude);
                MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:loc.coordinate addressDictionary:nil];
                MKMapItem *mapItem = [[MKMapItem alloc] initWithPlacemark:placemark];
                mapItem.name = @"Whatever name you want goes here";
                mapItem.phoneNumber = @"And if you have a phone number, it would go here";
                NSArray *mapItemArray = @[ mapItem ];
                NSDictionary *launchOpt = @{ MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving };
                [MKMapItem openMapsWithItems:mapItemArray launchOptions:launchOpt];
                [mapItem release];
                [placemark release];
            }
        }];
 
        [geocoder release];
        return;
    }
 
    NSString *urlString = [NSString stringWithFormat:@"http://maps.google.com/maps?saddr=%@&daddr=%@", currentLocation, serviceAddress];
    NSString *escaped = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:escaped]];
}

And here are the defines for the OS checking macros that I use. (Yes, I know you should check for specific features instead of checking OS version numbers.)

#define SYSTEM_VERSION_EQUAL_TO(v)                  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v)              ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)

The address string passed in would just be the components of your address separated by spaces (such as “1060 W Addison St Chicago IL”), and the Maps app should open up and give you the opportunity to start navigation to the destination.

BTW, Happy Birthday to Frank Zamboni, who is now forever immortalized with a Google Doodle.

Codemash conference recap

I have been back now a few days from my first ever Codemash experience, and I can say without a doubt that it was a great conference. Thanks to Jim Holmes and the army of volunteers and presenters that made the conference a rousing success.

I tried to attend mobile sessions since that is my primary focus here at My Service Depot, and the sessions were for the most part very informative. The highlight of the conference for me was Jon Skeet‘s presentation on abusing the C# compiler in Visual Studio. The room was standing room only literally seconds after the presenter before Jon got done with his presentation. Also, I attended both of Chris Risner‘s presentations on Windows Azure Mobile Services, and found them to be impressive, certainly worth a look for some of the ideas that I have floating about in my conscious.

Unfortunately, the lowlight of the conference had to be the line at the bacon bar. I suspect that could have been done a bit better than it was, as I really wanted to attend a session at that time instead of standing in line waiting to get bacon.

BTW, Happy Ratification Day to all my fellow U.S. citizens.

Codemash 2013 Wednesday Pre-compiler

Well this is my first time attending the Codemash developer conference at the Kalahari Resort in Sandusky, Ohio. I must say that this is a very nice conference considering that it is not taking place in Seattle or California.

For the morning session, I attended the HTML5 talk, and in the afternoon, I attended the Android talk. Both talks were very informative. And I especially like the bacon wrapped potatoes that they serve for breakfast.

BTW, happy birthday to Michael Schenker, one of my favorite rock guitar players.