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 trialSteve Hunter
57,712 PointsCLLocationManager doesn't store location
Hi all,
I've followed the video and been through it again to make sure I didn't miss anything but I can't get entry.location
to equal anything other than null
.
I have inserted some NSLog
lines to see which bits of code are being reached, and which aren't.
This shows me that in viewDidLoad
of the EntryViewController.m
the line,
[self.locationManager startUpdatingLocation];
does get reached. The callback never happens as the NSLog
I placed inside -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:
never appears in the log so the GPS simulation doesn't call that code.
In the EntryCell.m
code, the self.locationLabel.text = @"No location";
definitely gets called and at that point, entry.location
is null
.
Any pointers would be great!
Steve.
Erion Vlada
13,496 PointsIts iOS8, not your code. Instead of me trying to act smart by copying and pasting, here is a link with full instructions. Hope it helps. (http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/)
2 Answers
ehud shahak
3,101 PointsThis is the reason for your problem: In iOS 8, this code doesn’t just fail, it fails silently. You will get no error or warning, you won’t ever get a location update and you won’t understand why. Your app will never even ask for permission to use location
the solution: In iOS 8 you need to do two extra things to get location working: Add a key to your Info.plist and request authorization from the location manager asking it to start. There are two Info.plist keys for the new location authorization. One or both of these keys is required. If neither of the keys are there, you can call startUpdatingLocation but the location manager won’t actually start. It won’t send a failure message to the delegate either (since it never started, it can’t fail). It will also fail if you add one or both of the keys but forget to explicitly request authorization.
So the first thing you need to do is to add one or both of the following keys to your Info.plist file:
NSLocationWhenInUseUsageDescription NSLocationAlwaysUsageDescription Both of these keys take a string which is a description of why you need location services. You can enter a string like “Location is required to find out where you are” which, as in iOS 7, can be localized in the InfoPlist.strings file.
Next you need to request authorization for the corresponding location method, WhenInUse or Background. Use one of these calls:
[self.locationManager requestWhenInUseAuthorization]
[self.locationManager requestAlwaysAuthorization]
Here’s a full implementation of a view controller with a location manager asking for WhenInUse (foreground) authorization. This is a basic example which doesn’t take into account whether the user has already denied or restricted location.
#import "ViewController.h"
@import CoreLocation;
@interface ViewController () <CLLocationManagerDelegate>
@property (strong, nonatomic) CLLocationManager *locationManager;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// ** Don't forget to add NSLocationWhenInUseUsageDescription in MyApp-Info.plist and give it a string
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
// Check for iOS 8. Without this guard the code will crash with "unknown selector" on iOS 7.
if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
}
[self.locationManager startUpdatingLocation];
}
// Location Manager Delegate Methods
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(@"%@", [locations lastObject]);
}
@end
Szymon Kadłuczka
8,762 PointsVery helpful, thanks!
Madhav Sharma
4,081 PointsGenius!
Dee Greene
8,508 Pointsgreat! this needs to be added to the teachers notes and video! Gabe Nadel
Donny Gumelar France
Courses Plus Student 1,148 Pointsi got an error when put this code
if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
}
[self.locationManager startUpdatingLocation];
is that wrong with my code ? or i misplace this code
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
&
[self.locationManager requestWhenInUseAuthorization]
[self.locationManager requestAlwaysAuthorization]
where tu put this code exactly ?
thx for helping
Eric M
2,242 PointsSame same. never calls the delegate. Please add notes to the video so folks don't have to dig into answers for this!
In iOS 8, this code doesn’t just fail, it fails silently. You will get no error or warning, you won’t ever get a location update and you won’t understand why. Your app will never even ask for permission to use location. I’m experienced with Core Location and it took me 30 minutes to figure out the new behavior. Baby devs are going to be even more frustrated by this change.
http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/
Steve Hunter
57,712 PointsSteve Hunter
57,712 PointsCode execution never reaches
didUpdateLocations
and certainly doesn't get inside thecompletionHandler^
within that.Very strange!