iPhone locationManager:didFailWithError problem when GPS disabled - iphone

So, I've followed other related threads, but for some reason I'm still having this error and I'm about ready to tear my hair out. I have implemented locationManager:didFailWithError to check and see if a user selects 'Don't Allow' to use the current location.
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(#"IN ERROR");
if ([error code] == kCLErrorDenied){
[manager stopUpdatingLocation];
}
}
However, the following error always appears when the user selects 'Don't Allow'...it's strange, especially the order that the text 'IN ERROR' appears.
ERROR,Time,293420691.000,Function,"void
CLClientHandleDaemonDataRegistration(__CLClient*,
const
CLDaemonCommToClientRegistration*,
const __CFDictionary*)",server did not
accept client registration 1
2010-04-19 21:44:51.000
testApp[1414:207] IN ERROR
So, it's outputting this error even before it has a chance to get into the didFailWithError function. Does anyone have any ideas of what might be happening? The rest of the locationManager code is as follows:
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
locationManager.distanceFilter = 2;
[locationManager startUpdatingLocation];

Looks like just an informational message from Core Location. It's not crashing your app, the user will not see it and it does still call didFailWithError with the correct error code.
In my tests, the message appears on the iPhone simulator and device (3.1.3) and the iPad simulator but not the iPad device (3.2).

If you're using MapKit as well, this is an error in MapKit. MapKit is registering with Core Location, and then not properly handling the error reported when the user rejects the location update or it fails. It should pass this error on via a delegate method (as it does for geocoding errors), but doesn't.
Unfortunately I can't think of any way to intercept the message from core location, as MapKit maintains an instance of CLLocationManager which it uses to get the location, and that's the one which is reporting the error to its delegate.

Related

monitoredRegions empty even though startMonitoringForRegion:desiredAccuracy: is called

