diff --git a/.gitignore b/.gitignore index d0ce7de..529f3a5 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,6 @@ DerivedData # CocoaPods Pods + +# Git +*.orig diff --git a/Music City Center.xcodeproj/project.pbxproj b/Music City Center.xcodeproj/project.pbxproj index d8233e1..b3700aa 100644 --- a/Music City Center.xcodeproj/project.pbxproj +++ b/Music City Center.xcodeproj/project.pbxproj @@ -7,8 +7,14 @@ objects = { /* Begin PBXBuildFile section */ + 2D4FF35B18D816C200A02B69 /* MCCDirectionsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D4FF35A18D816C200A02B69 /* MCCDirectionsTableViewController.m */; }; 2D4FF35F18D82FCD00A02B69 /* MCCSettingsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D4FF35E18D82FCD00A02B69 /* MCCSettingsTableViewController.m */; }; 2D9F3ED118A1D8F700AA3F6C /* UIView+Screenshot.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D9F3ED018A1D8F700AA3F6C /* UIView+Screenshot.m */; }; + 2DA0202518DAAFAA0099E975 /* MCCArtAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DA0202418DAAFAA0099E975 /* MCCArtAnnotation.m */; }; + 2DA0202718DAAFCE0099E975 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DA0202618DAAFCE0099E975 /* MapKit.framework */; }; + 2DA0202918DAC81C0099E975 /* guitar.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 2DA0202818DAC81C0099E975 /* guitar.jpg */; }; + 2DA0202B18DAC8270099E975 /* music.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 2DA0202A18DAC8270099E975 /* music.jpg */; }; + 2DA0202D18DAC82E0099E975 /* trumpet.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 2DA0202C18DAC82E0099E975 /* trumpet.jpg */; }; 2DD8447518BC447000B4296F /* MCCResponseSerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DD8447418BC447000B4296F /* MCCResponseSerializer.m */; }; 4B8E50CB18A04A93009F4266 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B8E50CA18A04A93009F4266 /* Foundation.framework */; }; 4B8E50CD18A04A93009F4266 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B8E50CC18A04A93009F4266 /* CoreGraphics.framework */; }; @@ -50,10 +56,18 @@ /* Begin PBXFileReference section */ 2394C53480684646969EDC29 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 2D4FF35918D816C200A02B69 /* MCCDirectionsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCCDirectionsTableViewController.h; sourceTree = ""; }; + 2D4FF35A18D816C200A02B69 /* MCCDirectionsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MCCDirectionsTableViewController.m; sourceTree = ""; }; 2D4FF35D18D82FCD00A02B69 /* MCCSettingsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCCSettingsTableViewController.h; sourceTree = ""; }; 2D4FF35E18D82FCD00A02B69 /* MCCSettingsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MCCSettingsTableViewController.m; sourceTree = ""; }; 2D9F3ECF18A1D8F700AA3F6C /* UIView+Screenshot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+Screenshot.h"; sourceTree = ""; }; 2D9F3ED018A1D8F700AA3F6C /* UIView+Screenshot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+Screenshot.m"; sourceTree = ""; }; + 2DA0202318DAAFAA0099E975 /* MCCArtAnnotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCCArtAnnotation.h; sourceTree = ""; }; + 2DA0202418DAAFAA0099E975 /* MCCArtAnnotation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MCCArtAnnotation.m; sourceTree = ""; }; + 2DA0202618DAAFCE0099E975 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; }; + 2DA0202818DAC81C0099E975 /* guitar.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = guitar.jpg; sourceTree = ""; }; + 2DA0202A18DAC8270099E975 /* music.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = music.jpg; sourceTree = ""; }; + 2DA0202C18DAC82E0099E975 /* trumpet.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = trumpet.jpg; sourceTree = ""; }; 2DD8447318BC447000B4296F /* MCCResponseSerializer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCCResponseSerializer.h; sourceTree = ""; }; 2DD8447418BC447000B4296F /* MCCResponseSerializer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MCCResponseSerializer.m; sourceTree = ""; }; 4B8E50C718A04A93009F4266 /* Music City Center.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Music City Center.app"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -107,6 +121,7 @@ files = ( 4B8E50CD18A04A93009F4266 /* CoreGraphics.framework in Frameworks */, 4B8E50CF18A04A93009F4266 /* UIKit.framework in Frameworks */, + 2DA0202718DAAFCE0099E975 /* MapKit.framework in Frameworks */, 4B8E50CB18A04A93009F4266 /* Foundation.framework in Frameworks */, AE1DFE2FCE634724A956700A /* libPods.a in Frameworks */, ); @@ -125,6 +140,21 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 2D4FF35718D8019600A02B69 /* View Controllers */ = { + isa = PBXGroup; + children = ( + 4B8E50DF18A04A93009F4266 /* MCCMapViewController.h */, + 4B8E50E018A04A93009F4266 /* MCCMapViewController.m */, + 4BBE291B18A0CD3700C38EB7 /* MCCFloorViewController.h */, + 4BBE291C18A0CD3700C38EB7 /* MCCFloorViewController.m */, + 2D4FF35918D816C200A02B69 /* MCCDirectionsTableViewController.h */, + 2D4FF35A18D816C200A02B69 /* MCCDirectionsTableViewController.m */, + 2D4FF35D18D82FCD00A02B69 /* MCCSettingsTableViewController.h */, + 2D4FF35E18D82FCD00A02B69 /* MCCSettingsTableViewController.m */, + ); + name = "View Controllers"; + sourceTree = ""; + }; 2DD8447218BC444C00B4296F /* Networking */ = { isa = PBXGroup; children = ( @@ -159,6 +189,7 @@ 4B8E50C918A04A93009F4266 /* Frameworks */ = { isa = PBXGroup; children = ( + 2DA0202618DAAFCE0099E975 /* MapKit.framework */, 4B8E50CA18A04A93009F4266 /* Foundation.framework */, 4B8E50CC18A04A93009F4266 /* CoreGraphics.framework */, 4B8E50CE18A04A93009F4266 /* UIKit.framework */, @@ -171,21 +202,18 @@ 4B8E50D018A04A93009F4266 /* Music City Center */ = { isa = PBXGroup; children = ( - 841DD66718B8B7F3009626B8 /* Nav */, + 841DD66718B8B7F3009626B8 /* Models */, + 2D4FF35718D8019600A02B69 /* View Controllers */, 2DD8447218BC444C00B4296F /* Networking */, 4B8E50D918A04A93009F4266 /* MCCAppDelegate.h */, 4B8E50DA18A04A93009F4266 /* MCCAppDelegate.m */, 4B8E50DC18A04A93009F4266 /* Main.storyboard */, - 4B8E50DF18A04A93009F4266 /* MCCMapViewController.h */, - 4B8E50E018A04A93009F4266 /* MCCMapViewController.m */, - 4BBE291B18A0CD3700C38EB7 /* MCCFloorViewController.h */, - 4BBE291C18A0CD3700C38EB7 /* MCCFloorViewController.m */, 4B8E50E218A04A93009F4266 /* Images.xcassets */, 4B8E50D118A04A93009F4266 /* Supporting Files */, 2D9F3ECF18A1D8F700AA3F6C /* UIView+Screenshot.h */, 2D9F3ED018A1D8F700AA3F6C /* UIView+Screenshot.m */, - 2D4FF35D18D82FCD00A02B69 /* MCCSettingsTableViewController.h */, - 2D4FF35E18D82FCD00A02B69 /* MCCSettingsTableViewController.m */, + 2DA0202318DAAFAA0099E975 /* MCCArtAnnotation.h */, + 2DA0202418DAAFAA0099E975 /* MCCArtAnnotation.m */, ); path = "Music City Center"; sourceTree = ""; @@ -193,6 +221,9 @@ 4B8E50D118A04A93009F4266 /* Supporting Files */ = { isa = PBXGroup; children = ( + 2DA0202C18DAC82E0099E975 /* trumpet.jpg */, + 2DA0202A18DAC8270099E975 /* music.jpg */, + 2DA0202818DAC81C0099E975 /* guitar.jpg */, 4B8E50D218A04A93009F4266 /* Music City Center-Info.plist */, 4B8E50D318A04A93009F4266 /* InfoPlist.strings */, 4B8E50D618A04A93009F4266 /* main.m */, @@ -219,7 +250,7 @@ name = "Supporting Files"; sourceTree = ""; }; - 841DD66718B8B7F3009626B8 /* Nav */ = { + 841DD66718B8B7F3009626B8 /* Models */ = { isa = PBXGroup; children = ( 841DD66A18B8B8F4009626B8 /* MCCFloorPlanLocation.h */, @@ -241,7 +272,7 @@ 4BF4026218BE98210067AD1A /* MCCFloorPlanImage.h */, 4BF4026318BE98210067AD1A /* MCCFloorPlanImage.m */, ); - name = Nav; + name = Models; sourceTree = ""; }; /* End PBXGroup section */ @@ -296,6 +327,11 @@ TargetAttributes = { 4B8E50C618A04A93009F4266 = { DevelopmentTeam = 7MA825R8KR; + SystemCapabilities = { + com.apple.iOS = { + enabled = 1; + }; + }; }; 4B8E50E718A04A93009F4266 = { TestTargetID = 4B8E50C618A04A93009F4266; @@ -326,7 +362,10 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 2DA0202B18DAC8270099E975 /* music.jpg in Resources */, + 2DA0202D18DAC82E0099E975 /* trumpet.jpg in Resources */, 4B8E50E318A04A93009F4266 /* Images.xcassets in Resources */, + 2DA0202918DAC81C0099E975 /* guitar.jpg in Resources */, 4B8E50D518A04A93009F4266 /* InfoPlist.strings in Resources */, 4B8E50DE18A04A93009F4266 /* Main.storyboard in Resources */, ); @@ -385,6 +424,7 @@ 841DD68718B8C501009626B8 /* MCCNavPath.m in Sources */, 841DD68A18B8CF88009626B8 /* MCCEvent.m in Sources */, 841DD67518B8BCB8009626B8 /* MCCFloorPlanImageMapping.m in Sources */, + 2DA0202518DAAFAA0099E975 /* MCCArtAnnotation.m in Sources */, 841DD67218B8BC7D009626B8 /* MCCNavData.m in Sources */, 841DD66C18B8B8F4009626B8 /* MCCFloorPlanLocation.m in Sources */, 4B8E50DB18A04A93009F4266 /* MCCAppDelegate.m in Sources */, @@ -396,6 +436,7 @@ 4BBE291D18A0CD3700C38EB7 /* MCCFloorViewController.m in Sources */, 2D9F3ED118A1D8F700AA3F6C /* UIView+Screenshot.m in Sources */, 841DD67E18B8BF6B009626B8 /* MCCClient.m in Sources */, + 2D4FF35B18D816C200A02B69 /* MCCDirectionsTableViewController.m in Sources */, 4BF4026418BE98210067AD1A /* MCCFloorPlanImage.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Music City Center/Base.lproj/Main.storyboard b/Music City Center/Base.lproj/Main.storyboard index f539ca7..3026d57 100644 --- a/Music City Center/Base.lproj/Main.storyboard +++ b/Music City Center/Base.lproj/Main.storyboard @@ -65,7 +65,7 @@ - + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -371,6 +445,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/Music City Center/MCCArtAnnotation.h b/Music City Center/MCCArtAnnotation.h new file mode 100644 index 0000000..bc89243 --- /dev/null +++ b/Music City Center/MCCArtAnnotation.h @@ -0,0 +1,23 @@ +// +// MCCArtAnnotation.h +// Music City Center +// +// Created by Seth Friedman on 3/20/14. +// Copyright (c) 2014 Music City Center. All rights reserved. +// + +#import + +@import MapKit; + +@interface MCCArtAnnotation : NSObject + +@property (nonatomic, readonly, copy) NSString *title; +@property (nonatomic, readonly) CLLocationCoordinate2D coordinate; +@property (strong, nonatomic) UIImage *image; // TODO - Change to imageURL once we get a way to fetch that from the server + +- (instancetype)initWithTitle:(NSString *)title coordinate:(CLLocationCoordinate2D)coordinate andImage:(UIImage *)image; + ++ (instancetype)artAnnotationWithTitle:(NSString *)title coordinate:(CLLocationCoordinate2D)coordinate andImage:(UIImage *)image; + +@end diff --git a/Music City Center/MCCArtAnnotation.m b/Music City Center/MCCArtAnnotation.m new file mode 100644 index 0000000..786d785 --- /dev/null +++ b/Music City Center/MCCArtAnnotation.m @@ -0,0 +1,35 @@ +// +// MCCArtAnnotation.m +// Music City Center +// +// Created by Seth Friedman on 3/20/14. +// Copyright (c) 2014 Music City Center. All rights reserved. +// + +#import "MCCArtAnnotation.h" + +@implementation MCCArtAnnotation + +#pragma mark - Designated Initializer + +- (instancetype)initWithTitle:(NSString *)title coordinate:(CLLocationCoordinate2D)coordinate andImage:(UIImage *)image { + self = [super init]; + + if (self) { + _title = title; + _coordinate = coordinate; + _image = image; + } + + return self; +} + +#pragma mark - Factory Method + ++ (instancetype)artAnnotationWithTitle:(NSString *)title coordinate:(CLLocationCoordinate2D)coordinate andImage:(UIImage *)image { + return [[self alloc] initWithTitle:title + coordinate:coordinate + andImage:image]; +} + +@end diff --git a/Music City Center/MCCClient.h b/Music City Center/MCCClient.h index 89e4825..67760ec 100644 --- a/Music City Center/MCCClient.h +++ b/Music City Center/MCCClient.h @@ -17,9 +17,15 @@ + (instancetype)sharedClient; - (NSURLSessionDataTask *)fetchFloorPlan:(NSString *)floorPlanId withCompletionBlock:(void (^)(MCCNavData *navData))completionBlock; + - (NSURLSessionDataTask *)shortestPathOnFloorPlan:(NSString *)floorPlanId from:(NSString *)from to:(NSString *)endLocationId withCompletionBlock:(void (^)(MCCNavPath *path))completionBlock; + - (NSURLSessionDataTask *)events:(NSString *)floorPlanId on:(NSDate *)date withCompletionBlock:(void (^)(NSArray *events))completionBlock; + - (NSURLSessionDataTask *)locationFromiBeacons:(NSDictionary *)beaconData forFloorPlan:(NSString *)floorPlanId withCompletionBlock:(void (^)(MCCFloorPlanLocation *floorPlanLocation))completionBlock; +- (NSURLSessionDataTask *)fetchEdgeImageForFloorPlanId:(NSString *)floorPlanId startLocationId:(NSString *)startLocationId andEndLocationId:(NSString *)endLocationId withCompletionBlock:(void (^)(UIImage *edgeImage))completionBlock; + + @end diff --git a/Music City Center/MCCClient.m b/Music City Center/MCCClient.m index 9fd46d2..d9c6537 100644 --- a/Music City Center/MCCClient.m +++ b/Music City Center/MCCClient.m @@ -136,6 +136,7 @@ - (NSURLSessionDataTask *)events:(NSString *)floorPlanId on:(NSDate *)date withC return dataTask; } + -(NSURLSessionDataTask *)locationFromiBeacons:(NSDictionary *)beaconData forFloorPlan:(NSString *)floorPlanId withCompletionBlock:(void (^)(MCCFloorPlanLocation *))completionBlock { NSLog(@"Location from iBeacons"); @@ -165,6 +166,32 @@ -(NSURLSessionDataTask *)locationFromiBeacons:(NSDictionary *)beaconData forFloo otherButtonTitles:nil] show]; }]; + + return dataTask; +} + +- (NSURLSessionDataTask *)fetchEdgeImageForFloorPlanId:(NSString *)floorPlanId startLocationId:(NSString *)startLocationId andEndLocationId:(NSString *)endLocationId withCompletionBlock:(void (^)(UIImage *edgeImage))completionBlock { + NSString *path = [NSString stringWithFormat:@"image/edge/%@/%@/%@", floorPlanId, startLocationId, endLocationId]; + + NSURLSessionDataTask *dataTask = [self GET:path + parameters:nil + success:^(NSURLSessionDataTask *task, id responseObject) { + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)task.response; + + if (httpResponse.statusCode == 200) { + completionBlock(responseObject); + } + } failure:^(NSURLSessionDataTask *task, NSError *error) { + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)task.response; + NSLog(@"Received HTTP %ld", httpResponse.statusCode); + // Failure + [[[UIAlertView alloc] initWithTitle:@"Edge Image Error" + message:[NSString stringWithFormat:@"%@",error] + delegate:nil + cancelButtonTitle:@"OK" + otherButtonTitles:nil] show]; + }]; + return dataTask; } diff --git a/Music City Center/MCCDirectionsTableViewController.h b/Music City Center/MCCDirectionsTableViewController.h new file mode 100644 index 0000000..107ca45 --- /dev/null +++ b/Music City Center/MCCDirectionsTableViewController.h @@ -0,0 +1,15 @@ +// +// MCCDirectionsTableViewController.h +// Music City Center +// +// Created by Seth Friedman on 3/18/14. +// Copyright (c) 2014 Music City Center. All rights reserved. +// + +#import + +@interface MCCDirectionsTableViewController : UITableViewController + +@property (nonatomic, copy) NSArray *directions; + +@end diff --git a/Music City Center/MCCDirectionsTableViewController.m b/Music City Center/MCCDirectionsTableViewController.m new file mode 100644 index 0000000..6da5296 --- /dev/null +++ b/Music City Center/MCCDirectionsTableViewController.m @@ -0,0 +1,58 @@ +// +// MCCDirectionsTableViewController.m +// Music City Center +// +// Created by Seth Friedman on 3/18/14. +// Copyright (c) 2014 Music City Center. All rights reserved. +// + +#import "MCCDirectionsTableViewController.h" + +@interface MCCDirectionsTableViewController () + +@end + +@implementation MCCDirectionsTableViewController + +#pragma mark - View Controller Lifecycle + +- (void)viewDidLoad { + [super viewDidLoad]; +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +#pragma mark - Table View Data Source + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return [self.directions count]; +} + + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + static NSString *cellIdentifier = @"DirectionCell"; + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier + forIndexPath:indexPath]; + + cell.textLabel.text = self.directions[indexPath.row]; + + return cell; +} + +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender +{ + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end diff --git a/Music City Center/MCCFloorPlanImageLocation.m b/Music City Center/MCCFloorPlanImageLocation.m index 159388d..da7a994 100644 --- a/Music City Center/MCCFloorPlanImageLocation.m +++ b/Music City Center/MCCFloorPlanImageLocation.m @@ -30,4 +30,20 @@ + (instancetype)floorPlanImageLocationWithX:(NSInteger)x andY:(NSInteger)y { andY:y]; } +#pragma mark - NSObject + +- (BOOL)isEqual:(id)object { + return [object isKindOfClass:[self class]] && (self == object || [self isEqualToFloorPlanImageLocation:object]); +} + +- (NSUInteger)hash { + return self.x ^ self.y; +} + +#pragma mark - Helper Method + +- (BOOL)isEqualToFloorPlanImageLocation:(MCCFloorPlanImageLocation *)floorPlanImageLocation { + return self.x == floorPlanImageLocation.x && self.y == floorPlanImageLocation.y; +} + @end diff --git a/Music City Center/MCCFloorViewController.m b/Music City Center/MCCFloorViewController.m index 94e47a5..95209dc 100644 --- a/Music City Center/MCCFloorViewController.m +++ b/Music City Center/MCCFloorViewController.m @@ -19,6 +19,9 @@ #import "MCCFloorPlanImageMapping.h" #import "MCCFloorPlanLocation.h" #import +#import "MCCDirectionsTableViewController.h" +#import "MCCArtAnnotation.h" +#import static NSString * const floorPlanId = @"full-test-1"; @@ -27,6 +30,15 @@ @interface MCCFloorViewController () @property (weak, nonatomic) IBOutlet MBXMapView *mapView; +@property (weak, nonatomic) IBOutlet UIButton *currentDirectionButton; +@property (weak, nonatomic) IBOutlet UIImageView *imageView; + +@property (strong, nonatomic) UIBarButtonItem *endButton; + +@property (weak, nonatomic) MCCNavData *navData; + +@property (nonatomic, getter = isRouting) BOOL routing; +@property (nonatomic, copy) NSArray *directions; @property (strong, nonatomic) NSString *currentFloor; @@ -37,7 +49,9 @@ @interface MCCFloorViewController () @property (strong, nonatomic) MCCFloorPlanLocation *endLocation; @property (strong, nonatomic) NSDictionary *locationData; -@property (strong, nonatomic) MKPolyline *polyline; +@property (strong, nonatomic) NSMutableArray *annotations; + +@property (strong, nonatomic) MKPolyline *routePolyline; @property (strong, nonatomic) NSDictionary *mapIDs; @@ -61,12 +75,9 @@ -(NSDictionary *)mapIDs { - (void)setCurrentFloor:(NSString *)currentFloor { _currentFloor = currentFloor; - - MCCAppDelegate *appDelegate = [UIApplication sharedApplication].delegate; - - self.topLeft = [appDelegate.navData.mapping coordinatesOfLocation:[NSString stringWithFormat:@"%@-TL", _currentFloor]]; - self.bottomRight = [appDelegate.navData.mapping coordinatesOfLocation:[NSString stringWithFormat:@"%@-BR", _currentFloor]]; + self.topLeft = [self.navData.mapping coordinatesOfLocation:[NSString stringWithFormat:@"%@-TL", _currentFloor]]; + self.bottomRight = [self.navData.mapping coordinatesOfLocation:[NSString stringWithFormat:@"%@-BR", _currentFloor]]; NSInteger sizeX = self.bottomRight.x - self.topLeft.x; NSInteger sizeY = self.bottomRight.y - self.topLeft.y; @@ -80,20 +91,106 @@ - (void)setCurrentFloor:(NSString *)currentFloor { } -# pragma mark - View Controller Lifecycle + +#pragma mark - Custom Getter + +-(NSMutableArray *)annotations { + if (!_annotations) { + _annotations = [NSMutableArray array]; + } + return _annotations; +} + +-(MCCNavData *)navData { + MCCAppDelegate *appDelegate = [UIApplication sharedApplication].delegate; + return appDelegate.navData; +} + +- (UIBarButtonItem *)endButton { + if (!_endButton) { + _endButton = [[UIBarButtonItem alloc] initWithTitle:@"End" + style:UIBarButtonItemStyleBordered + target:self + action:@selector(endTapped:)]; + } + + return _endButton; +} + +#pragma mark - Custom Setter + +- (void)setRouting:(BOOL)routing { + _routing = routing; + self.currentDirectionButton.hidden = !routing; + + if (routing) { + // TODO - The user sees this change from "Button" to the first direction's + // text. While we could just have the button start with no text, it would + // be nice to animate the button down from the navbar (like in Maps.app) + // once the text has been set. + [self.currentDirectionButton setTitle:[self.directions firstObject] + forState:UIControlStateNormal]; + self.navigationItem.rightBarButtonItem = self.endButton; + + // TODO - Fill edge image + /*[self.imageView setImageWithURL:{URL} + placeholderImage:nil];*/ + } else { + self.navigationItem.rightBarButtonItem = nil; + [self.mapView removeOverlay:self.routePolyline]; + self.routePolyline = nil; + self.directions = nil; + [self.mapView removeAnnotations:self.annotations]; + [self.annotations removeAllObjects]; + } +} + +#pragma mark - View Controller Lifecycle - (void)viewDidLoad { [super viewDidLoad]; - self.currentFloor = @"1"; - self.mapView.mapID = self.mapIDs[self.currentFloor]; - self.mapView.region = MKCoordinateRegionMake(CLLocationCoordinate2DMake(36.1575, -86.777), MKCoordinateSpanMake(.004, .004)); + self.mapView.region = MKCoordinateRegionMake(CLLocationCoordinate2DMake(36.1575, -86.777), MKCoordinateSpanMake(.004, .004)); self.mapView.delegate = self; + // Hard code some art markers +// [self.mapView addAnnotation:[MCCArtAnnotation artAnnotationWithTitle:@"Guitar Picture" +// coordinate:CLLocationCoordinate2DMake(36.1585, -86.777) +// andImage:[UIImage imageNamed:@"guitar.jpg"]]]; +// [self.mapView addAnnotation:[MCCArtAnnotation artAnnotationWithTitle:@"Music Picture" +// coordinate:CLLocationCoordinate2DMake(36.1575, -86.777) +// andImage:[UIImage imageNamed:@"music.jpg"]]]; +// [self.mapView addAnnotation:[MCCArtAnnotation artAnnotationWithTitle:@"Trumpet Picture" +// coordinate:CLLocationCoordinate2DMake(36.1580, -86.777) +// andImage:[UIImage imageNamed:@"trumpet.jpg"]]]; + + // TODO - Look into fetching these in parallel with the tile imagery by + // modifying MBXMapKit.m. + // See: https://github.com/mapbox/mbxmapkit/issues/75#issuecomment-37945403 +// [[MCCClient sharedClient] fetchFloorPlan:@"full-test-1" +// withCompletionBlock:^(MCCNavData *navData) { +// self.navData = navData; +// +// // Fencepost +// MCCFloorPlanEdge *firstEdge = [self.navData.floorPlan.edges firstObject]; +// [self.mapView addAnnotation:[self pointAnnotationForEdge:firstEdge +// withLocation:firstEdge.startLocation]]; +// +// for (MCCFloorPlanEdge *edge in self.navData.floorPlan.edges) { +// [self.mapView addAnnotation:[self pointAnnotationForEdge:edge +// withLocation:edge.endLocation]]; +// } +// +// }]; + + self.routing = NO; + + // self.mapView.mapType = MKMapTypeHybrid + } - (void)didReceiveMemoryWarning @@ -107,6 +204,7 @@ - (void)setPolylineToFloorPlanLocation:(MCCFloorPlanLocation *)location andLocat // Save the incoming data self.endLocation = location; + [[MCCClient sharedClient] locationFromiBeacons:locationData forFloorPlan:floorPlanId withCompletionBlock:^(MCCFloorPlanLocation *floorPlanLocation) { @@ -121,7 +219,9 @@ -(void)setPolylineToFloorPlanLocation:(MCCFloorPlanLocation *)endLocation fromFl [self drawPolylineFromStartLocation:startLocation]; } -#pragma mark - MKMapViewDelegate + + +#pragma mark - Map View Delegate - (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id)overlay { MKOverlayRenderer *renderer = nil; @@ -144,6 +244,8 @@ - (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id 45) { + direction = @"Turn left"; + } else if (relativeAngle < -45) { + direction = @"Turn right"; + } else { + direction = @"Go straight"; + } + + return direction; +} + + +- (CLLocationCoordinate2D)coordinateFromEdge:(MCCFloorPlanEdge *)edge { + MCCFloorPlanImageLocation *location = [self.navData.mapping coordinatesOfLocation:edge.endLocation.locationId]; + + MCCFloorPlanImageLocation *translatedLocation = [MCCFloorPlanImageLocation floorPlanImageLocationWithX:location.x - self.topLeft.x + andY:location.y - self.topLeft.y]; + + // Turn the floorplan location into lat/long + return [self.floorPlanImage coordinateFromFloorPlanImageLocation:translatedLocation]; +} + +//- (MKPointAnnotation *)pointAnnotationForEdge:(MCCFloorPlanEdge *)edge withLocation:(MCCFloorPlanLocation *)location { +// MKPointAnnotation *pointAnnotation = [[MKPointAnnotation alloc] init]; +// // TODO - Don't hardcore this floor and top left +// pointAnnotation.coordinate = [self coordinateFromEdge:edge +// withFloorPlanImage:self.floorPlanImage +// andTopLeftImageLocation:self.topLeft]; +// pointAnnotation.title = location.locationId; +// +// return pointAnnotation; +//} + +- (MKPointAnnotation *)pointAnnotationForLocation:(MCCFloorPlanLocation *)location withTitle:(NSString *)title { + MKPointAnnotation *pointAnnotation = [[MKPointAnnotation alloc] init]; + + MCCFloorPlanImageLocation *imageLocation = [self.navData.mapping coordinatesOfLocation:location.locationId]; + + imageLocation.x -= self.topLeft.x; + imageLocation.y -= self.topLeft.y; + + pointAnnotation.coordinate = [self.floorPlanImage coordinateFromFloorPlanImageLocation:imageLocation]; + + pointAnnotation.title = title; + + [self.annotations addObject:pointAnnotation]; + + return pointAnnotation; +} + +#pragma mark - Map View Delegate + +- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation { + static NSString * const pointAnnotationIdentifier = @"PointAnnotation"; + static NSString * const artAnnotationIdentifier = @"ArtAnnotation"; + + MKAnnotationView *annotationView; + + if ([annotation isKindOfClass:[MKPointAnnotation class]]) { + annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:pointAnnotationIdentifier]; + + if (!annotationView) { + annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation + reuseIdentifier:pointAnnotationIdentifier]; + } + } else if ([annotation isKindOfClass:[MCCArtAnnotation class]]) { + MKPinAnnotationView *pinAnnotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:artAnnotationIdentifier]; + + if (!pinAnnotationView) { + pinAnnotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation + reuseIdentifier:artAnnotationIdentifier]; + } + + pinAnnotationView.pinColor = MKPinAnnotationColorPurple; + + UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 46.0, 46.0)]; + pinAnnotationView.leftCalloutAccessoryView = imageView; + + UIButton *detailDisclosureButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; + pinAnnotationView.rightCalloutAccessoryView = detailDisclosureButton; + + annotationView = pinAnnotationView; + } + + annotationView.annotation = annotation; + annotationView.canShowCallout = YES; + + return annotationView; +} +- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view { + // TODO - Eventually asyncronously fetch the image for the annotation view from the + //server. + if ([view.leftCalloutAccessoryView isKindOfClass:[UIImageView class]]) { + UIImageView *imageView = (UIImageView *)view.leftCalloutAccessoryView; + MCCArtAnnotation *artAnnotation = (MCCArtAnnotation *)view.annotation; + + imageView.image = artAnnotation.image; + } +} + +#pragma mark - IB Actions + +- (IBAction)endTapped:(UIBarButtonItem *)sender { + self.routing = NO; +} +// Unwind segue +- (IBAction)directionsDone:(UIStoryboardSegue *)segue {} @end diff --git a/Music City Center/MCCMapViewController.m b/Music City Center/MCCMapViewController.m index 1f2ec83..e5e1de6 100644 --- a/Music City Center/MCCMapViewController.m +++ b/Music City Center/MCCMapViewController.m @@ -206,6 +206,7 @@ - (void)didReceiveMemoryWarning #pragma mark - Table View Data Source + - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { NSInteger numberOfSections = 0; @@ -215,6 +216,7 @@ - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { } if ([self.roomSearchResults count] > 0) { ++numberOfSections; + } return numberOfSections; @@ -317,7 +319,7 @@ -(BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar { [self.searchBar setShowsCancelButton:YES animated:YES]; self.tabBarController.tabBar.hidden = YES; [self populateEventsAndRooms]; - + if (!self.searching) { [self updateBlur]; @@ -348,6 +350,7 @@ -(void)endSearch { self.blurView.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 0); self.blurView.layer.contentsRect = CGRectMake(0.0f, 0.0f, 1.0f, 0.0f); }]; + [self.searchBar resignFirstResponder]; self.searching = NO; } @@ -433,6 +436,9 @@ - (void)populateEventsAndRooms { }]; } + +#pragma mark - Helper Methods + // Find all matching strings - (void)findMatches:(NSString *)searchText { [self.eventSearchResults removeAllObjects]; @@ -457,6 +463,7 @@ - (void)findMatches:(NSString *)searchText { } } + - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString:@"PushMap"]) { if ([sender isKindOfClass:[MCCFloorPlanLocation class]]) { @@ -551,4 +558,23 @@ - (NSDictionary *)locationData { } +- (NSString *)titleStringForSegue:(UIStoryboardSegue *)segue { + NSString *segueIdentifier = segue.identifier; + NSString *title; + + if ([segueIdentifier isEqualToString:@"PushLevel4"]) { + title = @"Level 4"; + } else if ([segueIdentifier isEqualToString:@"PushLevel3"]) { + title = @"Level 3"; + } else if ([segueIdentifier isEqualToString:@"PushLevel2"]) { + title = @"Level 2"; + } else if ([segueIdentifier isEqualToString:@"PushLevel1M"]) { + title = @"Level 1M"; + } else { // PushLevel1 + title = @"Level 1"; + } + + return title; +} + @end diff --git a/Music City Center/MCCResponseSerializer.m b/Music City Center/MCCResponseSerializer.m index 20df4ef..ca5385c 100644 --- a/Music City Center/MCCResponseSerializer.m +++ b/Music City Center/MCCResponseSerializer.m @@ -69,10 +69,8 @@ - (id)responseObjectForResponse:(NSURLResponse *)response data:(NSData *)data er NSDictionary *innerMappingDictionary = responseObject[@"mapping"][@"mapping"]; for (NSString *locationID in innerMappingDictionary) { - MCCFloorPlanImageLocation *location = - [MCCFloorPlanImageLocation - floorPlanImageLocationWithX:[innerMappingDictionary[locationID][@"x"] integerValue] - andY:[innerMappingDictionary[locationID][@"y"] integerValue]]; + MCCFloorPlanImageLocation *location = [MCCFloorPlanImageLocation floorPlanImageLocationWithX:[innerMappingDictionary[locationID][@"x"] integerValue] + andY:[innerMappingDictionary[locationID][@"y"] integerValue]]; mappingDictionary[locationID] = location; } @@ -87,9 +85,8 @@ - (id)responseObjectForResponse:(NSURLResponse *)response data:(NSData *)data er NSMutableArray *locationArray = [NSMutableArray array]; for (NSDictionary *locationDictionary in responseObject[@"floorplan"][@"locations"]) { - MCCFloorPlanLocation *location = [MCCFloorPlanLocation - floorPlanLocationWithLocationId:locationDictionary[@"id"] - andType:locationDictionary[@"type"]]; + MCCFloorPlanLocation *location = [MCCFloorPlanLocation floorPlanLocationWithLocationId:locationDictionary[@"id"] + andType:locationDictionary[@"type"]]; [locationArray addObject:location]; } @@ -154,7 +151,8 @@ - (id)responseObjectForResponse:(NSURLResponse *)response data:(NSData *)data er } responseObject = [events copy]; - + } else if ([firstPathComponent isEqualToString:@"image"]) { + } return responseObject; diff --git a/Music City Center/guitar.jpg b/Music City Center/guitar.jpg new file mode 100644 index 0000000..efa84d5 Binary files /dev/null and b/Music City Center/guitar.jpg differ diff --git a/Music City Center/music.jpg b/Music City Center/music.jpg new file mode 100644 index 0000000..73c8566 Binary files /dev/null and b/Music City Center/music.jpg differ diff --git a/Music City Center/trumpet.jpg b/Music City Center/trumpet.jpg new file mode 100644 index 0000000..e4df449 Binary files /dev/null and b/Music City Center/trumpet.jpg differ diff --git a/Podfile.lock b/Podfile.lock index bfae272..072e730 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,24 +1,24 @@ PODS: - - AFNetworking (2.2.1): + - AFNetworking (2.2.3): - AFNetworking/NSURLConnection - AFNetworking/NSURLSession - AFNetworking/Reachability - AFNetworking/Security - AFNetworking/Serialization - AFNetworking/UIKit - - AFNetworking/NSURLConnection (2.2.1): + - AFNetworking/NSURLConnection (2.2.3): - AFNetworking/Reachability - AFNetworking/Security - AFNetworking/Serialization - - AFNetworking/NSURLSession (2.2.1): + - AFNetworking/NSURLSession (2.2.3): - AFNetworking/NSURLConnection - - AFNetworking/Reachability (2.2.1) - - AFNetworking/Security (2.2.1) - - AFNetworking/Serialization (2.2.1) - - AFNetworking/UIKit (2.2.1): + - AFNetworking/Reachability (2.2.3) + - AFNetworking/Security (2.2.3) + - AFNetworking/Serialization (2.2.3) + - AFNetworking/UIKit (2.2.3): - AFNetworking/NSURLConnection - AFNetworking/NSURLSession - - GPUImage (0.1.2) + - GPUImage (0.1.4) - MBXMapKit (0.2.1) DEPENDENCIES: @@ -27,8 +27,8 @@ DEPENDENCIES: - MBXMapKit SPEC CHECKSUMS: - AFNetworking: 0121f4b69be3fa58d1ab317866e036e12ac9651d - GPUImage: 007145faa0e27f1ddbcab93e07f026c9776e2fa2 + AFNetworking: ae513199cca79e9d7af2708ccabe2ed075550c42 + GPUImage: f9b32e12350792a630e596ffc7b050bea3662670 MBXMapKit: ddbf1945d8f640f6db3411a41ffcfe1b132497a5 COCOAPODS: 0.32.1 diff --git a/README.md b/README.md index 1b43b13..ea6b38a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,11 @@ -iOS -=== +# iOS [![Build Status](https://travis-ci.org/MusicCityCenter/iOS.png?branch=master)](https://travis-ci.org/MusicCityCenter/iOS) iOS App for Nashville's Music City Center + +## Installation + +1. Clone the repo to your local machine. +2. Run `$ pod install` (install [CocoaPods](cocoapods.org) first if you haven't already). +3. In *MBXMapKit.m*, comment out the line `[self updateMarkers]` in `setMapID:` (based on advice given [here](https://github.com/mapbox/mbxmapkit/issues/75#issuecomment-37945403)).