Welcome to Day 19 of the 31 Days of iOS. Yesterday, we talked about how to launch your application from a custom URL scheme. Today we’re going to start talking about how to use maps in your application. Specifically, we’ll cover how to show a map to the user and then how to display the user’s current location on it. We’ll continue the discussion around maps tomorrow when we show how to annotate the map. We’ll be starting with a brand new project, but if you’d like to follow along with the completed code, you can access it here.
Creating our project and handling the UI
Open up Xcode and choose File, New, Project. We’ll use a Single View Application and name it DayNineteen:
Open up the MainStoryboard.storyboard and let’s handle our UI. Find the Map View in the element selector in the bottom right of Xcode and drag it on to your view. We don’t actually want the map to take up the whole screen so we’re going to drag the top down and leave room for two labels above the map. Once you’ve added the labels, your UI should look like this:
Now open the Assistant Editor in the top right of Xcode and control + click and drag from each of the labels and the map view over to your code behind. We want to create outlets for them all. You may notice that as soon as you create the map view outlet, your code file will show an error. We’ll solve this in just a minute. Go ahead and close the Assistant Editor. Before leaving the storyboard, we need to handle one more thing: the map view delegate. Control + click and drag from the map view down to the view controller object beneath it:
In the popup that appears, select the delegate option. Now let’s handle the header file.
The header file
Open up ViewController.h. If you hover over the red error indicator, you’ll see it’s complaining about Unknown type name ‘MKMapView’. In order to fix this, we first need to open our project file and go to the target’s Build Phases. Expand the Link Binary With Libraries section and hit the + button. From this, we want to select the MapKit.framework:
Select the framework and click Add. Now return to ViewController.h and add an import for MapKit/MapKit.h. Now your app should compile and the source code should look like this:
Now if you run your app, you should see an actual map:
Displaying the current location
Showing the current location of the device is actually incredibly easy. We can accomplish this with a single line of code. Open up ViewController.m and add the line self.mapView.showsUserLocation = YES; into the viewDidLoad method so it looks like this:
Now if you run the application, you should first be asked if you’d like to allow the app to display your current location:
After you hit the OK button, you should see a blue sonar like indicator wherever your device is at (if you’re on the simulator, it may default to Apple headquarters in Cupertino or show you your actual current location):
Getting the current latitude and longitude
Showing the location on the map was super easy. Now we’ll finish things up by showing how to get the current longitude and latitude. This isn’t too tough, but does involve a bit of code. The first thing we’re going to do is right click on our project and add a new file. Pick an Objective-C class, name it CoreLocationController, and make it subclass NSObject. This class is going to contain the logic we’ll nee to interface with Core Location to get the device’s location. In the CoreLocationController.h file, we first need to import the CoreLocation/CoreLocation.h file. This will give us a reference to all of the core location classes we need. Inside this class, we’ll first implement a delegate so that we can get triggered when the location changes. We’ll then tell our class that it’s going to implement the CLLocationManagerDelegate. Finally, we add a property for CLLocationManager and a delegate property. When we’re done, the header file will look like this:
Before we can handle the implementation for our location controller, we need to add another library to our project. Return to the Build Phases tab of our project’s target settings and expand the Link Binary With Libraries section. Click the + button to add a new library and select CoreLocation.framework:
Now switch over to CoreLocationController.m. Here we’ll create an init method to handle setting up our locationManager, as well as methods from the CLLocationManagerDelegate to receive updates on the location (which will then be passed to whatever is set to the CoreLocationController’s delegate):
Now we can use this class in our view controller. Open up ViewController.h and start by making it import CoreLocationController.h. Then, make the class implement the CoreLocationControllerDelegate (so we can send location updates back to the view controller). Finally, we need to add a property to our class to contain a CoreLocationController. When we’re done, the class will look like this:
Now we can implement those changes. Switch over to ViewController.m. First, in the viewDidLoad method we need to set up our location controller, set it’s delegate, and get it going it by passing in the startUpdatingLocation message:
Now we can implement the location update and error methods:
The update method takes in a CLLocation variable which has a coordinate property. We can use that property to pull out the latitude and longitude to set the text labels each time there is a location update. If there is an error, we’re setting the latitude label to display the error’s description. Now when we run our app, we get the current location as well as the latitude and longitude written out on the screen:
Today we covered a lot of ground with maps. We went through how to put a map into your app, how to show the current user’s location, as well as how to get the actual latitude and longitude out of the user’s current location. That opens up a lot of possibilities for doing geolocation apps (apps like FourSquare or Facebook Check-ins) which are always popular. Tomorrow we’ll talk about how to display data points on top of the map. You can download the final source code from today’s app here.