I am developing a iPhone app running on iOS5, and am unable to set up geofences when I call the startMonitoringForRegion:desiredAccuracy: method on click of a button.
It works fine in the simulator when I print out the regions in monitoredRegions, but when running on an actual iPhone 4, the monitoredRegions is always empty. Expectedly, the didEnterRegion: and didExitRegion: methods are not called as well.
Another puzzling fact is that on BOTH the simulator and the iPhone 4 device, the CLLocationManagerDelegate method didStartMonitoringForRegion: is never called as well.
Would appreciate some help here, thank you!
EDIT:
this is method that I call on click of a button:
-(void) queueGeofence: (CLLocationCoordinate2D)selectedBranch userCoordinate:(CLLocationCoordinate2D)userCoordinate radius: (CLLocationDegrees)radius {
geofence = [[CLRegion alloc] initCircularRegionWithCenter:selectedBranch radius:radius identifier:#"geofence"];
CLLocationAccuracy acc = kCLLocationAccuracyNearestTenMeters;
[locationManager startMonitoringForRegion:geofence desiredAccuracy:acc];
[CLLocationManager regionMonitoringEnabled];
NSLog([CLLocationManager regionMonitoringEnabled] ? #"regionMonitoringEnabled:Yes" : #"regionMonitoringEnabled:No");
NSLog([CLLocationManager regionMonitoringAvailable] ? #"regionMonitoringAvailable:Yes" : #"regionMonitoringAvailable:No");
NSLog(#"LOCATIONMANAGER monitored regions: %#", [locationManager monitoredRegions]});
}
Region monitoring is both enabled and available, but monitoredRegions is still giving me back nothing.
If you look in CLLocationManager.h, the comments in the header for startMonitoringForRegion:desiredAccuracy: state that
If a region with the same identifier is already being monitored for this application, it
will be removed from monitoring. This is done asynchronously and may not be immediately reflected in monitoredRegions.
Therefore, you shouldn't necessarily expect that [locationManager monitoredRegions] would include your newly added region since it is added asynchronously.
Are you implementing the delegate method for locationManager:monitoringDidFailForRegion:withError:? Maybe that's getting called instead of locationManager:didStartMonitoringForRegion:. Also note that a region with the same identifier as an existing region will get removed, so you might be running into some unexpected problems because you're reusing "geofence" as your identifier.
First of all, you should be sure, that your app has a permission to use LocationManager. Check it when you alloc your manager.
[CLLocationManager authorizationStatus];
I had the same trouble when start app and decline a permission. And after deleting and rebuilding app. I had a flag, that user didn't accept it. Turn it on.
If you are just going by your NSLog, it probably isn't going to work. [locationManager monitoredRegions] returns an NSSet of CLRegions. They won't display to your log that way. Try this:
NSSet *setOfRegions = [locationManager monitoredRegions];
for (CLRegion *region in setOfRegions) {
NSLog (#"region info: %#", region);
}

is iphone Simulator capable of showing heading and latitude , longitude?

I am using iphone simulator 4.2 and try to display or NSLog Heading and other Location services attributes e.g. Latitude, Longitude, altitude, horizontalAccuracy, VerticalAccuracy, speed. but its not showing the correct parameters and Incase of Heading its actually not firing the event.
as its execute CLLocation code
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
[self.delegate locationUpdate:newLocation];
}
and not executing CLHeading code
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
[self.delegate headingUpdate:newHeading];
}
and when I put breakpoint on these both codes it never touch CLHeading code. I am updating location and heading in init.
- (id) init{
if (self!=nil) {
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.distanceFilter = kCLDistanceFilterNone;
[self.locationManager startUpdatingLocation];
[self.locationManager startUpdatingHeading];
}
return self;
}
The problem is that I do not know that is due to simulator or there is any problem in code?
please help.
CLLocationManager needs additional hardware and hence wont work on simulator. However you can test that using the method described in this other SO question.
From the documentation:
Some location services require the presence of specific hardware on the given device. For example, heading information is available only for devices that contain a hardware compass. This class defines several methods that you can use to determine which services are currently available.
This answer can be updated for anyone using Xcode 4.2. It is still in beta status, but if you are a paid developer you will have access to it. Also, if you are a paid developer, there are some good videos from WWDC 2011 that explain how to use the simulator for location simulation.
WWDC 2011
See What's New in Core Location and Testing Your Location-Aware App Without Leaving Your Chair
**Note: Please note again that only paid developers have access to these videos
It looks like the behaviour is by default
It fires Location but not heading.
I have not tested my application in actual hard ware to confirm my though...
Anthony Desa

Why is my CLLocationmanager delegate not getting called?

I'm not getting any location callbacks on either sim or device. I've got this code being called:
- (void)startLocationCallbacks: (NSObject*) ignore
{
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
locationManager.distanceFilter = MINIMUM_METERS;
[locationManager startUpdatingLocation];
NSLog(#"[DEBUG] [locationManager startUpdatingLocation] (%#, %#)", locationManager, locationManager.delegate);
}
and log statements at the top of both
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
and
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
but neither log statement ever gets called. Location Notifications are enabled for my app (as shown in Settings, plus I said "allow.")
What are some possible reasons that I'm not getting location updates?
Config/other info:
I have allocated locationManager, and saved it in a retain property.
I have called startUpdatingLocation
I'm using 4.1 SDK
Problem is on both Sim & iPod-touch (2nd Gen) & iPhone-3, all running 4.1
Location notifications are allowed in my app (both as indicated in Settings and because I clicked "allow" in the alert.)
I've used CLLocationManager successfully before (in many shipping apps!) This is a real hair-puller for me.
Thanks!
Whew! Ok, I found it.
It turns out that one of the ways to make a CLLocationManager not fire off location callbacks is to do all the set-up in not-the-main-thread. When I moved my setup routine to a performSelectorOnMainThread, all worked exactly as expected.
What a nightmare!
Hope this answer helps others...
Edit/clarification:
Originally, I had something like this:
- (BOOL) appDidFinishLaunchingWithOptions: (NSDictionary*) options
{
// ...[app setup, snip]
[NSThread detachNewThreadSelector: #selector(postLaunchSetupThread) toTarget: self withObject: nil];
}
- (void)postLaunchSetupThread
{
NSAutoreleasePool *pool = [NSAutoreleasePool new];
// ...[other setup, snip]
[self setupLocationManager];
[pool release];
}
- (void)setupLocationManager
{
self.myLocationManager = [[[CLLocationManager alloc] init] autorelease];
[myLocationManager startLocationUpdates];
}
But calling setupLocationManager in a thread prevented the callbacks. So my fix was to move the line
[self setupLocationManager];
out of the thread and back into appDidFinishLaunchingWithOptions
Actually you can run it from another thread as well.
From Apple documentation:
Configuration of your location manager object must always occur on a
thread with an active run loop, such as your application’s main
thread.
Just make sure your run loop is running on that thread, and the CLLocationManager events are dispatched.
More about run loop:
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html
For iOS 8
1) I placed these lines right after I init'd the location manager.
if([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}
2) I added NSLocationAlwaysUsageDescription to the plist and set it to a string and added a message.
3) In my target, I clicked on Capabilities tab, and then turned on Background Modes and checked "Location Updates" and "Uses Bluetooth LE accessories"
This worked for me
// check out this
//...CLLocationManager does n't call delegate method properly
//...after lot of R&D I'm using a watchdog method it calls "
https://stackoverflow.com/questions/7156920/didupdatetolocation-doesnt-gets-called-immediately/14605889#14605889
In my case it was because of my device was unable to determine location - while staying indoors GPS signal was unavailable and wi-fi was also disconnected so location manager just wasn't able to receive any location data and delegate was never called.
Once I've connected wi-fi it worked (I guess moving outdoors should also do the trick in that case, but sometimes it is not very convenient way :) )

Application crashes when asking if user wants to use Location Services

I have an iPhone app that is using CoreLocation.
Upon first installing the app, the iPhone system message is displayed asking whether or not the user wants to allow location services, if they click yes, my app suddenly displays the first screen of my app (I'm using a navigation controller), and crashes. This is what I see in the log -
warning: UUID mismatch detected with the loaded library - on disk is:
/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk/System/Library/PrivateFrameworks/CoreTelephony.framework/CoreTelephony
=uuid-mismatch-with-loaded-file,file="/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk/System/Library/PrivateFrameworks/CoreTelephony.framework/CoreTelephony"
Program received signal: “EXC_BAD_ACCESS”.
And the stack trace looks like this
My code isn't too far off from the LocateMe sample (which works on my device). I have this:
CLLocationManager *clLocationManager = [[CLLocationManager alloc] init];
clLocationManager.delegate = self;
if (clLocationManager.locationServicesEnabled) {
[clLocationManager startUpdatingLocation];
} else {
self.searchBar.placeholder = #"Enter location";
}
Any idea on waht I'm doing wrong?
does your navigation controller support CLLocationManagerDelegate? it looks like it's crashing trying to send you an event.
what does your locationManager:didUpdateToLocation:fromLocation: function look like?
It looks like this is a byproduct of this question
To solve the problem, I wound up following this approach
Basically, in my ViewController's dealloc method -
- (void)dealloc {
locationManager.delegate = nil;
[locationManager release];
}

Is there a callback to use to tell when the user's location is available

I'm after a callback or protocol that will notify me when the user's location is available. So that when a user's location is found I can zoom into where they are. What can I use to do this?
I was thinking there waas something in CoreLocation that could do it, but I can't find how to do it.
[Update]
I've implemented <CLLocationManagerDelegate> with locationManager:didUpdateToLocation:fromLocation: and created an CLLocationManager instance.
locationManager = [[[CLLocationManager alloc] init] autorelease];
locationManager.delegate = self;
[locationManager startUpdatingLocation];
but I'm still not getting any location updates. Also if I use didUpdateLocation: then it will re-zoom to the user each update. Is there a better way than having a check to see if it's the first update?
[Update 2]
adding self. to the locationManager got it going and I checked to see if fromLocation: is nil to tell if it was the first update.
Look into the CLLocationManagerDelegate protocol, specifically -locationManager:didUpdateToLocation:fromLocation:. You can get the accuracy of the location reading from the newLocation parameter's horizontalAccuracy property.