[英]Location Services not working in iOS 8
My app that worked fine on iOS 7 doesn't work with the iOS 8 SDK.我在 iOS 7 上运行良好的应用程序不适用于 iOS 8 SDK。
CLLocationManager
doesn't return a location, and I don't see my app under Settings -> Location Services either. CLLocationManager
不返回位置,我也没有在“设置” ->“位置服务”下看到我的应用程序。 I did a Google search on the issue, but nothing came up.我对这个问题进行了谷歌搜索,但没有任何结果。 What could be wrong?
可能有什么问题?
I ended up solving my own problem.我最终解决了我自己的问题。
Apparently in iOS 8 SDK, requestAlwaysAuthorization
(for background location) or requestWhenInUseAuthorization
(location only when foreground) call on CLLocationManager
is needed before starting location updates.显然在 iOS 8 SDK 中,在开始位置更新之前,需要在
CLLocationManager
上调用requestAlwaysAuthorization
(用于后台位置)或requestWhenInUseAuthorization
(仅在前台时定位)。
There also needs to be NSLocationAlwaysUsageDescription
or NSLocationWhenInUseUsageDescription
key in Info.plist
with a message to be displayed in the prompt. Info.plist
还需要有NSLocationAlwaysUsageDescription
或NSLocationWhenInUseUsageDescription
键,并在提示中显示一条消息。 Adding these solved my problem.添加这些解决了我的问题。
For more extensive information, have a look at: Core-Location-Manager-Changes-in-ios-8有关更多信息,请查看: Core-Location-Manager-Changes-in-ios-8
I was pulling my hair out with the same problem.我正在用同样的问题拉我的头发。 Xcode gives you the error:
Xcode 给你错误:
Trying to start
MapKit
location updates without prompting for location authorization.尝试在不提示位置授权的情况下启动
MapKit
位置更新。 Must call-[CLLocationManager requestWhenInUseAuthorization]
or-[CLLocationManager requestAlwaysAuthorization]
first.必须先调用
-[CLLocationManager requestWhenInUseAuthorization]
或-[CLLocationManager requestAlwaysAuthorization]
。
But even if you implement one of the above methods, it won't prompt the user unless there is an entry in the info.plist for NSLocationAlwaysUsageDescription
or NSLocationWhenInUseUsageDescription
.但即使您实现了上述方法之一,它也不会提示用户,除非 info.plist 中有
NSLocationAlwaysUsageDescription
或NSLocationWhenInUseUsageDescription
。
Add the following lines to your info.plist where the string values represent the reason you you need to access the users location将以下行添加到您的 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>
I think these entries may have been missing since I started this project in Xcode 5. I'm guessing Xcode 6 might add default entries for these keys but have not confirmed.我认为自从我在 Xcode 5 中开始这个项目以来,这些条目可能已经丢失了。我猜 Xcode 6 可能会为这些键添加默认条目,但尚未确认。
You can find more information on these two Settings here您可以在此处找到有关这两个设置的更多信息
To ensure that this is backwards compatible with iOS 7, you should check whether the user is running iOS 8 or iOS 7. For example:为确保这与 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];
- (void)startLocationManager
{
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone; //whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
[locationManager requestWhenInUseAuthorization]; // Add This Line
}
And to your info.plist File和你的 info.plist 文件
According to the Apple docs:根据苹果文档:
As of iOS 8, the presence of a NSLocationWhenInUseUsageDescription
or a NSLocationAlwaysUsageDescription
key value in your app's Info.plist file is required.从 iOS 8 开始,应用程序的 Info.plist 文件中需要存在
NSLocationWhenInUseUsageDescription
或NSLocationAlwaysUsageDescription
键值。 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.然后还需要在注册位置更新之前请求用户的许可,根据您的需要调用
[self.myLocationManager requestWhenInUseAuthorization]
或[self.myLocationManager requestAlwaysAuthorization]
。 The string you entered into the Info.plist will then be displayed in the ensuing dialog.您在 Info.plist 中输入的字符串将显示在随后的对话框中。
If the user grants permission, it's business as usual.如果用户授予权限,则一切照旧。 If they deny permission, then the delegate is not informed of location updates.
如果他们拒绝许可,则不会通知代表位置更新。
- (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.
在 iOS 8 中,你需要做两件额外的事情来让定位工作:在你的 Info.plist 中添加一个密钥,并从位置管理器请求授权,要求它启动。 There are two Info.plist keys for the new location authorization.
新位置授权有两个 Info.plist 密钥。 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.
如果两个键都不存在,您可以调用 startUpdatingLocation 但位置管理器实际上不会启动。 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:
因此,您需要做的第一件事是将以下一个或两个键添加到您的 Info.plist 文件中:
Both of these keys take a string这两个键都需要一个字符串
which is a description of why you need location services.
这是您需要定位服务的原因的描述。 You can enter a string like “Location is required to find out where you are” which, as in iOS 7, can be localized in the InfoPlist.strings file.
您可以输入类似“Location is required to find your where you are”这样的字符串,就像在 iOS 7 中一样,可以在 InfoPlist.strings 文件中进行本地化。
My solution which can be compiled in Xcode 5:我的解决方案可以在 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];
The old code for asking location won't work in iOS 8. You can try this method for location authorization:旧的询问位置的代码在 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];
}
}
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在 iOS 8 中,你需要做两件额外的事情来让定位工作:向你的 Info.plist 添加一个密钥并请求定位管理器的授权,要求它启动
info.plist:信息.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>
Add this to your code将此添加到您的代码中
if (IS_OS_8_OR_LATER)
{
[locationmanager requestWhenInUseAuthorization];
[locationmanager requestAlwaysAuthorization];
}
One common error for Swift developers: Swift 开发人员的一个常见错误:
First make sure you add a value to the plist for either NSLocationWhenInUseUsageDescription
or NSLocationAlwaysUsageDescription
.首先确保为
NSLocationWhenInUseUsageDescription
或NSLocationAlwaysUsageDescription
添加一个值到 plist。
If you are still not seeing a window pop up asking for authorization, look to see if you are putting the line var locationManager = CLLocationManager()
in your View Controller's viewDidLoad
method.如果您仍然没有看到请求授权的弹出窗口,请查看您是否将
var locationManager = CLLocationManager()
放在视图控制器的viewDidLoad
方法中。 If you do, then even if you call locationManager.requestWhenInUseAuthorization()
, nothing will show up.如果这样做,那么即使您调用
locationManager.requestWhenInUseAuthorization()
,也不会显示任何内容。 This is because after viewDidLoad executes, the locationManager variable is deallocated (cleared out).这是因为在 viewDidLoad 执行后,locationManager 变量被释放(清除)。
The solution is to locate the line var locationManager = CLLocationManager()
at the top of the class method.解决方案是在类方法的顶部找到行
var locationManager = CLLocationManager()
。
Before [locationManager startUpdatingLocation];
[locationManager startUpdatingLocation];
之前[locationManager startUpdatingLocation];
, add an iOS8 location services request: ,添加一个 iOS8 位置服务请求:
if([locationManager respondsToSelector:@selector(requestAlwaysAuthorization)])
[locationManager requestAlwaysAuthorization];
Edit your app's Info.plist
and add key NSLocationAlwaysUsageDescription
with the string value that will be displayed to the user (for example, We do our best to preserve your battery life.
)编辑您的应用程序的
Info.plist
并添加键NSLocationAlwaysUsageDescription
和将显示给用户的字符串值(例如, We do our best to preserve your battery life.
)
If your app needs location services only while the app is open, replace:如果您的应用仅在应用打开时才需要定位服务,请替换:
requestAlwaysAuthorization
with requestWhenInUseAuthorization
and requestAlwaysAuthorization
和requestWhenInUseAuthorization
和
NSLocationAlwaysUsageDescription
with NSLocationWhenInUseUsageDescription
. NSLocationAlwaysUsageDescription
和NSLocationWhenInUseUsageDescription
。
I was working on an app that was upgraded to iOS 8 and location services stopped working.我正在开发一个升级到 iOS 8 的应用程序,但位置服务停止工作。 You'll probably get and error in the Debug area like so:
您可能会在 Debug 区域中得到和错误,如下所示:
Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.
I did the least intrusive procedure.我做了最少侵入性的程序。 First add
NSLocationAlwaysUsageDescription
entry to your info.plist:首先将
NSLocationAlwaysUsageDescription
条目添加到您的 info.plist 中:
Notice I didn't fill out the value for this key.注意我没有填写这个键的值。 This still works, and I'm not concerned because this is a in house app.
这仍然有效,我并不担心,因为这是一个内部应用程序。 Also, there is already a title asking to use location services, so I didn't want to do anything redundant.
另外,已经有一个标题要求使用位置服务,所以我不想做任何多余的事情。
Next I created a conditional for iOS 8:接下来我为 iOS 8 创建了一个条件:
if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
[_locationManager requestAlwaysAuthorization];
}
After this the locationManager:didChangeAuthorizationStatus:
method is call:在此之后
locationManager:didChangeAuthorizationStatus:
方法被调用:
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus: (CLAuthorizationStatus)status
{
[self gotoCurrenLocation];
}
And now everything works fine.现在一切正常。 As always, check out the documentation .
与往常一样,请查看文档。
Solution with backward compatibility:具有向后兼容性的解决方案:
SEL requestSelector = NSSelectorFromString(@"requestWhenInUseAuthorization");
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined &&
[self.locationManager respondsToSelector:requestSelector]) {
[self.locationManager performSelector:requestSelector withObject:NULL];
} else {
[self.locationManager startUpdatingLocation];
}
Setup NSLocationWhenInUseUsageDescription key in your Info.plist在 Info.plist 中设置 NSLocationWhenInUseUsageDescription 键
Solution with backward compatibility which doesn't produce Xcode warnings:具有向后兼容性且不会产生 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];
}
Setup NSLocationWhenInUseUsageDescription
key in your Info.plist
.在
Info.plist
设置NSLocationWhenInUseUsageDescription
键。
For iOS version 11.0+ : Setup NSLocationAlwaysAndWhenInUseUsageDescription
key in your Info.plist
.对于 iOS 11.0+ 版本:在
Info.plist
设置NSLocationAlwaysAndWhenInUseUsageDescription
键。 along with other 2 keys.以及其他 2 个键。
This is issue with ios 8 Add this to your code这是 ios 8 的问题 将此添加到您的代码中
if (IS_OS_8_OR_LATER)
{
[locationmanager requestWhenInUseAuthorization];
[locationmanager requestAlwaysAuthorization];
}
and to info.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>
To Access User Location in iOS 8 you will have to add,要在 iOS 8 中访问用户位置,您必须添加,
NSLocationAlwaysUsageDescription in the Info.plist
This will ask the user for the permission to get their current location.这将要求用户获得获取其当前位置的权限。
Objective-C Procedure Follow the below instructions: Objective-C 过程遵循以下说明:
For iOS-11 For iOS 11 have a look at this Answer: iOS 11 location access对于 iOS-11对于 iOS 11,请查看此答案: iOS 11 位置访问
Need to Add two Keys into plist and provide message as below image:需要将两个密钥添加到 plist 并提供如下图所示的消息:
1. NSLocationAlwaysAndWhenInUseUsageDescription
2. NSLocationWhenInUseUsageDescription
3. NSLocationAlwaysUsageDescription
For iOS-10 and below:
对于 iOS-10 及以下:
NSLocationWhenInUseUsageDescription
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
if([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]){
[locationManager requestWhenInUseAuthorization];
}else{
[locationManager startUpdatingLocation];
}
Delegate Methods委托方法
#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];
}
Swift Procedure快速程序
Follow the below instructions:请按照以下说明操作:
For iOS-11 For iOS 11 have a look at this Answer: iOS 11 location access对于 iOS-11对于 iOS 11,请查看此答案: iOS 11 位置访问
Need to Add two Keys into plist and provide message as below image:需要将两个密钥添加到 plist 并提供如下图所示的消息:
1. NSLocationAlwaysAndWhenInUseUsageDescription
2. NSLocationWhenInUseUsageDescription
3. NSLocationAlwaysUsageDescription
For iOS-10 and below:
对于 iOS-10 及以下:
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()
}
}
Delegate Methods委托方法
//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
}
对于那些使用Xamarin 的人,我必须手动将键NSLocationWhenInUseUsageDescription
添加到 info.plist 中,因为它在 Xamarin 5.5.3 Build 6 或 XCode 6.1 的下拉列表中不可用 - 只有NSLocationUsageDescription
在列表中,这导致了CLLocationManager
继续默默地失败。
A little helper for all of you that have more than one Info.plist file...对拥有多个 Info.plist 文件的所有人的小帮手...
find . -name Info.plist | xargs -I {} /usr/libexec/PlistBuddy -c 'Add NSLocationWhenInUseUsageDescription string' {}
It will add the needed tag to all of the Info.plist files in the current directory (and subfolders).它会将所需的标签添加到当前目录(和子文件夹)中的所有 Info.plist 文件中。
Another is:另一个是:
find . -name Info.plist | xargs -I {} /usr/libexec/PlistBuddy -c 'Set NSLocationWhenInUseUsageDescription $YOURDESCRIPTION' {}
It will add your description to all files.它会将您的描述添加到所有文件中。
// ** 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]);
}
Keep Cocoa Keys information always at your fingertips for those updates, here is the link:让Cocoa Keys信息始终触手可及,以获取这些更新,这是链接:
https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW26 https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW26
Enjoy.享受。
I get a similar error in iOS9 (working with Xcode 7 and Swift 2): Trying to start MapKit location updates without prompting for location authorization.我在 iOS9 中遇到了类似的错误(使用 Xcode 7 和 Swift 2):尝试在不提示位置授权的情况下启动 MapKit 位置更新。 Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.
必须先调用 -[CLLocationManager requestWhenInUseAuthorization] 或 -[CLLocationManager requestAlwaysAuthorization]。 I was following a tutorial but the tutor was using iOS8 and Swift 1.2.
我正在学习教程,但导师使用的是 iOS8 和 Swift 1.2。 There are some changes in Xcode 7 and Swift 2, I found this code and it works fine for me (if somebody needs help):
在 Xcode 7 和 Swift 2 中有一些变化,我发现这段代码对我来说很好用(如果有人需要帮助):
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)
}
}
Finally, I put that in info.plist: Information Property List: NSLocationWhenInUseUsageDescription Value: App needs location servers for staff最后,我把它放在 info.plist 中:信息属性列表: NSLocationWhenInUseUsageDescription值:应用程序需要员工的位置服务器
In order to access the users location in iOS.为了访问用户在 iOS 中的位置。 You need to add two keys
你需要添加两个键
NSLocationWhenInUseUsageDescription NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription NSLocationAlwaysUsageDescription
into the Info.plist file.进入 Info.plist 文件。
<key>NSLocationWhenInUseUsageDescription</key>
<string>Because I want to know where you are!</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Want to know where you are!</string>
See this below image.请参阅下图。
Add key NSLocationWhenInUseUsageDescription
or NSLocationAlwaysUsageDescription
(background GPS use) with string asking to use GPS on each info.plist
from each target.添加键
NSLocationWhenInUseUsageDescription
或NSLocationAlwaysUsageDescription
(背景 GPS 使用)和字符串,要求在每个目标的每个info.plist
上使用 GPS。
Ask for permission by running:通过运行请求许可:
[self initLocationManager:locationManager]; [self initLocationManager:locationManager];
Where initLocationManager
is: initLocationManager
在哪里:
// asks for GPS authorization on iOS 8
-(void) initLocationManager:(CLLocationManager *) locationManager{
locationManager = [[CLLocationManager alloc]init];
if([locationManager respondsToSelector:@selector(requestAlwaysAuthorization)])
[locationManager requestAlwaysAuthorization];
}
Remember that if the keys are not on each info.plist
for each target the app will not ask the user.请记住,如果密钥不在每个目标的每个
info.plist
,应用程序将不会询问用户。 The if
provides compatibility with iOS 7 and the respondsToSelector:
method guarantees future compatibility rather than just solving the issue for iOS 7 and 8. if
提供与 iOS 7 的兼容性, respondsToSelector:
方法保证了未来的兼容性,而不仅仅是解决 iOS 7 和 8 的问题。
The problem for me was that the class that was the CLLocationManagerDelegate
was private, which prevented all the delegate methods from being called.我的问题是
CLLocationManagerDelegate
类是私有的,这阻止了所有委托方法被调用。 Guess it's not a very common situation but thought I'd mention it in case t helps anyone.猜猜这不是一个很常见的情况,但我想我会提到它以防对任何人有帮助。
I add those key in InfoPlist.strings
in iOS 8.4, iPad mini 2. It works too.我在iOS 8.4、iPad mini 2 的
InfoPlist.strings
中添加了这些键。它也能工作。 I don't set any key, like NSLocationWhenInUseUsageDescription
, in my Info.plist
.我没有在我的
Info.plist
设置任何键,比如NSLocationWhenInUseUsageDescription
。
InfoPlist.strings : InfoPlist.strings :
"NSLocationWhenInUseUsageDescription" = "I need GPS information....";
Base on this thread , it said, as in iOS 7
, can be localized in the InfoPlist.strings.它说, 基于这个线程,
as in iOS 7
,可以在 InfoPlist.strings 中进行本地化。 In my test, those keys can be configured directly in the file InfoPlist.strings
.在我的测试中,这些键可以直接在文件
InfoPlist.strings
配置。
So the first thing you need to do is to add one or both of the > following keys to your Info.plist file:
因此,您需要做的第一件事是将 > 以下键中的一个或两个添加到您的 Info.plist 文件中:
- NSLocationWhenInUseUsageDescription
NSLocationWhenInUseUsageDescription
- NSLocationAlwaysUsageDescription
NSLocationAlwaysUsageDescription
Both of these keys take a string which is a description of why you need location services.
这两个键都采用一个字符串,它描述了您为什么需要位置服务。 You can enter a string like “Location is required to find out where you are” which, as in iOS 7 , can be localized in the InfoPlist.strings file.
您可以输入类似“Location is required to find your where you are”这样的字符串,就像在iOS 7 中一样,可以在 InfoPlist.strings 文件中进行本地化。
UPDATE:更新:
I think @IOS
's method is better.我认为
@IOS
的方法更好。 Add key to Info.plist
with empty value and add localized strings to InfoPlist.strings
.使用空值向
Info.plist
添加键,并将本地化字符串添加到InfoPlist.strings
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.