当 kCL AuthorizationStatus Denied 时,带有地图子视图的视图会反弹回其调用者
View with a map subview bounced back to its caller when kCLAuthorizationStatusDenied
这里我有2个观点:
- 登录视图控制器
- WallViewController
用户在 LoginViewController 中登录后,它将转到包含地图视图的 WallViewController。首先,它会询问用户是否允许访问当前位置。如果用户选择允许访问,就不会有任何问题。但是,如果用户选择不允许访问,用户将从 WallViewController 跳回到 LoginViewController。 我想做的是让用户留在 WallViewController 中,即使无法访问当前位置。我怎样才能做到这一点? 下面是我的相关代码。
LoginViewController.m
[PFUser logInWithUsernameInBackground:username password:password block:^(PFUser *user, NSError *error) {
// Tear down the activity view in all cases.
[activityView.activityIndicator stopAnimating];
[activityView removeFromSuperview];
if (user) {
//***************call WallViewController here*********
PAWWallViewController *wallViewController = [[PAWWallViewController alloc] initWithNibName:nil bundle:nil];
[(UINavigationController *)self.presentingViewController pushViewController:wallViewController animated:NO];
[self.presentingViewController dismissModalViewControllerAnimated:YES];
//****************************************************
} else {
// Didn't get a user.
NSLog(@"%s didn't get a user!", __PRETTY_FUNCTION__);
// Re-enable the done button if we're tossing them back into the form.
doneButton.enabled = [self shouldEnableDoneButton];
UIAlertView *alertView2 = nil;
if (error == nil) {
// the username or password is probably wrong.
NSLog(@"1");
alertView2 = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Couldn’t log in:\nThe username or password were wrong.", nil) message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:NSLocalizedString(@"Ok", nil), nil];
alertView2.tag = kSecondAlertViewTag;
} else {
// Something else went horribly wrong:
NSLog(@"2");
alertView2 = [[UIAlertView alloc] initWithTitle:[[error userInfo] objectForKey:@"error"] message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:NSLocalizedString(@"Ok", nil), nil];
alertView2.tag = kSecondAlertViewTag;
}
[alertView2 show];
// Bring the keyboard back up, because they'll probably need to change something.
[usernameField becomeFirstResponder];
}
}];
WallViewController.m
- (void)viewDidLoad {
// ...
[self startStandardUpdates];
}
- (void)startStandardUpdates {
if (nil == locationManager) {
locationManager = [[CLLocationManager alloc] init];
}
locationManager.delegate = self;
// This part was added due to a location authorization issue on iOS8
// See more at: http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/
if ([self._locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[self._locationManager requestWhenInUseAuthorization];
}
self.mapView.showsUserLocation = YES;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
// Set a movement threshold for new events.
locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters;
[locationManager startUpdatingLocation];
CLLocation *currentLocation = locationManager.location;
if (currentLocation) {
PAWAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
appDelegate.currentLocation = currentLocation;
}
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
NSLog(@"%s", __PRETTY_FUNCTION__);
switch (status) {
case kCLAuthorizationStatusAuthorized:
NSLog(@"kCLAuthorizationStatusAuthorized");
// Re-enable the post button if it was disabled before.
self.navigationItem.rightBarButtonItem.enabled = YES;
[locationManager startUpdatingLocation];
break;
//**********This alert will show up, once click Ok it will go back to its caller which is LoginViewController***********
case kCLAuthorizationStatusDenied:
NSLog(@"kCLAuthorizationStatusDenied");
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"This app can’t access your current location.\n\nTo view nearby posts or create a post at your current location, turn on access for this app to your location in the Settings app under Location Services.", nil) message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:NSLocalizedString(@"Ok", nil), nil];
[alertView show];
// Disable the post button.
self.navigationItem.rightBarButtonItem.enabled = NO;
}
break;
//**********************************************************************************************************************
case kCLAuthorizationStatusNotDetermined:
NSLog(@"kCLAuthorizationStatusNotDetermined");
break;
case kCLAuthorizationStatusRestricted:
NSLog(@"kCLAuthorizationStatusRestricted");
break;
default:break;
}
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
NSLog(@"%s", __PRETTY_FUNCTION__);
PAWAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
appDelegate.currentLocation = newLocation;
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error {
NSLog(@"%s", __PRETTY_FUNCTION__);
NSLog(@"Error: %@", [error description]);
if (error.code == kCLErrorDenied) {
[locationManager stopUpdatingLocation];
} else if (error.code == kCLErrorLocationUnknown) {
// todo: retry?
// set a timer for five seconds to cycle location, and if it fails again, bail and tell the user.
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error retrieving location", nil)
message:[error description]
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:NSLocalizedString(@"Ok", nil), nil];
[alert show];
}
}
根据上面的代码,我发现登录后会有一个弹窗询问用户是否允许当前位置访问。如果用户选择否,将会有一个警告视图说 "This app can’t access your current location. To view nearby posts or create a post at your current location, turn on access for this app to your location in the Settings app under Location Services." 在我单击确定后,它将返回到它的调用者,即 LoginViewController 但我希望它保留在 WallViewController 中。这里需要一些帮助。提前谢谢你。
我在下面的代码中将 delegate:self
更改为 delegate:nil
并解决了问题。
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"This app can’t access your current location.\n\nTo view nearby posts or create a post at your current location, turn on access for this app to your location in the Settings app under Location Services.", nil) message:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:NSLocalizedString(@"Ok", nil), nil];
这里我有2个观点:
- 登录视图控制器
- WallViewController
用户在 LoginViewController 中登录后,它将转到包含地图视图的 WallViewController。首先,它会询问用户是否允许访问当前位置。如果用户选择允许访问,就不会有任何问题。但是,如果用户选择不允许访问,用户将从 WallViewController 跳回到 LoginViewController。 我想做的是让用户留在 WallViewController 中,即使无法访问当前位置。我怎样才能做到这一点? 下面是我的相关代码。
LoginViewController.m
[PFUser logInWithUsernameInBackground:username password:password block:^(PFUser *user, NSError *error) {
// Tear down the activity view in all cases.
[activityView.activityIndicator stopAnimating];
[activityView removeFromSuperview];
if (user) {
//***************call WallViewController here*********
PAWWallViewController *wallViewController = [[PAWWallViewController alloc] initWithNibName:nil bundle:nil];
[(UINavigationController *)self.presentingViewController pushViewController:wallViewController animated:NO];
[self.presentingViewController dismissModalViewControllerAnimated:YES];
//****************************************************
} else {
// Didn't get a user.
NSLog(@"%s didn't get a user!", __PRETTY_FUNCTION__);
// Re-enable the done button if we're tossing them back into the form.
doneButton.enabled = [self shouldEnableDoneButton];
UIAlertView *alertView2 = nil;
if (error == nil) {
// the username or password is probably wrong.
NSLog(@"1");
alertView2 = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Couldn’t log in:\nThe username or password were wrong.", nil) message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:NSLocalizedString(@"Ok", nil), nil];
alertView2.tag = kSecondAlertViewTag;
} else {
// Something else went horribly wrong:
NSLog(@"2");
alertView2 = [[UIAlertView alloc] initWithTitle:[[error userInfo] objectForKey:@"error"] message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:NSLocalizedString(@"Ok", nil), nil];
alertView2.tag = kSecondAlertViewTag;
}
[alertView2 show];
// Bring the keyboard back up, because they'll probably need to change something.
[usernameField becomeFirstResponder];
}
}];
WallViewController.m
- (void)viewDidLoad {
// ...
[self startStandardUpdates];
}
- (void)startStandardUpdates {
if (nil == locationManager) {
locationManager = [[CLLocationManager alloc] init];
}
locationManager.delegate = self;
// This part was added due to a location authorization issue on iOS8
// See more at: http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/
if ([self._locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[self._locationManager requestWhenInUseAuthorization];
}
self.mapView.showsUserLocation = YES;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
// Set a movement threshold for new events.
locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters;
[locationManager startUpdatingLocation];
CLLocation *currentLocation = locationManager.location;
if (currentLocation) {
PAWAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
appDelegate.currentLocation = currentLocation;
}
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
NSLog(@"%s", __PRETTY_FUNCTION__);
switch (status) {
case kCLAuthorizationStatusAuthorized:
NSLog(@"kCLAuthorizationStatusAuthorized");
// Re-enable the post button if it was disabled before.
self.navigationItem.rightBarButtonItem.enabled = YES;
[locationManager startUpdatingLocation];
break;
//**********This alert will show up, once click Ok it will go back to its caller which is LoginViewController***********
case kCLAuthorizationStatusDenied:
NSLog(@"kCLAuthorizationStatusDenied");
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"This app can’t access your current location.\n\nTo view nearby posts or create a post at your current location, turn on access for this app to your location in the Settings app under Location Services.", nil) message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:NSLocalizedString(@"Ok", nil), nil];
[alertView show];
// Disable the post button.
self.navigationItem.rightBarButtonItem.enabled = NO;
}
break;
//**********************************************************************************************************************
case kCLAuthorizationStatusNotDetermined:
NSLog(@"kCLAuthorizationStatusNotDetermined");
break;
case kCLAuthorizationStatusRestricted:
NSLog(@"kCLAuthorizationStatusRestricted");
break;
default:break;
}
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
NSLog(@"%s", __PRETTY_FUNCTION__);
PAWAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
appDelegate.currentLocation = newLocation;
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error {
NSLog(@"%s", __PRETTY_FUNCTION__);
NSLog(@"Error: %@", [error description]);
if (error.code == kCLErrorDenied) {
[locationManager stopUpdatingLocation];
} else if (error.code == kCLErrorLocationUnknown) {
// todo: retry?
// set a timer for five seconds to cycle location, and if it fails again, bail and tell the user.
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error retrieving location", nil)
message:[error description]
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:NSLocalizedString(@"Ok", nil), nil];
[alert show];
}
}
根据上面的代码,我发现登录后会有一个弹窗询问用户是否允许当前位置访问。如果用户选择否,将会有一个警告视图说 "This app can’t access your current location. To view nearby posts or create a post at your current location, turn on access for this app to your location in the Settings app under Location Services." 在我单击确定后,它将返回到它的调用者,即 LoginViewController 但我希望它保留在 WallViewController 中。这里需要一些帮助。提前谢谢你。
我在下面的代码中将 delegate:self
更改为 delegate:nil
并解决了问题。
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"This app can’t access your current location.\n\nTo view nearby posts or create a post at your current location, turn on access for this app to your location in the Settings app under Location Services.", nil) message:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:NSLocalizedString(@"Ok", nil), nil];