CLLocation Manager not updated when App is in Guided Access mode - ios

I kept Guided Access for iPad app. When the app is launched it asks for user's current location using CLLocationManager.This is working under Normal mode and updates user current location. But under Guided Access, popup ("Allow to access your location") is not shown and authorizationStatus is always kCLAuthorizationStatusNotDetermined and doesn't update current location of user . Couldn't understand what could be the problem.Searched a lot but couldn't find it.
ViewController.m :
- (void)viewDidAppear:(BOOL)animated
{
[appDelegate startLocation];
[self performSelector:#selector(CheckLocationManger) withObject:nil afterDelay:0.1];
}
-(void)CheckLocationManger
{
AppAppDelegate *appDelegate=(AppAppDelegate*)[[UIApplication sharedApplication]delegate];
if(![CLLocationManager locationServicesEnabled])
{
UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:#"Whoops we can’t find you!" message:#"Location services are disabled" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
if(activityIndictr)
[activityIndictr stopAnimating];
[alert1 show];
return;
}
if([CLLocationManager locationServicesEnabled])
{
if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusDenied)
{
UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:#"Whoops we can’t find you!"message:#"Location services are disabled. You can fix this by going to Settings > Privacy > Location" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
if(activityIndictr)
[activityIndictr stopAnimating];
[alert1 show];
return;
}
if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusNotDetermined) //This is called
{
[self performSelector:#selector(CheckLocationManger) withObject:self afterDelay:0.1];
return;
}
}
if(![self connected])
{
UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:#"Network Error" message:#"Please verify that you have internet connectivity" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
if(activityIndictr)
[activityIndictr stopAnimating];
[alert1 show];
[alert1 release];
return;
}
else {
//continue further process
}
}
AppDelegate.m
- (void)startLocation
{
self.locationManager = [[[CLLocationManager alloc] init]autorelease];
self.locationManager.pausesLocationUpdatesAutomatically=NO;
[self.locationManager setDelegate:self];
if([[[UIDevice currentDevice ]systemVersion] floatValue]>=8.0)
{
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization]; //is executed but popup never displays
}
}
[self.locationManager startUpdatingLocation];
}
Any suggestions would be helpful.Thank you !

At very first set NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription in your .plist.
Add CoreLocation.framework and import in your class.h file -> #import <CoreLocation/CoreLocation.h> then set CLLocationManagerDelegate to your class.
Declare #property (strong, nonatomic) CLLocationManager *locationManager;
Init locationManager and set default value to it.
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.pausesLocationUpdatesAutomatically = NO;
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyBestForNavigation];
[self.locationManager setDistanceFilter:200.0f];
if ([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) // Or if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])
[self.locationManager requestAlwaysAuthorization]; // Or [self.locationManager requestWhenInUseAuthorization];
[self.locationManager startUpdatingLocation];
Implement CLLocationMAnager delegate method
#pragma mark - Location Delegate
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(#"updated coordinate are %#", [locations lastObject]);
CLLocation *currentLocation = [locations lastObject];
// Your code.....
}

Related

Check when user returns from Settings app iOS

I require location of the user in my application if in case the user has device location services disabled I am checking like this.
if([CLLocationManager locationServicesEnabled])
{
if([locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])
{
[locationManager requestWhenInUseAuthorization];
}
}
else if(![CLLocationManager locationServicesEnabled])
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Location Services are disabled please enable location services to enjoy nearby experience" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Settings", nil];
alert.tag = 103;
[alert show];
}
In my alert view I am directing the user to location settings like this
else if(alertView.tag == 103)
{
if(buttonIndex == 1)
{
NSURL*url=[NSURL URLWithString:#"prefs:root=LOCATION_SERVICES"];
[[UIApplication sharedApplication] openURL:url];
}
}
After the user comes back from settings how to get location again
You can manage your stuff in applicationWillEnterForeground because this method will get called when you come from setting app to your app.
You can write your code in this method like,
if([CLLocationManager locationServicesEnabled])
{
if([locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])
{
[locationManager requestWhenInUseAuthorization];
}
}
Use Location Delegate method :-
if([CLLocationManager locationServicesEnabled])
{
if([locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])
{
[locationManager requestWhenInUseAuthorization];
//Set Location Delegate
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
//Update Location start
[locationManager startUpdatingLocation];
}
}
else if(![CLLocationManager locationServicesEnabled])
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Location Services are disabled please enable location services to enjoy nearby experience" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Settings", nil];
alert.tag = 103;
[alert show];
}
#pragma mark CLLocationManager Delegate
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
//NSLog(#"OldLocation %f %f", oldLocation.coordinate.latitude, oldLocation.coordinate.longitude);
//NSLog(#"NewLocation %f %f", newLocation.coordinate.latitude, newLocation.coordinate.longitude);
[locationManager stopUpdatingLocation];
}

