Software engineer, data guy, Open Source enthusiast, New Hampshire resident, husband, father. Fan of guitars, hiking, photography, homebrewing, sarcasm.
Create an iOS Swift app to send your location to a Rails API and display on Google Maps
In this post I’ll share a proof of concept project I worked on to create a Swift iOS application to track a user’s location and send the data back to a Rails API. I thought it would be interesting to tinker with a lot of geolocation data and display it back to the user. For this post I decided to simply display the data on a Google Map using the directions API.
Part 1: the Rails backend
Initial project setup:
Add Ruby gems, edit file: Gemfile, add:
Execute bundle install to install the gems.
Ran the geocoder generator: rails generate geocoder:config. The geocoder gem is used to look up addresses from latitude and longitude. You’ll need to add an ENV variable for your Google Maps API key. Modified file: config/initializers/geocoder.rb
Created the User model via devise generator.
Created a migration for the location payloads. This is the table that will contain the data sent from iOS. new file: migrate/20160630145853_create_location_payloads.rb
Execute rake db:migrate to create the new table.
Edit the user model to add model association, edit file: app/models/user.rb
Edit the location payload model to add the geocoder config and model association, edit file: app/models/location_payload.rb
Create a new API controller to receive the location payloads, new file: app/controllers/api/location_payloads_controller.rb
Add create route for location payloads, edit file: config/routes.rb
Execute rails s -b 0.0.0.0 to start the web server (Puma).
Part 2: iOS Swift app code
Now that the backend is ready to receive the location payloads, we’ll move onto the iOS code. I created a new project in Xcode: iOS Single View application, product name: “Location Tracker”, Language: Swift, Devices: Universal.
In the application’s Capabilities section, I enabled Location updates in the background modes. In the Info section, under Custom iOS Target Properties, section: Required background modes, “App registers for location updates” should be included. In addition, I added keys “Privacy - Location Always Usage Description” and “Privacy - Location When In Use Usage Description” with the values “Location is required.”
I dumped all the location services code in the ViewController.swift file:
At this point, I plugged in my iPhone 6 and built/ran the app for my device. After accepting the request to run location services, it opened to a white screen and started sending my location to the Rails API.
Part 3: Google Maps integration
For sake of generating a neat screenshot for this post, and hiding my personal GPS coordinates, I decided to seed some data. Edit file: db/seeds.rb
Executed rake db:seed to seed my database.
Created a new API route to visualize the locations for a user, edit file: config/routes.rb
Created the new controller, file: app/controllers/locations_controller.rb
Added a simple ERB view to create a map container div, output the location data as JSON, and embed the Google Maps API key, file: app/views/locations/index.html.erb
Added some CSS to make the map div fullscreen, edit file: app/assets/stylesheets/application.css
And last, I added a new JS file to render the location payloads using the Google Maps API directions service, new file: app/assets/javascripts/locations.js
I browsed to http://10.0.1.4:3000/users/1/locations to see: