我的应用在iOS 7上运行良好,但在iOS 8 SDK上却无法运行。

CLLocationManager不返回位置,我没有看到我的应用程序下设置->位置服务。我在这个问题上做了谷歌搜索,但没有任何结果。会有什么问题呢?


当前回答

用于询问位置的旧代码将无法在iOS 8中使用。您可以尝试使用此方法进行位置授权:

- (void)requestAlwaysAuthorization
{
    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 *alertView = [[UIAlertView alloc] initWithTitle:title
                                                            message:message
                                                           delegate:self
                                                  cancelButtonTitle:@"Cancel"
                                                  otherButtonTitles:@"Settings", nil];
        [alertView show];
    }
    // The user has not enabled any location services. Request background authorization.
    else if (status == kCLAuthorizationStatusNotDetermined) {
        [self.locationManager requestAlwaysAuthorization];
    }
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 1) {
        // Send the user to the Settings for this app
        NSURL *settingsURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
        [[UIApplication sharedApplication] openURL:settingsURL];
    }
}

其他回答

我也因为同样的问题而抓狂。Xcode给出错误:

试图启动MapKit位置更新而没有提示 位置授权。必须调用-[CLLocationManager requestWhenInUseAuthorization]或-[CLLocationManager . request requestAlwaysAuthorization]。

但即使实现了上述方法之一,它也不会提示用户,除非信息中有条目。NSLocationAlwaysUsageDescription或NSLocationWhenInUseUsageDescription。

添加以下行到您的信息。Plist,其中字符串值代表您需要访问用户位置的原因

<key>NSLocationWhenInUseUsageDescription</key>
<string>This application requires location services to work</string>

<key>NSLocationAlwaysUsageDescription</key>
<string>This application requires location services to work</string>

我认为自从我在Xcode 5中开始这个项目以来,这些条目可能已经丢失了。我猜Xcode 6可能会为这些键添加默认条目,但还没有确认。

你可以在这里找到更多关于这两个设置的信息

苹果的文件显示:

https://developer.apple.com/documentation/corelocation/requesting_permission_to_use_location_services https://developer.apple.com/documentation/corelocation/cllocationmanager/1620562-requestwheninuseauthorization

As of iOS 8, the presence of a NSLocationWhenInUseUsageDescription or a NSLocationAlwaysUsageDescription key value in your app's Info.plist file is required. It's then also necessary to request permission from the user prior to registering for location updates, either by calling [self.myLocationManager requestWhenInUseAuthorization] or [self.myLocationManager requestAlwaysAuthorization] depending on your need. The string you entered into the Info.plist will then be displayed in the ensuing dialog.

如果用户授予了权限,则业务照常进行。如果他们拒绝权限,则委托不会被告知位置更新。

我的解决方案可以在Xcode 5中编译:

#ifdef __IPHONE_8_0
    NSUInteger code = [CLLocationManager authorizationStatus];
    if (code == kCLAuthorizationStatusNotDetermined && ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)] || [self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])) {
        // choose one request according to your business.
        if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"]){
            [self.locationManager requestAlwaysAuthorization];
        } else if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) {
            [self.locationManager  requestWhenInUseAuthorization];
        } else {
            NSLog(@"Info.plist does not contain NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription");
        }
    }
#endif
    [self.locationManager startUpdatingLocation];

用于询问位置的旧代码将无法在iOS 8中使用。您可以尝试使用此方法进行位置授权:

- (void)requestAlwaysAuthorization
{
    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 *alertView = [[UIAlertView alloc] initWithTitle:title
                                                            message:message
                                                           delegate:self
                                                  cancelButtonTitle:@"Cancel"
                                                  otherButtonTitles:@"Settings", nil];
        [alertView show];
    }
    // The user has not enabled any location services. Request background authorization.
    else if (status == kCLAuthorizationStatusNotDetermined) {
        [self.locationManager requestAlwaysAuthorization];
    }
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 1) {
        // Send the user to the Settings for this app
        NSURL *settingsURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
        [[UIApplication sharedApplication] openURL:settingsURL];
    }
}

Swift开发者常犯的一个错误:

首先确保你添加了一个值到plist为NSLocationWhenInUseUsageDescription或NSLocationAlwaysUsageDescription。

如果你仍然没有看到一个窗口弹出要求授权,看看你是否把行var locationManager = CLLocationManager()在你的视图控制器的viewDidLoad方法。如果这样做,那么即使调用locationManager.requestWhenInUseAuthorization(),也不会显示任何内容。这是因为在viewDidLoad执行后,locationManager变量被释放(清除)。

解决方案是在类方法的顶部找到var locationManager = CLLocationManager()行。