How To Make an App Like Runkeeper: Part 1
Runkeeper, a GPS app like the one you’re about to make, has over 40 million users! This tutorial will show you how to make an app like Runkeeper. By Richard Critz.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
How To Make an App Like Runkeeper: Part 1
35 mins
How About Some Breadcrumbs?
The post-run map is stunning, but how about having a map during the run?
The storyboard is set up using UIStackView
s to make it easy to add one!
First, open NewRunViewController.swift and import MapKit:
import MapKit
Now, open Main.storyboard and find the New Run View Controller Scene. Be sure the Document Outline is visible. If not, press the button outlined in red below:
Drag a UIView
into the Document Outline and place it between the Top Stack View and the Button Stack View. Make sure it appears between them and not inside one of them. Double-click it and rename it to Map Container View.
In the Attributes Inspector, check Hidden under Drawing.
In the Document Outline, Control-drag from the Map Container View to the Top Stack View and select Equal Widths from the pop-up.
Drag an MKMapView
into the Map Container View. Press the Add New Constraints button (A.K.A the "Tie Fighter button") and set all 4 constraints to 0. Make sure Constrain to margins is not checked. Click Add 4 Constraints.
With Map View selected in the Document Outline, open the Size Inspector (View\Utilities\Show Size Inspector). Double-click on the constraint Bottom Space to: Superview.
Change the priority to High (750).
In the Document Outline, Control-drag from Map View to New Run View Controller and select delegate.
Open the Assistant Editor, ensure it is showing NewRunViewController.swift and Control-drag from the Map View to create an outlet named mapView. Control-drag from Map Container View and create an outlet called mapContainerView.
Close the Assistant Editor and open NewRunViewController.swift.
Add the following to the top of startRun()
:
mapContainerView.isHidden = false
mapView.removeOverlays(mapView.overlays)
To the top of stopRun()
add the following:
mapContainerView.isHidden = true
Now, you need an MKMapViewDelegate
to provide a renderer for the line. Add the following implementation in an extension
at the bottom of the file:
extension NewRunViewController: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
guard let polyline = overlay as? MKPolyline else {
return MKOverlayRenderer(overlay: overlay)
}
let renderer = MKPolylineRenderer(polyline: polyline)
renderer.strokeColor = .blue
renderer.lineWidth = 3
return renderer
}
}
This is just like the delegate you wrote in RunDetailsViewController.swift except that the line is blue.
Finally, you just need to add the line segment overlay and update the map region to keep it focused on the area of your run. Add the following to locationManager(_:didUpdateLocations:)
after the line distance = distance + Measurement(value: delta, unit: UnitLength.meters)
:
let coordinates = [lastLocation.coordinate, newLocation.coordinate]
mapView.add(MKPolyline(coordinates: coordinates, count: 2))
let region = MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 500, 500)
mapView.setRegion(region, animated: true)
Build and run and start a new run. You will see your new map updating in real time!
Where To Go From Here?
Click here to download the the project up to this point.
You may have noticed that the user's pace always displays in "min/mi", even if your locale causes the distance to be displayed in meters (or km). Find a way to use the locale to choose between .minutesPerMile
and .minutesPerKilometer
in the places you call FormatDisplay.pace(distance:seconds:outputUnit:)
.
Continue to part two of the How to Make an App Like Runkeeper tutorial where you will introduce an achievement badge system.
As always, I look forward to your comments and questions! :]