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

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


当前回答

在iOS 8中,你需要做两件额外的事情来让定位工作:给你的信息添加一个键。Plist并从位置管理器请求授权,要求它启动

info.plist:

<key>NSLocationUsageDescription</key>
<string>I need location</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>I need location</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>I need location</string>

将此添加到代码中

if (IS_OS_8_OR_LATER)
{
    [locationmanager requestWhenInUseAuthorization];

    [locationmanager requestAlwaysAuthorization];
}

其他回答

为了确保这与iOS 7向后兼容,你应该检查用户运行的是iOS 8还是iOS 7。例如:

#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)

//In ViewDidLoad
if(IS_OS_8_OR_LATER) {
   [self.locationManager requestAlwaysAuthorization];
}

[self.locationManager startUpdatingLocation];

我当时在开发一款升级到iOS 8的应用,位置服务停止了。你可能会在Debug区域得到一个错误,如下所示:

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

我做了侵入性最小的手术。首先添加NSLocationAlwaysUsageDescription条目到你的info.plist:

注意,我没有填写这个键的值。这仍然有效,我并不担心,因为这是一个内部应用程序。此外,已经有一个标题要求使用位置服务,所以我不想做任何多余的事情。

接下来我为iOS 8创建了一个条件:

if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
    [_locationManager requestAlwaysAuthorization];
}

之后locationManager:didChangeAuthorizationStatus:方法为call:

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:  (CLAuthorizationStatus)status
{
    [self gotoCurrenLocation];
}

现在一切正常。和往常一样,请查看文档。

- (void)viewDidLoad
{
    
    [super viewDidLoad];
    self.locationManager = [[CLLocationManager alloc] init];
    
    self.locationManager.delegate = self;
    if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]){
        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");
            }
        }
    }
    [self.locationManager startUpdatingLocation];
}

>  #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 didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
    {
        NSLog(@"didUpdateToLocation: %@", newLocation);
        CLLocation *currentLocation = newLocation;
        
        if (currentLocation != nil) {
            longitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];
            latitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
        }
    }

In iOS 8 you need to do two extra things to get location working: Add a key to your Info.plist and request authorization from the location manager asking it to start. There are two Info.plist keys for the new location authorization. One or both of these keys is required. If neither of the keys are there, you can call startUpdatingLocation but the location manager won’t actually start. It won’t send a failure message to the delegate either (since it never started, it can’t fail). It will also fail if you add one or both of the keys but forget to explicitly request authorization. So the first thing you need to do is to add one or both of the following keys to your Info.plist file:

NSLocationWhenInUseUsageDescription NSLocationAlwaysUsageDescription

这两个键都有一个字符串

这就是为什么你需要位置服务。你可以 输入一个字符串,如“位置是必须找到你在哪里” 和iOS 7一样,可以在InfoPlist中进行本地化。字符串文件。

这是ios 8的问题 将此添加到代码中

if (IS_OS_8_OR_LATER)
{
    [locationmanager requestWhenInUseAuthorization];

    [locationmanager requestAlwaysAuthorization];
}

到info.plist:

 <key>NSLocationUsageDescription</key>
 <string>I need location</string>
 <key>NSLocationAlwaysUsageDescription</key>
 <string>I need location</string>
 <key>NSLocationWhenInUseUsageDescription</key>
 <string>I need location</string>

苹果的文件显示:

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.

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