Objective c 位置服务在iOS 8中不工作

Objective c 位置服务在iOS 8中不工作,objective-c,ios8,location,cllocationmanager,Objective C,Ios8,Location,Cllocationmanager,我在iOS7上运行良好的应用程序与ios8sdk不兼容 CLLocationManager不会返回位置,我也不会在设置->位置服务下看到我的应用程序。我在谷歌上搜索了这个问题,但什么也没找到。有什么问题吗?我最终解决了自己的问题 显然,在iOS 8 SDK中,在开始位置更新之前需要调用CLLocationManager(用于后台位置)或RequestWhenUseAuthorization(仅在前台位置)调用CLLocationManager 还需要NSLocationAlwaysUsageDe

我在iOS7上运行良好的应用程序与ios8sdk不兼容


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

我最终解决了自己的问题

显然,在iOS 8 SDK中,在开始位置更新之前需要调用
CLLocationManager
(用于后台位置)或
RequestWhenUseAuthorization
(仅在前台位置)调用
CLLocationManager

还需要
NSLocationAlwaysUsageDescription
nsLocationWhenUsageDescription
输入
Info.plist
,并在提示中显示消息。添加这些解决了我的问题


有关更多详细信息,请查看:

我也遇到了同样的问题。Xcode为您提供了以下错误:

正在尝试启动
MapKit
位置更新,而不提示输入 位置授权。必须调用
-[CLLocationManager
使用授权时请求]
-[CLLocationManager
请求始终授权]
首先

但是,即使您实现了上述方法之一,它也不会提示用户,除非info.plist中有
NSLocationAlwaysUsageDescription
nslocationwhenusagedescription
的条目

在info.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>
n不使用时的位置说明
此应用程序需要位置服务才能工作
N位置始终使用说明
此应用程序需要位置服务才能工作
我想自从我在Xcode 5中启动这个项目以来,这些条目可能已经丢失了。我猜Xcode 6可能会为这些键添加默认条目,但尚未确认


您可以根据Apple文档找到关于这两种设置的更多信息:

从iOS 8开始,在应用程序的Info.plist文件中不使用UsageDescription时,需要出现
nsLocation或
NSLocationAlwaysUsageDescription
键值。然后,还需要在注册位置更新之前,通过调用
[self.myLocationManager RequestWhenUseAuthorization]
[self.myLocationManager requestAlwaysAuthorization]
请求用户的许可,具体取决于您的需要。然后,您在Info.plist中输入的字符串将显示在随后的对话框中


如果用户授予权限,则一切照旧。如果他们拒绝权限,则不会通知代理位置更新。

要确保这与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];

具有向后兼容性的解决方案:

SEL requestSelector = NSSelectorFromString(@"requestWhenInUseAuthorization");
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined &&
    [self.locationManager respondsToSelector:requestSelector]) {
    [self.locationManager performSelector:requestSelector withObject:NULL];
} else {
    [self.locationManager startUpdatingLocation];
}

在您的Info.plist解决方案中设置NSLocationWhenUsageDescription key,该解决方案具有向后兼容性,不会产生Xcode警告:

SEL requestSelector = NSSelectorFromString(@"requestWhenInUseAuthorization");
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined &&
  [self.locationManager respondsToSelector:requestSelector]) {
((void (*)(id, SEL))[self.locationManager methodForSelector:requestSelector])(self.locationManager, requestSelector);
  [self.locationManager startUpdatingLocation];
} else {
  [self.locationManager startUpdatingLocation];
}
设置
nslocationwhenusagedescription
输入您的
Info.plist

对于iOS版本11.0+
设置
nsLocationAlways和WhenUsageDescription
输入您的
Info.plist
。还有另外两把钥匙

可以在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];
    }
}
和你的info.plist文件

在iOS 8中,您需要做两件额外的事情才能使位置正常工作:在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>
NSLocationWhenInUseUsageDescription

为所有拥有多个Info.plist文件的用户提供的小帮助

find . -name Info.plist | xargs -I {} /usr/libexec/PlistBuddy -c 'Add NSLocationWhenInUseUsageDescription string' {} 
它将向当前目录(及其子文件夹)中的所有Info.plist文件添加所需的标记

另一个是:

find . -name Info.plist | xargs -I {} /usr/libexec/PlistBuddy -c 'Set NSLocationWhenInUseUsageDescription $YOURDESCRIPTION' {} 

它会将您的描述添加到所有文件中。

[locationManager startUpdatingLocation]之前,添加iOS8位置服务请求:

if([locationManager respondsToSelector:@selector(requestAlwaysAuthorization)])
    [locationManager requestAlwaysAuthorization];
