watchOS

WatchKit tutorial: Maps on the Apple Watch

We finally have a release date for the Apple Watch! I’m looking forward to building apps with the actual device, but for now the simulator will just have to do. There’s an interesting new watch simulator called Watch Sim that will let you evaluate your Apple Watch app in real size on an iPhone or iPad, but it’s a bit pricey. If you’re not planning to get a watch though, $9.99 is a great bargain (but would you really be making Watch apps without owning an actual watch?). I find that Bezel is a pretty good substitute, but there’s no physical interaction (it’s still only on your computer screen).

Onto the tutorial!

Apple Watch Maps

If you’ve been following along, this next tutorial should be pretty simple compared to the last couple that I’ve made. We’ll be looking at displaying a map on the Apple Watch and setting both native and custom markers on it.

Map Interface
The downside is that that’s pretty much all you can do at this moment (as of the iOS 8.2 release). Users can’t even interact with these static maps – once the user taps on it, it will open up the default Apple Maps app. You can read more about map capabilities on the Apple Human User Interface Guidelines.

As always, I’ve provided all of the project code on GitHub. You’ll also need some image files – download the zip file here. Let’s get started.

Watch Interface

Create a new iPhone project and name it WatchKitMap. If you’ve never created a Watch project before, check out the beginning of this post. Remember to create a new target for the Watch app since it won’t be created for you automatically. Expand the WatchKitMap WatchKit App folder and open the Interface.storyboard. Grab a map from the sidebar and drag it into the default Interface Controller scene. Drag the sides so that it takes up the entire space of the frame.

Map IB

Click on the Map box in the storyboard and then click on the Attributes Inspector icon on the sidebar (looks like a bookmark). In the size area, change the width and height to be “Relative to Container.” That way, the map will fill all the available space no matter what size Watch the user has.

Map Attributes Inspector

The last thing you want to do is open up the assistant editor (split view, the icon with the two overlapping circles) between the watch storyboard and InterfaceController.m. Drag an outlet from the storyboard map to InterfaceController.m and name it map. That’s it for the interface.

WatchKit Extension

Since this will be a static map, the entire thing will only take 3-4 lines of code to set up the map and display the markers. We’ll be using some APIs from MapKit and CoreLocation to set up the location and zoom factor. Replace your awakeWithContext method with the following:

- (void)awakeWithContext:(id)context {
    [super awakeWithContext:context];
    
    // Determine a location to display - Apple headquarters
    CLLocationCoordinate2D mapLocation = CLLocationCoordinate2DMake(37, -122);
    //
    MKCoordinateSpan coordinateSpan = MKCoordinateSpanMake(1, 1);
    
    // Other colors include red and green pins
    [self.map addAnnotation:mapLocation withPinColor: WKInterfaceMapPinColorPurple];
    
    [self.map setRegion:(MKCoordinateRegionMake(mapLocation, coordinateSpan))];
}

CLLocationCoordinate2D allows us to define a map location by latitudinal and longitudinal values (in degrees). (37, -122) happens to be the current Apple headquarters location =).

Next, we create a coordinate span. This basically just defines the area spanned by the map region – the (1,1) corresponds to the zoom level (with smaller values = higher zoom).

The next line

[self.map addAnnotation:mapLocation withPinColor: WKInterfaceMapPinColorPurple];

adds a pin to the mapLocation we set earlier. Notice there are multiple color options here.

Purple – show a particular point
Red – show an ending location (for use in directions)
Green – show a starting location (for use in directions)

Make sure to use the correct color pin depending on your circumstance.

Lastly, we’ll set the region we just created for the map view. Save and run the watch app. You should now have something that looks like this:

Single pin watchkit map

Notice the pin actually appears in the center of the map. You can move the location of the pin by a basic offset if you wish. I’ll show you how to do that in the next step with a custom pin marker image.

Open up the zip file you downloaded earlier. In it, there should be a couple of pin marker images – go ahead and pick one. I’m using the pink flag. Drag your desired image into the Images.xcassets folder of your WatchKit extension (this will not work if you drag it into the wrong Images.xcassets folder, so make sure it’s the one for your WatchKit extension). Ideally, you should have an image for all of the sizes, but these markers are only for 2x so make sure you drag the image over to its appropriate place in Images.xcassets, otherwise it might appear too large and pixelated.

Images.xcassets

Add the following line of code in between the last two lines, substituting the name appropriately if you went with a different image:

[self.map addAnnotation:mapLocation withImage:[UIImage imageNamed:@"pink_flag"] centerOffset:CGPointMake(20, -20)]

Here you can see we were able to specify a custom image and a center offset. Run your program again at this point and you’ll see both the map markers on the screen. That’s it!

Leave any questions and thoughts in the comments and I’ll get back to you =)

10 thoughts on “WatchKit tutorial: Maps on the Apple Watch

  1. For what ever reason my watch simulator just spins when I try to use maps. Even when I’m use your Xcode project. Would you have any idea why?

    Thanks

    1. Are you on the watchOS 2 beta? I’ve heard people having issues with the maps loading on the simulator. Apparently it’s working on device though (haven’t tried myself).

      Edit: Found this in the beta 5 release notes:

      Maps will no longer load for watchOS beta 1 and watchOS beta 2

      The map background never loads, but the pins do for beta 5. Hopefully this will be fixed in the next version.

  2. i am using Xcode 7 beta 3. am getting map as loading screen i can’t able to see map with static coordinates also. Is this problem in simulator or my code.

  3. It’s really helpful to me. But one more question for u, can we build route on WKInterfaceMap? I thought, it’s impossible because map on watch is static on in trailer of Apple, I saw it can draw route on map. What do you think?

    1. No, not at this time. There’s not much to the WKInterfaceMap APIs aside from just annotating the map with markers unfortunately. Apple probably has access to some additional APIs that allows them to do much more than their letting third-party developers do at this time.

  4. “Users can’t even interact with these static maps – once the user taps on it, it will open up the default Apple Maps app.” — Turns out you can actually uncheck the “Enabled” box on the Map View Attributes Inspector, and a map tap no longer takes you to Apple Maps. Great tutorial! I used this to build a watchOS app for GoTypeChart (a Pokemon Go companion app).

Leave a Reply