Как исправить ошибку CLLocation Manager с ошибкой местоположения?
Я пытаюсь заставить работать менеджер CLLocation, но он постоянно выдает мне сообщение об ошибке locationManager failed with error=Error Domain=kCLErrorDomain Code=0 "The operation couldn’t be completed. (kCLErrorDomain error 0.)"
, Я посмотрел на stackru для ответов, и я обнаружил, что This error also occurs if you have Scheme/Edit Scheme/Options/Allow Location Simulation checked but don't have a default location set.
Применяя это, он поднял синюю точку с установленным местоположением по умолчанию. Но я хочу текущее местоположение пользователя. У меня есть код для этого, но, похоже, не работает должным образом, следовательно, ошибка, обнаруживающая текущего пользователя.
Viewcontroller.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CLLocation.h>
#import "Park.h"
@interface ViewController : UIViewController <MKMapViewDelegate,CLLocationManagerDelegate>
@property(nonatomic, strong) IBOutlet MKMapView *mapView;
//@property(nonatomic, strong) IBOutlet UIBarButtonItem *refresh;
@property(nonatomic, strong) UIActivityIndicatorView *activityView;
@property(nonatomic, strong) CLLocationManager *locationManager;
@property(nonatomic, strong) NSMutableArray *parks;
@property(nonatomic, readonly) MKUserLocation *userLocation;
-(void)startUpdating; //start location manager updating plus..
-(void)stopUpdating; //stop location manager updating plus..
-(IBAction)refresh; //call startUpdating
// Source: http://www.devfright.com/mkmapview-and-mkmapview-delegate-tutorial/
-(IBAction)setMapType:(UISegmentedControl *)sender;
@end
ViewController.m
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
@synthesize locationManager, userLocation;
#pragma mark -
#pragma mark MKMapViewDelegateMethods
// This delegate method is called once for every annotation that is created.
// If no view is returned by this method, then only the default pin is seen by the user
-(MKAnnotationView *)mapView:(MKMapView *)mv viewForAnnotation:(id<MKAnnotation>)annotation
{
MKAnnotationView *view = nil;
if(annotation != mv.userLocation)
{
// if it's NOT the user's current location pin, create the annotation
Park *parkAnnotation = annotation;
// Look for an existing view to reuse
view = [mv dequeueReusableAnnotationViewWithIdentifier:@"parkAnnotation"];
// If an existing view is not found, create a new one
if(view == nil)
{
view = [[MKPinAnnotationView alloc] initWithAnnotation:(id)parkAnnotation reuseIdentifier:@"parkAnnotation"];
}
// Now we have a view for the annotation, so let's set some properties
[(MKPinAnnotationView *)view setPinColor:MKPinAnnotationColorRed];
[(MKPinAnnotationView *)view setAnimatesDrop:YES];
[view setCanShowCallout:YES];
// Now create buttons for the annotation view
// The "tag" properties are set so that we can identify which button was tapped later
UIButton *leftButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
leftButton.tag = 0;
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
rightButton.tag = 1;
// Add buttons to annotation view
[view setLeftCalloutAccessoryView:leftButton];
[view setRightCalloutAccessoryView:rightButton];
}
// send this annotation view back to MKMapView so it can add it to the pin
return view;
}
// This method is called when one of the two buttons added to the annotation view is tapped
-(void)mapView:(MKMapView *)mv annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
Park *parkAnnotation = (Park *)[view annotation];
switch([control tag])
{
case 0: // left button
{
NSURL *url = [NSURL URLWithString:parkAnnotation.link];
[[UIApplication sharedApplication] openURL:url];
}
break;
case 1: // right button
{
//build maps url. This will launch the Maps app on the hardware, and the apple maps in the simulator
CLLocationCoordinate2D coordinate = locationManager.location.coordinate;
NSString *url2 = [NSString stringWithFormat:@"http://maps.apple.com/maps?saddr=%f,%f&daddr=%f,%f",coordinate.latitude,coordinate.longitude,parkAnnotation.gps_location.coordinate.latitude,parkAnnotation.gps_location.coordinate.longitude];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:url2]];
}
break;
default: NSLog(@"Should not be here in calloutAccessoryControlTapped, tag=%d!",[control tag]);
break;
}
// Reference
// https://developer.apple.com/library/ios/featuredarticles/iPhoneURLScheme_Reference/MapLinks/MapLinks.html
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 20000,20000);
[self.mapView setRegion:region animated:YES];
//add an annotation
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = userLocation.coordinate;
point.title = @"My Current Location";
point.subtitle = @"You are here.";
[self.mapView addAnnotation:point];
[self stopUpdating];
[self.mapView setCenterCoordinate:userLocation.coordinate animated:YES]; // animate current location when moving
// zoom onto the user's current location
float spanX = 0.00725;
float spanY = 0.00725;
//MKCoordinateRegion region;
region.center.latitude = self.mapView.userLocation.coordinate.latitude;
region.center.longitude = self.mapView.userLocation.coordinate.longitude;
region.span.latitudeDelta = spanX;
region.span.longitudeDelta = spanY;
}
// Source: http://stackru.com/questions/10222308/zoom-mapview-to-a-region-where-pins-are-dropped
-(void)zoomToFitMapAnnotations:(MKMapView*)mapView insideArray:(NSArray*)anAnnotationArray
{
// NSLog(@"%s", __FUNCTION__);
if([mapView.annotations count] == 0) return;
CLLocationCoordinate2D topLeftCoord;
topLeftCoord.latitude = -90;
topLeftCoord.longitude = 180;
CLLocationCoordinate2D bottomRightCoord;
bottomRightCoord.latitude = 90;
bottomRightCoord.longitude = -180;
for(MKPointAnnotation *annotation in anAnnotationArray)
{
topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude);
topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude);
bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude);
bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude);
}
MKCoordinateRegion region;
region.center.latitude = topLeftCoord.latitude - (topLeftCoord.latitude - bottomRightCoord.latitude) * 0.5;
region.center.longitude = topLeftCoord.longitude + (bottomRightCoord.longitude - topLeftCoord.longitude) * 0.5;
region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 1.1; // Add a little extra space on the sides
region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 1.1; // Add a little extra space on the sides
region = [mapView regionThatFits:region];
[mapView setRegion:region animated:YES];
}
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(@"locationManager failed with error=%@",error);
[self stopUpdating];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Location Manager Failed!" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Map and Location Initialization
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.mapView.delegate = self;
self.mapView.mapType = MKMapTypeStandard; // set default selection
self.mapView.showsUserLocation = YES;
[self startUpdating];
for(Park *park in self.parks)
{
[self.mapView addAnnotation:(id)park];
}
}
-(void)startUpdating //start location manager updating plus..
{
[self.locationManager startUpdatingLocation];
}
-(void)stopUpdating //stop location manager updating plus..
{
[self.locationManager stopUpdatingLocation];
}
-(IBAction)refresh //call startUpdating
{
[self startUpdating];
}
// Source: http://www.devfright.com/mkmapview-and-mkmapview-delegate-tutorial/
// Switch between map view type
-(IBAction)setMapType:(UISegmentedControl *)sender
{
switch(sender.selectedSegmentIndex)
{
case 0: self.mapView.mapType = MKMapTypeStandard;
break;
case 1: self.mapView.mapType = MKMapTypeSatellite;
break;
case 2: self.mapView.mapType = MKMapTypeHybrid;
break;
default:
break;
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
1 ответ
Несколько вещей, одна из которых NSLocationAlwaysUsageDescription добавлена в файл info.plist ваших приложений? Два вы установили местоположение в симуляторе? (Debug->Location). В-третьих, вы должны запросить дополнительную авторизацию для использования основного местоположения в ios8.
if ([locationManager respondsToSelector:@selector(requestAlwaysAuthorization)])
[locationManager requestAlwaysAuthorization];