I am working with Map Kit in iOS 8 using Obj-C NOT SWIFT. I cannot get the device location it is set a 0.00, 0.00 and I am getting the error:
我正在使用iOS 8中的Map Kit,使用object - c而不是SWIFT。我无法得到设备位置它被设置为0。00,0。00我得到了错误:
Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.
I have implemented: ( I have tried only one at a time and no luck )
我实现了:(我一次只尝试了一个,没有运气)
if(IS_OS_8_OR_LATER) {
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
}
[self.locationManager startUpdatingLocation];
And in info.plist
而在info.plist
NSLocationWhenInUseUsageDescription : App would like to use your location.
NSLocationAlwaysUsageDescription : App would like to use your location.
I do get prompted to allow the app to use my location but after I agree nothing changes. The location is being showed as 0.00, 0.00.
我确实会被提示允许应用程序使用我的位置,但在我同意之后没有任何改变。位置显示为0.00,0.00。
Code for displaying users location:
显示用户位置的代码:
//Get Location
self.locatiOnManager= [[CLLocationManager alloc] init];
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
MKCoordinateRegion region = { { 0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = self.locationManager.location.coordinate.latitude;
region.center.lOngitude= self.locationManager.location.coordinate.longitude;
region.span.lOngitudeDelta= 0.005f;
region.span.lOngitudeDelta= 0.005f;
[mapView setRegion:region animated:YES];
Mike.
迈克。
**EDIT: View Answer Below.
* *编辑:查看下面的回答。
130
I got it working. I've posted my code below to help anyone else having issues.
我明白了工作。我在下面发布了我的代码,以帮助其他有问题的人。
Here is my full code to get the MapKit Map View working in iOS 8.
这是我在ios8中使用MapKit地图视图的完整代码。
In your AppName-Info.plist Add a new row with the key name being:
在你AppName-Info。plist添加一个新的行,键名为:
NSLocationWhenInUseUsageDescription
Or
或
NSLocationAlwaysUsageDescription
With the value being a string of the message that you want to be displayed:
值为您希望显示的消息的字符串:
YourAppName would like to use your location.
In your header file. (I use App Name-Prefix.pch but YourViewController.h will work too)
在你的头文件。(我使用应用程序名称前缀。pch但YourViewController。h也将工作)
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
YourViewController.h
YourViewController.h
#import
#import
@interface YourViewController : UIViewController {
}
@property(nonatomic, retain) IBOutlet MKMapView *mapView;
@property(nonatomic, retain) CLLocationManager *locationManager;
YourViewController.m
YourViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
mapView.delegate = self;
self.locatiOnManager= [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
#ifdef __IPHONE_8_0
if(IS_OS_8_OR_LATER) {
// Use one or the other, not both. Depending on what you put in info.plist
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
}
#endif
[self.locationManager startUpdatingLocation];
mapView.showsUserLocation = YES;
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
}
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:YES];
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
NSLog(@"%@", [self deviceLocation]);
//View Area
MKCoordinateRegion region = { { 0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = self.locationManager.location.coordinate.latitude;
region.center.lOngitude= self.locationManager.location.coordinate.longitude;
region.span.lOngitudeDelta= 0.005f;
region.span.lOngitudeDelta= 0.005f;
[mapView setRegion:region animated:YES];
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
}
- (NSString *)deviceLocation {
return [NSString stringWithFormat:@"latitude: %f longitude: %f", self.locationManager.location.coordinate.latitude, self.locationManager.location.coordinate.longitude];
}
- (NSString *)deviceLat {
return [NSString stringWithFormat:@"%f", self.locationManager.location.coordinate.latitude];
}
- (NSString *)deviceLon {
return [NSString stringWithFormat:@"%f", self.locationManager.location.coordinate.longitude];
}
- (NSString *)deviceAlt {
return [NSString stringWithFormat:@"%f", self.locationManager.location.altitude];
}
Enjoy!
享受吧!
--Mike
——迈克
8
It's not written anywhere, but if your app starts with MapKit, you will still receive the error message "Trying to start MapKit location updates without prompting for location authorization" even after implementing MBarton's answer. To avoid it, you have to create a new view controller before the MapKit, and implement the location manager delegates there. I called it AuthorizationController.
它不是在任何地方编写的,但是如果你的应用以MapKit开始,即使实现了MBarton的答案,你仍然会收到错误信息“试图在不提示位置授权的情况下启动MapKit位置更新”。为了避免这种情况,您必须在MapKit之前创建一个新的视图控制器,并在那里实现位置管理器委托。我叫它AuthorizationController。
So, in AuthorizationController.h:
所以,在AuthorizationController.h:
#import
#import
@interface MCIAuthorizationController : UIViewController
@property (strong, nonatomic) CLLocationManager *locationManager;
@end
And in AuthorizationController.m:
而在AuthorizationController.m:
- (void)viewDidLoad {
[super viewDidLoad];
// Location manager
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];
}
}
#pragma mark - Location Manager delegates
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
NSLog(@"didUpdateLocations: %@", [locations lastObject]);
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(@"Location manager error: %@", error.localizedDescription);
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
if (status == kCLAuthorizationStatusAuthorizedWhenInUse) {
[self.locationManager startUpdatingLocation];
[self performSegueWithIdentifier:@"startSegue" sender:self];
} else if (status == kCLAuthorizationStatusDenied) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Location services not authorized"
message:@"This app needs you to authorize locations services to work."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
} else
NSLog(@"Wrong location status");
}
3
Try This One:
试试这个:
(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
if (status == kCLAuthorizationStatusAuthorizedWhenInUse) {
self.mapView.showsUserLocation = YES;
}
2
Your code looks fine, though you do not need to call requestWhenInUseAuthorization and the other requestAlwaysAuthorization , choose one you need.
您的代码看起来很好,但是不需要调用requestWhenInUseAuthorization和另一个requestAlwaysAuthorization,选择一个您需要的。
Code for displaying locations is just yet allocating locationManager, do not expect to get location data instantly.
显示位置的代码正在分配locationManager,不要期望立即获得位置数据。
you need to wait till delegate method gets called : -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
, then self.locationManager.location will also be set.
您需要等待委托方法被调用:-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)位置,然后self。locationManager。位置也将被设置。
2
Further to Mikes answer, I found that using both [self.locationManager requestWhenInUseAuthorization];
and [self.locationManager requestAlwaysAuthorization];
as demonstrated in his code does not work. You should only use ONE.
进一步的回答,我发现两者都使用。locationManager requestWhenInUseAuthorization];和自我。locationManager requestAlwaysAuthorization];如他的代码所示,它不起作用。你应该只使用一个。
I assume some further changes were made with a more recent/stable version of the API.
我假设对API的最新/稳定版本做了进一步的修改。
2
I had the same problem but adding these two line in plist file solved my problems
我遇到了同样的问题,但是在plist文件中添加这两行就解决了我的问题
NSLocationWhenInUseUsageDescription
And
和
NSLocationAlwaysUsageDescription
NOTE : Must provide string description of both these values. You can use any of them in your controller file as below
注意:必须提供这两个值的字符串描述。您可以在您的控制器文件中使用它们中的任何一个,如下所示
self.locatiOnManager= [[CLLocationManager alloc] init];
self.locationManager.delegate=self;
[self.locationManager requestAlwaysAuthorization];
You must implement CLLOcationManagerDelegate
in your controller to access this functionality
您必须在控制器中实现CLLOcationManagerDelegate,以访问这个功能
0
To extend the accepted answer and if you create a sample project with just the above functionality, then apart from CoreLocation
and Mapkit
frameworks, you might need to add UIKit
, Foundation
and CoreGraphics
framework manually as well in Xcode 6
.
为了扩展所接受的答案,如果您创建了一个具有上述功能的示例项目,那么除了CoreLocation和Mapkit框架之外,您可能还需要在Xcode 6中手动添加UIKit、Foundation和CoreGraphics框架。
-2
Actually, I am studying the CS193P Lecture 16, which is about location and map view, and I could not make the location manager work in iOS 8, applying what was in the video. Looking at your answer, I could make it work.
实际上,我正在学习CS193P课程16,它是关于位置和地图视图的,我不能让位置管理器在ios8中工作,应用视频中的内容。看着你的答案,我可以让它生效。
The Info.plist was modified as described in the answers (I use the NSLocationWhenInUseUsageDescription).
Info。plist被修改为在答案中所描述的(我使用的NSLocationWhenInUseUsageDescription)。
In AddPhotoViewController.hn the define was added :
在AddPhotoViewController。增加了定义:
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
In AddPhotoViewController.m, the following code was added in ViewDidLoad (after self.image):
在AddPhotoViewController。m,在ViewDidLoad中添加了以下代码(self.image之后):
#ifdef __IPHONE_8_0
if(IS_OS_8_OR_LATER)
{
[self.locationManager requestWhenInUseAuthorization];
}
#endif
The authorization will be asked only once, the first time you launch the application.
当您第一次启动应用程序时,将只请求一次授权。
The following was also added to AddPhotoViewController.h because it was not said in Lecture 16 :
下面的内容也被添加到AddPhotoViewController中。h,因为第16讲没有提到
@property (nonatomic) NSInteger locationErrorCode;
shouldPerformSegueWithIdentifier was modified to include else if (!self.location) :
shouldPerformSegueWithIdentifier被修改为包含else if (!self.location):
else if (![self.titleTextField.text length])
{
[self alert:@"Title required"];
return NO;
}
else if (!self.location)
{
switch (self.locationErrorCode)
{
case kCLErrorLocationUnknown:
[self alert:@"Couldn't figure out where this photo was taken (yet)."]; break;
case kCLErrorDenied:
[self alert:@"Location Services disabled under Privacy in Settings application."]; break;
case kCLErrorNetwork:
[self alert:@"Can't figure out where this photo is being taken. Verify your connection to the network."]; break;
default:
[self alert:@"Cant figure out where this photo is being taken, sorry."]; break;
}
return NO;
}
else
{ // should check imageURL too to be sure we could write the file
return YES;
}
didFailWithError was added :
didFailWithError添加:
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
self.locatiOnErrorCode= error.code;
}