当 kCL AuthorizationStatus Denied 时,带有地图子视图的视图会反弹回其调用者

View with a map subview bounced back to its caller when kCLAuthorizationStatusDenied

这里我有2个观点:

用户在 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];