Method orders in viewDidLoad

I have methods in viewDidLoad, and it seems like the order of methods getting called is weird.
- (void)viewDidLoad
{
[super viewDidLoad];
// Get Location
self.locationManager = [[CLLocationManager alloc] init];
self.geocoder = [[CLGeocoder alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
if([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])
{
[self.locationManager requestWhenInUseAuthorization];
}
[self.locationManager startUpdatingLocation];
// Retrieve Data
[self retrieveData];
}
After viewDidLoad is called, it calls the retrieveData method before locationManager.
Shouldn't the locationManager be called before retrieveData because of the order?
I am new in Objective C, thank you for your help in advance.
as per your need call your method in inside the delegate methods, so remove the [self retrieveData]; from ViewDidLoad and add into inside the didFailWithError or didUpdateLocations methods.
- (void)viewDidLoad
{
[super viewDidLoad];
// Get Location
self.locationManager = [[CLLocationManager alloc] init];
self.geocoder = [[CLGeocoder alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
if([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])
{
[self.locationManager requestWhenInUseAuthorization];
}
[self.locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
UIAlertView *errorAlert = [[UIAlertView alloc]
initWithTitle:#"Error"
message:#"Failed to Get Your Location"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[errorAlert show];
// call here
[self retrieveData];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
// set or stop your location update
manager = nil;
[self.locationManager stopUpdatingLocation];
[manager stopUpdatingLocation];
CLLocation *newLocation = locations[[locations count] -1];
CLLocation *currentLocation = newLocation;
NSString *longitude = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.longitude];
NSString *latitude = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.latitude];
if (currentLocation != nil) {
NSLog(#"latitude: %#", latitude);
NSLog(#"longitude: #"%#", longitude);
}else {
UIAlertView *errorAlert = [[UIAlertView alloc]
initWithTitle:#"Error" message:#"Failed to Get Your Location"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[errorAlert show];
}
// call here
[self retrieveData];
}
Note
objective -C is the interpreter , it execute the every in step by step , so or may be your [self retrieveData]; is called in main thread, that is the reason it execute in prior.

locationManager not working on iOS 9

I have a problem with the refresh information on your GPS position.
The function given by me "locationManager" when you click the button does not refresh the information in the "Label".
My code: http://pastebin.com/hWeq6gTS
I am a novice programmer iOS. Please help.
The issue that is not always obvious with the location services is that you have to have one of these two keys in your Info.plist:
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
Then, when starting updating of your position, don't forget to request permissions first (again, depending on your requirements (when in use/always):
[self.locationManager requestWhenInUseAuthorization]
[self.locationManager requestAlwaysAuthorization]
Add these two properties in info.plist
'NSLocationAlwaysUsageDescription' and below property
Create CocoaTouch Class 'LocationManager' inherit from NSObject like below class.
Singleton Location Manager Class .h
#import <Foundation/Foundation.h>
#interface LocationManager : NSObject <CLLocationManagerDelegate>
{
CLLocationManager *locationManager;
}
#property (strong, nonatomic) NSString *longitude;
#property (strong, nonatomic) NSString *latitude;
#property (strong, nonatomic) CLLocation *currentLocation;
+ (instancetype)sharedInstance;
#end
Implementation here .m
#import "LocationManager.h"
#implementation LocationManager
- (id) init
{
self = [super init];
if (self != nil)
{
[self locationManager];
}
return self;
}
+ (instancetype)sharedInstance
{
static LocationManager *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[LocationManager alloc] init];
// Do any other initialisation stuff here
});
return sharedInstance;
}
- (void) locationManager
{
if ([CLLocationManager locationServicesEnabled])
{
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
if ([locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])
{
[locationManager requestWhenInUseAuthorization];
}
[locationManager startUpdatingLocation];
}
else{
UIAlertView *servicesDisabledAlert = [[UIAlertView alloc] initWithTitle:#"Location Services Disabled" message:#"You currently have all location services for this device disabled. If you proceed, you will be showing past informations. To enable, Settings->Location->location services->on" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:#"Continue",nil];
[servicesDisabledAlert show];
[servicesDisabledAlert setDelegate:self];
}
}
- (void)requestWhenInUseAuthorization
{
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
// If the status is denied or only granted for when in use, display an alert
if (status == kCLAuthorizationStatusAuthorizedWhenInUse || status == kCLAuthorizationStatusDenied) {
NSString *title;
title = (status == kCLAuthorizationStatusDenied) ? #"Location services are off" : #"Background location is not enabled";
NSString *message = #"To use background location you must turn on 'Always' in the Location Services Settings";
UIAlertView *alertViews = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Settings", nil];
[alertViews show];
}
// The user has not enabled any location services. Request background authorization.
else if (status == kCLAuthorizationStatusNotDetermined) {
[locationManager requestWhenInUseAuthorization];
}
}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"didFailWithError: %#", error);
UIAlertView *errorAlert = [[UIAlertView alloc]
initWithTitle:#"Error" message:#"Failed to Get Your Location" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
// [errorAlert show];
}
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
switch (status) {
case kCLAuthorizationStatusNotDetermined:
case kCLAuthorizationStatusRestricted:
case kCLAuthorizationStatusDenied:
{
// do some error handling
}
break;
default:{
[locationManager startUpdatingLocation];
}
break;
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
CLLocation *location;
location = [manager location];
CLLocationCoordinate2D coordinate = [location coordinate];
_currentLocation = [[CLLocation alloc] init];
_currentLocation = newLocation;
_longitude = [NSString stringWithFormat:#"%f",coordinate.longitude];
_latitude = [NSString stringWithFormat:#"%f",coordinate.latitude];
// globalObjects.longitude = [NSString stringWithFormat:#"%f",coordinate.longitude];
// globalObjects.latitude = [NSString stringWithFormat:#"%f",coordinate.latitude];
}
#end
import
#import "LocationManager.h"
in your AppDelegate.h
and call that in your AppDelegate.m's like this
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[LocationManager sharedInstance];
return true;
}
Then just get
[LocationManager sharedInstance].longitude or latitude for updated lat long.
Instead of using
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation{
// Location update code
}
use this function to get updated location
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
// Assigning the last object as the current location of the device
CLLocation *currentLocation = [locations lastObject];
}
Sometimes we do face problem when we do not check the authorisation status. You can check this code
// Custom initialization code
CLLocationManager *manager = [[CLLocationManager alloc]init];
manager.delegate = self;
manager.desiredAccuracy = kCLLocationAccuracyBest;
// Setting distance fiter to 10 to get notified only after location change about 10 meter
manager.distanceFilter = kCLDistanceFilterNone;
// Requesting for authorization
if ([manager respondsToSelector:#selector(requestWhenInUseAuthorization)]){
[manager requestWhenInUseAuthorization];
}
// Immediately starts updating the location
[manager startUpdatingLocation];
[manager startUpdatingHeading];
if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
// user activated automatic attraction info mode
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status == kCLAuthorizationStatusDenied ||
status == kCLAuthorizationStatusAuthorizedWhenInUse ||
status == kCLAuthorizationStatusNotDetermined) {
// present an alert indicating location authorization required
// and offer to take the user to Settings for the app via
// UIApplication -openUrl: and UIApplicationOpenSettingsURLString
[manager requestAlwaysAuthorization];
}
[manager requestWhenInUseAuthorization];
else
[manager requestAlwaysAuthorization];
endif

iOS 8 Parse.com update and pf geopoint current location

So I recently updated to the latest Parse SDK that's compatible with iOS 8 and I add the two keys NSLocationWhenInUseUsageDescription and NSLocationAlwaysUsageDescription...but for some reason [PFGeoPoint geopointForCurrentLocationInBackground] is not being called....and I don't understand why.
and here is a snippet of the code:
[PFGeoPoint geoPointForCurrentLocationInBackground:^(PFGeoPoint *geoPoint, NSError *error) {
if(!error){
NSLog(#"Got current geopoint!");
....
else{
UIAlertView *errorAlert = [[UIAlertView alloc]initWithTitle:#"Oops!" message:[error description] delegate:self cancelButtonTitle:nil otherButtonTitles:#"Okay", nil];
[errorAlert show]; }
}];
Can someone help please?
[PFGeoPoint geopointForCurrentLocationInBackground] will only be called if you have first called your CLLocationManager engaged and have asked the user for permission to show their location.
You also need to update the (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status method for iOS 8.
Something like this is what I use:
// 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];
}
else {
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters;
[locationManager startUpdatingLocation];
//<<PUT YOUR CODE HERE AFTER LOCATION IS UPDATING>>
}
You also need to implement the locationmanager delegate method to handle changes is location authorization status, like so:
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
switch (status) {
case kCLAuthorizationStatusDenied:
NSLog(#"kCLAuthorizationStatusDenied");
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Location Services Not Enabled" message:#"The app can’t access your current location.\n\nTo enable, please turn on location access in the Settings app under Location Services." delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alertView show];
}
break;
case kCLAuthorizationStatusAuthorizedWhenInUse:
{
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters;
[locationManager startUpdatingLocation];
CLLocation *currentLocation = locationManager.location;
if (currentLocation) {
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate setCurrentLocation:currentLocation];
}
}
break;
case kCLAuthorizationStatusAuthorizedAlways:
{
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters;
[locationManager startUpdatingLocation];
CLLocation *currentLocation = locationManager.location;
if (currentLocation) {
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate setCurrentLocation:currentLocation];
}
}
break;
case kCLAuthorizationStatusNotDetermined:
NSLog(#"kCLAuthorizationStatusNotDetermined");
break;
case kCLAuthorizationStatusRestricted:
NSLog(#"kCLAuthorizationStatusRestricted");
break;
}
}

Location Services in IOS

All,
I have this code :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert)];
self.locationmanager = [CLLocationManager new];
[self.locationmanager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.locationmanager setDistanceFilter:kCLDistanceFilterNone];
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status == kCLAuthorizationStatusRestricted || status == kCLAuthorizationStatusDenied)
{
// location not avaialble create an alert.
NSLog(#"User has not allowed location to be tracked");
}
if (status == kCLAuthorizationStatusAuthorized)
{
in the AppDelegate didfinishLauncingWithOptions, and I need to it to check / allow the location lat/long to be retrieved, the ViewdidLoad opens before the IF statement to see if it authorised. So the ViewDidLoad doesn't get the correct information. When the if(authorised) is executed then it goes to a db with the lat and long and then the view did load should get the data. but the view did load is blank as the if statement has not be ran. Within the IF statement it executes a block (NFNetworking) and it does get there. If i re-run it from XCODE it does.
In your Appdelegate.h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate,CLLocationManagerDelegate>
{
CLLocationCoordinate2D homeLocation;
CLLocationCoordinate2D phoneLocation;
CLLocationManager *locationManager;
CLLocation *currentLocation;
NSDictionary *cstreampostData;
}
In Appdeleate.m
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if ([CLLocationManager locationServicesEnabled]) {
self.locationManager = [[CLLocationManager alloc]init];
self.locationManager.delegate=self;
self.locationManager.desiredAccuracy=kCLLocationAccuracyKilometer;
}else{
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Location Services Not Available!" message:#"" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[alert show];
}
.
.
.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window makeKeyAndVisible];
return YES;
}
#pragma mark- Current Location Delegates
-(void)setUpLocationManager:(id)sender{
//location tracking
[self.locationManager startUpdatingLocation];
}
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
self.phoneLocation=CLLocationCoordinate2DMake(newLocation.coordinate.latitude, newLocation.coordinate.longitude);
self.currentLocation=newLocation;
if (newLocation.horizontalAccuracy <=1000.0f) {
[self.locationManager stopUpdatingLocation];
NSLog(#"%g %g",newLocation.coordinate.longitude, newLocation.coordinate.latitude);
self.cstreampostData=[NSDictionary dictionaryWithObjectsAndKeys:
[NSString stringWithFormat:#"%g",newLocation.coordinate.latitude],#"latitude",
[NSString stringWithFormat:#"%g",newLocation.coordinate.longitude],#"longitude", nil];
}
NSLog(#"current location latitude is======%f",phoneLocation.latitude);
NSLog(#"current location longitude is======%f",phoneLocation.longitude);
}
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
if (error.code == kCLErrorDenied) {
[self.locationManager stopUpdatingLocation];
}else if(error.code == kCLErrorLocationUnknown){
//retry
}else{
}
NSLog(#"%#",error);
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Location Services Not Available!" message:#"" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[alert show];
}
in your ViewController.m
-(void)viewDidLoad
{
[super viewDidLoad];
AppDelegate *appDelegate=(AppDelegate *)[UIApplication sharedApplication].delegate;
[appDelegate setUpLocationManager:sender];
}

Resources