编辑应用程序的
Info.plist
,并使用将显示给用户的字符串值添加key
NSLocationAlwaysUsageDescription
(例如,
我们尽最大努力保护您的电池寿命。

如果您的应用仅在应用打开时才需要位置服务,请更换:

requestAlwaysAuthorization
requestwhenUseAuthorization

nslocationalwayusagedescription
nslocationwhenusagedescription
一起使用

  • 添加键
    nsLocationWhenUsageDescription
    NSLocationAlwaysUsageDescription
    (后台GPS使用)以及字符串,请求在每个目标的
    info.plist
    上使用GPS

  • 通过运行以下命令请求许可:

    [自初始化locationManager:locationManager]

  • 其中,
    initLocationManager
    是:

    // asks for GPS authorization on iOS 8
    -(void) initLocationManager:(CLLocationManager *) locationManager{
    
        locationManager = [[CLLocationManager alloc]init];
    
        if([locationManager respondsToSelector:@selector(requestAlwaysAuthorization)])
            [locationManager requestAlwaysAuthorization];
    }
    

    请记住,如果每个目标的
    info.plist
    上都没有按键,则应用程序不会询问用户。
    if
    提供了与iOS 7的兼容性,而
    respondsToSelector:
    方法保证了未来的兼容性,而不仅仅是解决iOS 7和8的问题。

    要访问iOS 8中的用户位置,您必须添加

    NSLocationAlwaysUsageDescription in the Info.plist 
    

    这将要求用户获得获取其当前位置的权限。

    对于使用Xamarin的用户,当InUsageDescription
    手动添加到info.plist时,我必须添加键
    nsLocation,因为它在Xamarin 5.5.3 Build 6或XCode 6.1的下拉列表中都不可用-只有
    NSLocationUsageDescription
    在列表中,这导致
    CLLocationManager
    继续无声地失败。

    我正在开发一个升级到iOS的应用程序
            // ** Don't forget to add NSLocationWhenInUseUsageDescription in MyApp-Info.plist and give it a string
    
            self.locationManager = [[CLLocationManager alloc] init];
            self.locationManager.delegate = self;
            // Check for iOS 8. Without this guard the code will crash with "unknown selector" on iOS 7.
            if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
                [self.locationManager requestWhenInUseAuthorization];
            }
            [self.locationManager startUpdatingLocation];
    
    
        // Location Manager Delegate Methods    
        - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
        {
            NSLog(@"%@", [locations lastObject]);
    
    }
    
            // ** Don't forget to add NSLocationWhenInUseUsageDescription in MyApp-Info.plist and give it a string
    
            self.locationManager = [[CLLocationManager alloc] init];
            self.locationManager.delegate = self;
            // Check for iOS 8. Without this guard the code will crash with "unknown selector" on iOS 7.
            if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
                [self.locationManager requestWhenInUseAuthorization];
            }
            [self.locationManager startUpdatingLocation];
    
    
        // Location Manager Delegate Methods    
        - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
        {
            NSLog(@"%@", [locations lastObject]);
    
    }
    
    if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
        [_locationManager requestAlwaysAuthorization];
    }
    
    - (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];
            }
        }
    
    "NSLocationWhenInUseUsageDescription" = "I need GPS information....";
    
    if (IS_OS_8_OR_LATER)
    {
        [locationmanager requestWhenInUseAuthorization];
    
        [locationmanager requestAlwaysAuthorization];
    }
    
     <key>NSLocationUsageDescription</key>
     <string>I need location</string>
     <key>NSLocationAlwaysUsageDescription</key>
     <string>I need location</string>
     <key>NSLocationWhenInUseUsageDescription</key>
     <string>I need location</string>
    
    import UIKit
    import MapKit
    import CoreLocation
    
    class MapViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
    
        // MARK: Properties
        @IBOutlet weak var mapView: MKMapView!
    
        let locationManager = CLLocationManager()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            self.locationManager.delegate = self
            self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
            self.locationManager.requestWhenInUseAuthorization()
            self.locationManager.startUpdatingLocation()
            self.mapView.showsUserLocation = true
    
        }
    
        // MARK: - Location Delegate Methods
    
        func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            let location = locations.last
            let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
            let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 1, longitudeDelta: 1))
            self.mapView.setRegion(region, animated: true)
        }
    
        func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
            print("Errors: " + error.localizedDescription)
        }
    }
    
        <key>NSLocationWhenInUseUsageDescription</key>
        <string>Because I want to know where you are!</string>
        <key>NSLocationAlwaysUsageDescription</key>
        <string>Want to know where you are!</string>
    
     1. NSLocationAlwaysAndWhenInUseUsageDescription 
     2. NSLocationWhenInUseUsageDescription
     3. NSLocationAlwaysUsageDescription
    
    NSLocationWhenInUseUsageDescription
    
    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
    if([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]){
        [locationManager requestWhenInUseAuthorization];
    }else{
        [locationManager startUpdatingLocation];
    } 
    
    #pragma mark - Lolcation Update 
    - (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 didChangeAuthorizationStatus:(CLAuthorizationStatus)status
    {
        switch (status) {
            case kCLAuthorizationStatusNotDetermined:
            case kCLAuthorizationStatusRestricted:
            case kCLAuthorizationStatusDenied:
            {
                // do some error handling
            }
                break;
            default:{
                [locationManager startUpdatingLocation];
            }
                break;
        }
    }
    - (void)locationManager:(CLLocationManager *)manager
         didUpdateLocations:(NSArray *)locations
    {
        CLLocation *location = [locations lastObject];
        userLatitude =  [NSString stringWithFormat:@"%f", location.coordinate.latitude] ;
        userLongitude =  [NSString stringWithFormat:@"%f",location.coordinate.longitude];
        [locationManager stopUpdatingLocation];
    }
    
     1. NSLocationAlwaysAndWhenInUseUsageDescription 
     2. NSLocationWhenInUseUsageDescription
     3. NSLocationAlwaysUsageDescription
    
    import CoreLocation
    class ViewController: UIViewController ,CLLocationManagerDelegate {
    var locationManager = CLLocationManager()
    
    //MARK- Update Location 
    func updateMyLocation(){
        locationManager.delegate = self;
        locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
        if locationManager.respondsToSelector(#selector(CLLocationManager.requestWhenInUseAuthorization)){
           locationManager.requestWhenInUseAuthorization()
        }
        else{
            locationManager.startUpdatingLocation()
        }
    }
    
    //MARK: Location Update
    func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
        NSLog("Error to update location :%@",error)
    }
    func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        switch status {
        case .NotDetermined: break
        case .Restricted: break
        case .Denied:
                NSLog("do some error handling")
            break
        default:
            locationManager.startUpdatingLocation()
        }
    }
    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
         let location = locations.last! as CLLocation
        var latitude = location.coordinate.latitude
        var longitude = location.coordinate.longitude
    
    }