Ios 当kCLAuthorizationStatusDenied时,带有映射子视图的视图反弹回其调用者

Ios 当kCLAuthorizationStatusDenied时,带有映射子视图的视图反弹回其调用者,ios,objective-c,parse-platform,cllocationmanager,Ios,Objective C,Parse Platform,Cllocationmanager,这里我有两种观点: 逻辑视图控制器 WallViewController 用户登录到LoginViewController后,它将转到包含地图视图的WallViewController。首先,它将请求用户访问当前位置的权限。如果用户选择允许访问,则不会有任何问题。但是,如果用户选择不允许访问,用户将从WallViewController返回到LoginViewController我想做的是让用户保持在WallViewController中,即使无法访问当前位置。如何实现这一点?下面是我的相关

这里我有两种观点:

  • 逻辑视图控制器
  • 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];
    }
}];
- (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];
    }
}
WallViewController.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];
    }
}];
- (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];
    }
}

考虑到上面的代码,我在登录后发现会出现一个弹出窗口,询问用户是否允许访问当前位置。如果用户选择“否”,则会出现一个警告视图,提示“此应用无法访问您的当前位置。若要查看附近的帖子或在您的当前位置创建帖子,请在“位置服务”下的“设置”应用中打开此应用对您位置的访问。”单击“确定”后,它将返回其调用者LoginViewController,但我希望它保持在WallViewController中。这里需要一些帮助。提前谢谢。

我在下面的代码中将
代表:self
更改为
代表: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];

那么在WallViewController viewDidLoad中,您还做了什么?看起来你一定是在某个地方跳转到根视图控制器或其他东西是的,还有其他东西,但没有一个可以跳转到根VC。我的理解是,一旦状态变为kCLAuthorizationStatusDenied,当前视图(WallViewController)将被强制关闭,然后返回根视图LoginViewController。我找不到一个办法来防止这种情况。如果你有任何线索,请提供建议。谢谢。