diff --git a/TalkinToTheNet/TalkinToTheNet.xcodeproj/project.pbxproj b/TalkinToTheNet/TalkinToTheNet.xcodeproj/project.pbxproj index ee35a70..f400af1 100644 --- a/TalkinToTheNet/TalkinToTheNet.xcodeproj/project.pbxproj +++ b/TalkinToTheNet/TalkinToTheNet.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + 4515B6571BB51038002461FA /* APIManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 4515B6561BB51038002461FA /* APIManager.m */; settings = {ASSET_TAGS = (); }; }; + 4515B65A1BB60AFB002461FA /* Place.m in Sources */ = {isa = PBXBuildFile; fileRef = 4515B6591BB60AFB002461FA /* Place.m */; settings = {ASSET_TAGS = (); }; }; + 4515B65D1BB61702002461FA /* DetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4515B65C1BB61702002461FA /* DetailViewController.m */; settings = {ASSET_TAGS = (); }; }; 8D7DCD4B1BAF859400A92AD2 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8D7DCD4A1BAF859400A92AD2 /* main.m */; }; 8D7DCD4E1BAF859400A92AD2 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8D7DCD4D1BAF859400A92AD2 /* AppDelegate.m */; }; 8D7DCD511BAF859400A92AD2 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8D7DCD501BAF859400A92AD2 /* ViewController.m */; }; @@ -16,6 +19,12 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 4515B6551BB51038002461FA /* APIManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIManager.h; sourceTree = ""; }; + 4515B6561BB51038002461FA /* APIManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = APIManager.m; sourceTree = ""; }; + 4515B6581BB60AFB002461FA /* Place.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Place.h; sourceTree = ""; }; + 4515B6591BB60AFB002461FA /* Place.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Place.m; sourceTree = ""; }; + 4515B65B1BB61702002461FA /* DetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DetailViewController.h; sourceTree = ""; }; + 4515B65C1BB61702002461FA /* DetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DetailViewController.m; sourceTree = ""; }; 8D7DCD461BAF859400A92AD2 /* TalkinToTheNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TalkinToTheNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 8D7DCD4A1BAF859400A92AD2 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 8D7DCD4C1BAF859400A92AD2 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; @@ -60,8 +69,14 @@ children = ( 8D7DCD4C1BAF859400A92AD2 /* AppDelegate.h */, 8D7DCD4D1BAF859400A92AD2 /* AppDelegate.m */, + 4515B6551BB51038002461FA /* APIManager.h */, + 4515B6561BB51038002461FA /* APIManager.m */, + 4515B6581BB60AFB002461FA /* Place.h */, + 4515B6591BB60AFB002461FA /* Place.m */, 8D7DCD4F1BAF859400A92AD2 /* ViewController.h */, 8D7DCD501BAF859400A92AD2 /* ViewController.m */, + 4515B65B1BB61702002461FA /* DetailViewController.h */, + 4515B65C1BB61702002461FA /* DetailViewController.m */, 8D7DCD521BAF859400A92AD2 /* Main.storyboard */, 8D7DCD551BAF859400A92AD2 /* Assets.xcassets */, 8D7DCD571BAF859400A92AD2 /* LaunchScreen.storyboard */, @@ -149,9 +164,12 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 4515B65A1BB60AFB002461FA /* Place.m in Sources */, + 4515B6571BB51038002461FA /* APIManager.m in Sources */, 8D7DCD511BAF859400A92AD2 /* ViewController.m in Sources */, 8D7DCD4E1BAF859400A92AD2 /* AppDelegate.m in Sources */, 8D7DCD4B1BAF859400A92AD2 /* main.m in Sources */, + 4515B65D1BB61702002461FA /* DetailViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -300,6 +318,7 @@ 8D7DCD5F1BAF859400A92AD2 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/TalkinToTheNet/TalkinToTheNet/APIManager.h b/TalkinToTheNet/TalkinToTheNet/APIManager.h new file mode 100644 index 0000000..a2d8f59 --- /dev/null +++ b/TalkinToTheNet/TalkinToTheNet/APIManager.h @@ -0,0 +1,17 @@ +// +// APIManager.h +// LearnAPI +// +// Created by Chris David on 9/20/15. +// Copyright © 2015 Chris David. All rights reserved. +// + +#import + +@interface APIManager : NSObject + ++ (void)GETRequestWithURL:(NSURL *)URL + completionHandler:(void(^)(NSData *, NSURLResponse *, NSError *)) +completionHandler; + +@end diff --git a/TalkinToTheNet/TalkinToTheNet/APIManager.m b/TalkinToTheNet/TalkinToTheNet/APIManager.m new file mode 100644 index 0000000..efc79ba --- /dev/null +++ b/TalkinToTheNet/TalkinToTheNet/APIManager.m @@ -0,0 +1,31 @@ +// +// APIManager.m +// LearnAPI +// +// Created by Chris David on 9/20/15. +// Copyright © 2015 Chris David. All rights reserved. +// + +#import "APIManager.h" + +@implementation APIManager + ++ (void)GETRequestWithURL:(NSURL *)URL +completionHandler:(void(^)(NSData *, NSURLResponse *, NSError *)) +completionHandler { + + NSURLSession *session = [NSURLSession sharedSession]; + + //API Converted to task + NSURLSessionDataTask *task = [session dataTaskWithURL:URL completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { + + dispatch_async(dispatch_get_main_queue(), ^{ + completionHandler(data, response, error); + }); + + }]; + + [task resume]; + +} +@end diff --git a/TalkinToTheNet/TalkinToTheNet/Base.lproj/Main.storyboard b/TalkinToTheNet/TalkinToTheNet/Base.lproj/Main.storyboard index f56d2f3..7eb83d1 100644 --- a/TalkinToTheNet/TalkinToTheNet/Base.lproj/Main.storyboard +++ b/TalkinToTheNet/TalkinToTheNet/Base.lproj/Main.storyboard @@ -1,13 +1,117 @@ - + - + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -15,11 +119,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TalkinToTheNet/TalkinToTheNet/DetailViewController.h b/TalkinToTheNet/TalkinToTheNet/DetailViewController.h new file mode 100644 index 0000000..a4e1703 --- /dev/null +++ b/TalkinToTheNet/TalkinToTheNet/DetailViewController.h @@ -0,0 +1,16 @@ +// +// DetailViewController.h +// TalkinToTheNet +// +// Created by Chris David on 9/25/15. +// Copyright © 2015 Mike Kavouras. All rights reserved. +// + +#import +#import "Place.h" +#import "APIManager.h" +@interface DetailViewController : UIViewController + +@property (nonatomic) Place *fourSquareObject; + +@end diff --git a/TalkinToTheNet/TalkinToTheNet/DetailViewController.m b/TalkinToTheNet/TalkinToTheNet/DetailViewController.m new file mode 100644 index 0000000..1e586b0 --- /dev/null +++ b/TalkinToTheNet/TalkinToTheNet/DetailViewController.m @@ -0,0 +1,84 @@ +// +// DetailViewController.m +// TalkinToTheNet +// +// Created by Chris David on 9/25/15. +// Copyright © 2015 Mike Kavouras. All rights reserved. +// + +#import "DetailViewController.h" + + +@interface DetailViewController () +@property (weak, nonatomic) IBOutlet UILabel *name; +@property (weak, nonatomic) IBOutlet UILabel *address; +@property (weak, nonatomic) IBOutlet UILabel *checkIns; + +@property (weak, nonatomic) IBOutlet UITableView *tableView; +@property (nonatomic) NSMutableArray *stations; + +@end + +@implementation DetailViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + [self.tableView setDelegate:self]; + [self.tableView setDataSource:self]; + self.name.text = self.fourSquareObject.name; + self.address.text = self.fourSquareObject.address; + self.checkIns.text = self.fourSquareObject.checkIns; + + [self GoogleAPIRequestBlock:^{ + [self.tableView reloadData]; + }]; +} +- (void) GoogleAPIRequestBlock:(void(^)())block{ + + + NSString *urlString = [NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=%@&rankby=distance&types=subway_station|transit_station&key=AIzaSyAWnqNcCoTk_j7oZabHJkVZW0ULVFg5uZ0", self.fourSquareObject.location]; + + NSString *encodedString = [urlString stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet URLQueryAllowedCharacterSet]]; + NSURL *url = [NSURL URLWithString:encodedString]; + [APIManager GETRequestWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + if (data != nil) { + NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; + self.stations = [[NSMutableArray alloc]init]; + + NSArray *results = [json objectForKey:@"results"]; + + for (NSDictionary *result in results) { + + [self.stations addObject:[result objectForKey:@"name"]]; + } + block(); + } + + }]; + +} +# pragma mark -tableView delegate methods + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + return self.stations.count; +} + +-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"PlaceCellIdentifier" forIndexPath:indexPath]; + + NSString * station = [self.stations objectAtIndex:indexPath.row]; + + + + cell.textLabel.text = station; + + return cell; +} + + + +@end diff --git a/TalkinToTheNet/TalkinToTheNet/Place.h b/TalkinToTheNet/TalkinToTheNet/Place.h new file mode 100644 index 0000000..14f041d --- /dev/null +++ b/TalkinToTheNet/TalkinToTheNet/Place.h @@ -0,0 +1,16 @@ +// +// Place.h +// TalkinToTheNet +// +// Created by Chris David on 9/25/15. +// Copyright © 2015 Mike Kavouras. All rights reserved. +// + +#import + +@interface Place : NSObject +@property (nonatomic) NSString * name; +@property (nonatomic) NSString * address; +@property (nonatomic) NSString * location; +@property (nonatomic) NSString * checkIns; +@end diff --git a/TalkinToTheNet/TalkinToTheNet/Place.m b/TalkinToTheNet/TalkinToTheNet/Place.m new file mode 100644 index 0000000..33e2df3 --- /dev/null +++ b/TalkinToTheNet/TalkinToTheNet/Place.m @@ -0,0 +1,13 @@ +// +// Place.m +// TalkinToTheNet +// +// Created by Chris David on 9/25/15. +// Copyright © 2015 Mike Kavouras. All rights reserved. +// + +#import "Place.h" + +@implementation Place + +@end diff --git a/TalkinToTheNet/TalkinToTheNet/ViewController.m b/TalkinToTheNet/TalkinToTheNet/ViewController.m index cbefa29..418d75a 100644 --- a/TalkinToTheNet/TalkinToTheNet/ViewController.m +++ b/TalkinToTheNet/TalkinToTheNet/ViewController.m @@ -7,21 +7,110 @@ // #import "ViewController.h" +#import "Place.h" +#import "APIManager.h" +#import "DetailViewController.h" -@interface ViewController () +@interface ViewController () +@property (weak, nonatomic) IBOutlet UITextField *searchTextField; +@property (weak, nonatomic) IBOutlet UITextField *searchLocationTextField; +@property (weak, nonatomic) IBOutlet UITableView *tableView; +@property (nonatomic) NSMutableArray *places; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; - // Do any additional setup after loading the view, typically from a nib. + [self.tableView setDataSource:self]; + [self.tableView setDelegate:self]; + [self.searchLocationTextField setDelegate:self]; } -- (void)didReceiveMemoryWarning { - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. + +- (void) makeFourSquareAPIRequest:(NSString*) searchTerm andLocation:(NSString*) location callbackBlock:(void(^)())block{ + + + NSString *urlString = [NSString stringWithFormat:@"https://api.foursquare.com/v2/venues/search?near=%@&query=%@&client_id=V4EZD2DVUA5S4EW4UWUFJQRCRO3L0QEBRZ2MNOA2IAVF2VXY&client_secret=J1KFSATHO1PDRRLDSQCEBSZ0ULLBVK20YC1WYIN3T53LXXPX&v=20150924", location, searchTerm]; + + NSString *encodedString = [urlString stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet URLQueryAllowedCharacterSet]]; + NSURL *url = [NSURL URLWithString:encodedString]; + + [APIManager GETRequestWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + if (data != nil) { + NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; + self.places = [[NSMutableArray alloc]init]; + + NSArray *results = [[json objectForKey:@"response"] objectForKey:@"venues"]; + + + for (NSDictionary *result in results) { + Place *object = [[Place alloc]init]; + object.name = [result objectForKey:@"name"]; + NSString *address = [[result objectForKey:@"location"] objectForKey:@"address"]; + NSString *city = [[result objectForKey:@"location"] objectForKey:@"city"]; + NSString *state = [[result objectForKey:@"location"] objectForKey:@"state"]; + NSString *postalCode = [[result objectForKey:@"location"] objectForKey:@"postalCode"]; + + object.address = [NSString stringWithFormat:@"%@ %@, %@ %@", address, city, state, postalCode]; + NSString *latitude = [[[result objectForKey:@"location"] objectForKey:@"lat"] stringValue]; + NSString *longitude = [[[result objectForKey:@"location"] objectForKey:@"lng"] stringValue]; + object.checkIns = [[[result objectForKey:@"stats"] objectForKey:@"checkinsCount"] stringValue]; + + object.location = [latitude stringByAppendingString:[NSString stringWithFormat:@",%@", longitude]]; + + [self.places addObject:object]; + } + block(); + } + + }]; + +} + +# pragma mark -tableView delegate methods + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + + return self.places.count; + +} + +-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellIdentifier" forIndexPath:indexPath]; + Place *result = [self.places objectAtIndex:indexPath.row]; + + + cell.textLabel.text = result.name; + cell.detailTextLabel.text = result.address; + + + return cell; +} +# pragma mark - text field delegate methods +- (BOOL)textFieldShouldReturn:(UITextField *)textField{ + [self.view endEditing:YES]; + + NSString * query = self.searchTextField.text; + + [self makeFourSquareAPIRequest:query andLocation:textField.text callbackBlock:^{ + [self.tableView reloadData]; + }]; + return YES; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + + DetailViewController *viewController = [self.navigationController.storyboard instantiateViewControllerWithIdentifier:@"DetailIdentifier"]; + viewController.fourSquareObject = [self.places objectAtIndex:indexPath.row]; + + [self.navigationController pushViewController:viewController animated:YES]; + } @end