Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Thomas Nilsen
14,957 PointsNURLSession within a custom delegate method: Response is first (null)
I have a Location.m model, which I use to obtain latitude and longitude. When I have those, I call my delegate method which is implemented in my Foursquare.m model.
Location.h looks like this:
@class Location;
@protocol LocationDelegate <NSObject>
- (void)location:(Location *)loc didFinishFindingLocation:(CLLocation *)location;
@end
@interface Location : NSObject <CLLocationManagerDelegate>
@property (nonatomic, weak) id <LocationDelegate> delegate;
- (void)startLocationManager;
@end
Location.m:
@implementation Location
{
CLLocationManager *_locationManager;
BOOL _locationIsUpdated;
}
- (void)startLocationManager
{
NSLog(@"In startLocationManager");
_locationManager = [[CLLocationManager alloc] init];
_locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
_locationManager.delegate = self;
_locationIsUpdated = NO;
[_locationManager startUpdatingLocation];
}
#pragma mark - LocationManager Delegates
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
if (locations && _locationIsUpdated == NO) {
self.location = [locations lastObject];
NSLog(@"%@", _location);
_locationIsUpdated = YES;
[self.delegate location:self didFinishFindingLocation:self.location];
}
}
@end
When the delegate method is called from the Foursquare model, and I NSLog out the response in an array (called self.dataResponse). It always outputs (null) first, then all the JSON. Why does that happen? If I NSLog out dataDictionary (see code below) directly, the JSON output shows a error-code:400 and nothing is printed. Couple of milliseconds after everything is printed and seems to be working fine...
Here is a picture: When I log the dataDictionary => http://imgur.com/Rzyw86Q
Here is the delegate method implemented in Foursquare.m:
- (void)location:(Location *)loc didFinishFindingLocation:(CLLocation *)location
{
loc.delegate = self;
self.resultFromResponse = [[NSMutableArray alloc] init];
NSString *search = [NSString stringWithFormat:@"https://api.foursquare.com/v2/venues/search?ll=%f,%f&radius=2000&categoryId=4d4b7105d754a06374d81259&client_id=%@&client_secret=%@&v=%@", location.coordinate.latitude, location.coordinate.longitude, kFourdquareAPIKey, fFoursquareSecret, [Foursquare getCurrentDate]];
NSURL *url = [NSURL URLWithString:search];
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSDictionary *dataDictionary = (NSDictionary *)[NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if (!error) {
self.dataResponse = dataDictionary[@"response"][@"venues"];
NSLog(@"%@", self.dataResponse);
for (NSDictionary *venue in self.dataResponse) {
FSDataFromJSON *data = [[FSDataFromJSON alloc] init];
data.name = venue[@"name"];
data.phone = venue[@"phone"];
data.location = venue[@"location"];
[self.resultFromResponse addObject:data];
}
//[[NSNotificationCenter defaultCenter] postNotificationName:@"JSONRequestFinishedLoading" object:nil];
} else {
NSLog(@"%@", error.description);
}
}];
[task resume];
}
At the very end, these models is started in my MainViewController:
_location = [[Location alloc] init];
[_location startLocationManager];
_foursquare = [[Foursquare alloc] init];
[_foursquare location:_location didFinishFindingLocation:_location.location];
I've been struggling with this for several days now. I'd really appreciate it if you took a look Amit Bijlani
1 Answer
Thomas Nilsen
14,957 PointsOkay - I kinda solved it, but I don't know why it would be needed. I wrapped the nsurl-stuff inside an "if(location){}". I thought since I was using delegates that function wouldn't be called before a location was found anyway? I'd still love some insight on this?