Greetings! This Instructable is to explain the steps of how to make an iOS application for the Access Map Seattle project.
So, what is Access Map? Access Map is the winning project of Hack the Commute hackathon. It is a web application - a map which displays a variety of possible obstacles for people with limited mobility such as elevations, bus stops, curb cuts. This would help people with limited mobility navigate an unfamiliar neighborhood and lessen their stress of planning an outing.
The thing is, on mobile devices, mapping application is most optimized in the form of native apps. This allows the app to utilize the phone built-in functionalities and make it more accessible for people to download through the App Store.
So, our goal is to build an iOS app for Access Map that deploy their current functionalities, and more! These are the features we will create:
- A map with accessible information (elevations, bus stops, curb cuts)
- Routing option that allow users to navigate an accessible route based on their mobility
- A crowd-sourced report option that allows users to report back to the application managers about inaccessible issues
To do this, there are several components coming into play. We will cover from the very basic, installing XCode, connecting to APIs, and developing UI elements.
Step 1: Get XCode Set Up
This Instructable offers a very throughout and comprehensive tutorial on the logistics of how to get started on your first iOS development project, but we will cover the basis.
If you are already familiar with XCode, you can skip this step.
XCode is Apple's official IDE, containing a suit of software development tools to develop for Mac OS, and iOS. In order to develop an iOS software, this is what you need to have (along with a computer that run Mac OS as this is only available on Mac App Store).
To download XCode, go to the Mac App Store and download it. After downloading, installation should start automatically.
After that, open XCode, and get yourself familiar with it.
Side note: We are using Swift for this project, therefore all instructions regarding programming language will be with Swift and not Objective-C.
Step 2: Set Up the Project
- Open XCode
- Go to File > New > Project
- Click on Single View Application and click Next
- Name it Access Map
- Choose iPhone as device type
- Click Next
- Choose the location you want to save your file and choose Create
You will modify the code in ViewController.swift file, and modify UI components in Main.Storyboard. More information on Swift and how to build UI components is found at iOS Developer Library
Step 3: Connect to Mapbox API
Mapbox is a mapping platform that developers can use to incorporate maps into their application. It comes with a variety of styling and custom options that one can add, as oppose to the limited options in Google Maps, and therefore allow for maximum customization.
1. Setting your access token
- To display maps hosted by Mapbox in your app, you need to place you raccess token inside the app’s Info.plist file:
- In the Project navigator (in the left sidebar), find your app’s Info.plist.
- Select the “Information Property List” row at the top, and go to Editor ‣ Add Item.
- In the new row that is inserted, set the Key to MGLMapboxAccessToken and set the Value to your access token.
You only have to set the access token once in this file, no matter how many map views you put in your app. Access tokens help to ensure that only your apps are using your Mapbox account.
2. Downloading and installing the Mapbox iOS SDK
Now that you’ve created an Xcode project, let’s install the Mapbox iOS SDK. Download the latest release as a dynamic framework, unzip the downloaded file, and then drag and drop Mapbox.framework into the Embedded Binaries section of your project:
Be sure to check Copy items if needed for the Destination.
With the Mapbox framework added to your project, you now have access toall the classes and methods available in our SDK.
More in-depth instructions is available at Mapbox documentation, and you can start from here.
Step 4: Create the Map and Add Annotations
Now that we have XCode and Mapbox set up, let's display a basic map.
The Mapbox SDK makes it simple to show a basic map view. Just apply the code here (https://www.mapbox.com/ios-sdk/examples/) to your own ViewController.swift file and you should be able to create your own basic map application. You can adjust the center latitude and longitude to have the map open to your own desired location.
Next, let's add data to the map. You will need to have either an API which you can call to retrieve GeoJSON data, or a file of GeoJSON data already. We display the data on the map by drawing an annotation for each data point/line.
Mapbox provides some examples for adding annotations on their website. We follow their example to parse our own data file/url and add the contents as annotations to the map. For crossings and elevation data lines, we use their example on drawing lines (https://www.mapbox.com/ios-sdk/examples/line-geojs... For bus stops, we extend this example with their tutorial on drawing custom markers, and using our own bus stop image (https://www.mapbox.com/ios-sdk/examples/marker-ima... We also keep an array of each kind of data element (crossings, elevation, bus stops), in order to allow removing them later which the map focus has shifted away from a particular region of the map.
Mapbox supports a method with method signature func mapView(mapView: MGLMapView, regionDidChangeAnimated animated: Bool) -> Void, which is called whenever the mapview is changed. We place our code for refreshing the view (by removing old annotations, calling the API and adding new annotations to the map) inside of this function so that the data which is displayed on the map is refreshed every time the user zooms in or out, or pans across the screen.
Other functions allow you to customize the annotations by changing their line width/color (for line annotations) or image (for point annotations). You can experiment with these until you achieve the look you desire.
Step 5: Add Routing Functionality
Routing functionality is enabled by making changes both to the storyboard and the code.
On the storyboard side, you will want to add two text fields to your app for the starting and ending location of the route. Next, you will delegate these text fields to the code by creating outlets from Main.storyboard to ViewController.swift (refer to an iOS basic UI tutorial if you do not know how to do this).
On the code side, you will take the text entered into the start/end address fields and convert these into coordinates using a GeoCoding API (refer to this post to learn how: http://stackoverflow.com/questions/24706885/how-ca...
Next, you will also need a routing API which can accept two coordinates and return a route from one point to the other. Call the API with the start and end coordinates and use the previously mentioned Mapbox line drawing example to draw a route between the two points (linked here again: https://www.mapbox.com/ios-sdk/examples/line-geojson/)
Step 6: Display a Legend
Maps can be hard to read, especially if the annotations you are using are not intuitively linked to the data they represent. To bypass this issue, you can add a pop-up legend to your app.
Displaying the legend can actually be done entirely through the storyboard--no need to add any code. You will begin by dragging and dropping a UIButton onto your application interface and naming it "Legend" or another name of your choice. Next, you will drag and drop a new ViewController onto the storyboard for the Legend popup itself. Link the Legend button to the new ViewController by creating a segue (ctrl+click on the button > Triggered Segues > (drag from the empty circle to the new ViewController) > (select "Present as Popover"). You should adjust the size of the ViewController to be smaller than the size of the app device.
You will need an image to use as your legend. To add this to the ViewController, you should first drag and drop an ImageView onto the ViewController; adjust the size to fill the entire ViewController, then select your image from the Utilities Attributes Inspector in the right side of XCode.
Step 7: Add a Navigation Bar
In Main.storyboard, embed the main ViewController within a NavigationController (an overview of how to do so can be found at https://developer.apple.com/library/ios/reference...
Add a title to the navigation bar (we chose to set it to Map and programmatically change the title to Routing once the user has entered routing mode), and add two buttons, Back and More, to the navigation bar in the storyboard. Add code to implement hiding of Back button on view loading, and displaying the button once user enters routing mode.
Step 8: Add Options Menu
There are several other features that we would like to provide to the user, such as the ability to toggle what kinds of data are displayed and the ability to report data back to the developer; but we would like to keep the user interface as simple as possible. To do this, let's add an options menu which will pop up when the user clicks the "More" button in the navigation bar.
First, we create a popover for the More menu, following this tutorial: http://richardallen.me/2014/11/28/popovers.html.
Next, we add toggling functionality to the more menu. In the storyboard, add switch components to the More menu by dragging and dropping; add labels alongside them describing the kind of data which we are toggling on and off.
Since we are allowing user interaction with the ViewController, we create a new OptionsViewController.swift file for the options menu, and connect it to the ViewController in the storyboard (refer here to see how this is done: http://stackoverflow.com/questions/26962713/addin...). Add global variables for the data that you want to be able to toggle on and off, and connect the switches in the storyboard with functions in OptionsViewController.swift; have these functions delegate actions back to the main ViewController.swift file (You can do this by creating a protocol, eg optionsDelegate, in your OptionsViewController file and keeping a delegate of that type within your OptionsViewController. Have the mainViewController.swift file implement this protocol and set itself as your OptionsViewController delegate.)
Step 9: Add Reporting Functionality
Sometimes, users may want to report data back to the developer, notifying them that the data shown on the map is inaccurate or outdated. To allow this, we create a basic reporting functionality that allows the user to send a message to the developer.
In the storyboard, we dd new “Report” button to More menu. Next, drag and drop a new ViewController onto your storyboard, and set it up with a label: “Brief description:”, a text field, and two buttons: "cancel" and "send". We can use the storyboard to connect a Report button click action with a function in your main ViewController.swift file. Within this function, add logic to recognize user taps and display the ReportViewController as a pop-up.
Step 10: Add Different Routing Functions
AccessMap is targeted towards mobility impaired users, but there are several different user groups within this larger overarching group whose needs we would like to address. To make our app more well-suited to each kind of user, let's allow users to be able to choose what kind of function is used in calculating their route from one location to another.
We do this by creating a pop-up, similarly to how we created a pop-up for the options menu, and placing three buttons on it--one for manual wheelchair, one for power wheelchair, and one for crutches/walker, representing the different kinds of mobility aids users may be using. While this is done in the Storyboard, we also need to create a new ViewController for this pop-up, called RoutingViewController. This ViewController will define a protocol which the main ViewController will implement, similarly to what we did with OptionsViewController. Then, the RoutingViewController can delegate button clicks back to the main ViewController, who can then choose the appropriate routing function to use, make an API call, and draw the resulting route on the map.
Step 11: Check Out the Source Code!
This is an opensource project, all of our source code is available on Access Map Github.
Check it out if you'd like. We'd love to hear about comments, or suggestions.