iOS Media App Development IGME-590-03

Project 1 - RIT Maps

Overview: An Application Definition Statement is a one or two line statement answering these two questions: What's the app do? and Who is it for?

Here's ours: RIT Maps is a mapping application that displays RIT buildings and relevant locations to prospective students and their parents.

Requirements and Grade Rubric

(85%) The following is the minimum capability that is required of the App:

  1. Master/Detail template (5%):
    • Make the app Universal, but you are only required to build the iPad version.
    • Make sure the Edit and + buttons from the template are gone, and that the titles of the View Controllers are "Places" and "RIT Map"
    • The Master view controller is a table view, the Detail view controller will display a MKMapView.
  2. Data (5%):
    • The app will load the JSON data file of buildings and convert it to an array of NSDictionary instances.
    • The NSDictionary instance data will be stored in a model class named RITBuilding
  3. The RITBuilding class (10%):
    • The RITBuilding class designated initializer will be: - (id)initWithDictionary:(NSDictionary*)dictionary
    • Model classes should validate their data. Some of the buildings returned from the web service are lacking history and full-description keys. If any of the NSString values come back from the JSON dictionary as nil, initialize them to a default value. See Hints below for an example.
    • The RITBuilding class will conform to the MKAnnotation protocol
    • Because the buildings will never move, initialize the values of coordinate, title, and subtitle in the designated initializer
    • will have the following properties:
	@property (nonatomic, copy) NSString *name;
	@property (nonatomic, copy) NSString *mdo_id;
	@property (nonatomic, copy) NSString *bDescription;
	@property (nonatomic) float latitude;
	@property (nonatomic) float longitude;
	@property (nonatomic, copy) NSString *polygon_id;
	@property (nonatomic) NSMutableArray *path;
	@property (nonatomic, copy) NSString *image;
	@property (nonatomic, copy) NSString *abbreviation;
	@property (nonatomic, copy) NSString *history;
	@property (nonatomic, copy) NSString *fulldescription;
  1. The table view (15%):
    • will display all 75 RITBuilding instances and display both a title and a subtitle.
    • The names of the buildings will appear alphabetically.
    • When a table row is tapped, the map will zoom in on and select that annotation on the map.
  2. MapView (50%):
    • There will be an annotation for every RITBuilding (5%)
    • The map will display correctly when the device is rotated. (3%)
    • The users current position will be displayed on the map. (2%)
    • There will be a UISegmentedControl in the navigation bar than controls what type of map will be displayed. The default mapType will be hybrid. (5%)
    • When the app starts up, the George Eastman Building will be selected at the center of the map, and the map will be at an appropriate zoom level. You'll have to search the array for the right RITBuilding instance. (5%)
    • A selected annotation will display both a title and a subtitle and a callout button. (5%)
    • Tapping a annotation callout will reveal the fulldescription information for that building instance. This information will appear in a UIPopoverController. See this Stack overflow post for ideas how to accomplish this. Also check out this UIPopoverController tutorial (25%)

Ideas for enhancements (Up to 25%)

Deductions

Coding Standards

Hints

   - (NSMutableArray *)parsePath:(NSString *)path{
      NSMutableArray *array = [NSMutableArray array];
      NSArray *points = [path componentsSeparatedByString:@"|"];
      for (NSString *p in points) {
         NSArray *values = [p componentsSeparatedByString:@","];
         float latitude = [values[0] floatValue];
         float longitude = [values[1] floatValue];

         CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude,longitude);
         [array addObject: [NSValue valueWithMKCoordinate: coordinate]];
      }
      return array;
   }
   // sort mutable array alphabetically
   NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"lastname" ascending:YES];
   NSArray *sortDescriptors = @[sortDescriptor];
   [myMutablePeopleArray sortUsingDescriptors:sortDescriptors];
   // a predicate is a statement or assertion
   // in this case, that the abbreviation property is equal to @"GOL"
   NSPredicate *predicate = [NSPredicate predicateWithFormat:@"abbreviation == %@", @"GOL"];
   NSArray *filteredArray = [self.buildings filteredArrayUsingPredicate:predicate];
   id match = [filteredArray objectAtIndex:0];
   if(d[@"name"] == nil){
      self.name = @"No name found";
   } else {
      self.name = d[@"name"];
   }

   // or as a one-liner using the ternary operator
   self.name = d[@"name"] ?  d[@"name"] : @"No name found";
   // get our NSArray
   NSArray *array = [building path];

   // initialize a C-array of points
   CLLocationCoordinate2D points[array.count];

   // loop through the C-array and initialize it
   for (int i=0; i<array.count; i++){
      points[i] = [(NSValue*)array[i] MKCoordinateValue];
   }

Screen Shots

Annotation with 2 callouts UIPopoverController containing a UIWebView Portrait Orientation Optional search bar Optional: overlaying the selected building Optional: overlaying the parking lots in green

Submission


App Feature Brainstorming (not part of the requirements above)

Let's come up with some app features in class that will meet out application definition statement. A good app can be though of as a "Focused solution to a well-defined problem", but here, let's come up with every feature we can that might help our target audience.