-
Peter J. Keleher authoredPeter J. Keleher authored
Assignment 4: Documents And MapKit
Due: Apr 26, 2020, 11:59:59 pm, v1
NOTE THAT THIS IS AN EVOLVING DOCUMENT and will surely change to incorporate more information and hints as the two weeks go by. UPDATE FREQUENTLY.
Goals
Learn to use:
- UIDocument abstractions
- Document Browser
- MapKit
You will build a biking or running GPS tracker app that saves and displays tracks through the document browser. See the following for a short demo of a running version of this app:
Tasks
The following is a suggested series of steps for you to take, together with approximate points that each step will be worth. You can ignore all this and just emulate the first video above. Doing that gets you full points. However, the following set of steps is a good approach to building this app methodically.
Step 1: Circles (20 pts)
-Emulate the functionality of the Circles app from 4/7.
In your version:
- the browser should work,
- "+" brings up another view controller that allow you to visibly create something (circles are easy), saved back to a file that can
- later be-reopened
You do NOT have to create the Circles app, but slavishly following what I did in the demo and turning in Circles will get you 20 pts (and count as a Good Faith Attempt).
Step 2: Showing a Map (10 pts)
Go through the videos on 4/8 for Core Location and MapKit. On clicking a "+" button we see the map with the user's current position marked, if in view. A button allows the map to be dismissed. No tracking or line drawing needed, an empty Circles file could be written to the file system.
Step 3: Tracking the Rider (20 pts)
- Set up location updating to get location updates.
- Keep the user centered in the middle of the screen in a region with
an appropriate zoom level. Do this by choosing the last point given in
each location update (there may be many), and creating a
MKCoordinateRegion
with that point as the center, and a radius of 300 meters.
Step 4: Drawing the Line (20 pts)
- At each call of your
locationManager(manager:, didUpdateLocations:)
, you will be given an array of one or moreCLLocation
s. Draw a polyline connecting the last previous point to all the points given in this call. - Overload
mapView(mapView:, rendererFor overlay: )
to give your line appropriate attritutes: red, and lineWidth 3.
Make it work on different-sized phones, w/ orientation changes. Make it look decent. Add a control to toggle between map and satellite views.
Step 5: Saving the File and Viewing Saved Files (20 pts)
Write important information to the file. Define a GPXTrack
that
contains information about the track, including but not limited to the
set of GPS points received from Core Location.
You will need to have routines to serialize to and from JSON, which is
cast as a Data
, which is then written/read to/from the file.
Step 5: Somethin' Else
(10 pts)
No, I'm not talking about a classic jazz album, I mean that you must pick and implement one of the items from the list below to get the final 10 pts.
Hints
- My first app used the simple format specified below.
struct GPXPoint: Codable {
var latitude: Double
var longitude: Double
var altitude: Double
var time: Date
}
struct GPXSegment: Codable {
var coords : [GPXPoint]
}
struct GPXTrack : Codable {
var name : String
var link : String
var time : String
var segments : [GPXSegment] = []
var distance = "-"
var feetClimbed = "-"
}
- Your GPXDocument override both
contents()
andload()
, and should probably have a property that holds a reference to the current track.
This is an example GPXTrack
using the default JSON
serialization to put to a file (use a text editor to look at).
Additional Task, and Extra Credit
Pick one or two of the tasks below for the last 10 points of this project.
Pick up to another three for 10 pts bonus for each you accomplish (up to a max of three), or a donut each,
your choice. You'd have to come by to pick up the donut. The points
will be appliable on either the assign5
or the final (which will be
out of 200 pts):
- (5 pts) Get your app to read and write files with the .gpx extension. Instead of
reading and writing .gpx436, read and write .gpx. Here, I'm just
asking you to get the UTI setup correct so that the document and
browser will allow you to read and write files with the
.gpx
extension. Doesn't matter what you write. Note that this is more difficult as the straightforward descriptions on how to do this (google) did not work for me. My version of the app can write to.gpx
, but only because I use a very general UTI that allows me to read and write everything. I'd like someone to discover the trick of doing this correctly. Might take you five minutes. Or not. - (5 pts) Get your app to read and write real gpx files. Your app should be
able to write read and write RideWithGPX files. Don't worry, look at
this file and you will see the format is dirt simple (though
there may be multiple
trkseg
s). - (5 pts) Show a pre-planned route. Show the route (w/ a different color) from another gpx file as you are recording a ride, so that the rider can follow a pre-planned route. Allow the user to choose which other ride to use by adding a button to the screen which showing a pre-recorded ride. Must be able to turn this off as well.
- (10 pts) Poor man's turn-by-turn navigation - The best way to do turn-by-turn navigation is to know when and where you turn onto a different street. We don't have that information, so you can try to use heuristics, like "turned left or right between 70 and 110 degrees and stayed on the new heading two or three points". Display the navigation in a line overlaying the map at the top of the screen. Navigation cues should be of the form: "Turn right in 50 feet", just showing the next turn. Of course, this only works if you have a pre-planned route as above.
- (5 pts) Map orientation button - Display a little icon (maybe check out MKCompassButton) that when clicked upon changes the map orientation so that either the current direction of travel is "up", or north is "up".
- (5 pts) Tracking vs not tracking map By default, our app tracks the rider on the map: keeps him/her centered in the middle of the screen with a set magnification. Cease tracking when you detect that the rider has manipulated the display, either moving, zooming, or rotating. Allow the rider to restart tracking by hitting a button, ideally the above map orientation button.