我是 iOS 开发的新手。我的问题是,当我想尝试在真实设备上获取当前位置但它不起作用并给我以下错误时:
Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.
我使用的是 Xcode 6.2,源代码如下:
////.h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
@protocol LocationViewDelegate <NSObject>
-(void)sendLocationLatitude:(double)latitude
longitude:(double)longitude
andAddress:(NSString *)address;
@end
@interface HomeViewController : UIViewController
@property (nonatomic, assign) id<LocationViewDelegate> delegate;
- (instancetype)initWithLocation:(CLLocationCoordinate2D)locationCoordinate;
@end
////.m
#import "HomeViewController.h"
#import "anotation.h"
#import <MapKit/MapKit.h>
#import "LocationViewController.h"
//In ViewDidLoad
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
static LocationViewController *defaultLocation = nil;
@interface HomeViewController () <MKMapViewDelegate,CLLocationManagerDelegate> {
CLLocationManager *locationManager;
MKMapView *_mapView;
MKPointAnnotation *_annotation;
CLLocationCoordinate2D _currentLocationCoordinate;
BOOL _isSendLocation;
}
@property (strong, nonatomic) NSString *addressString;
@end
@implementation HomeViewController
@synthesize addressString = _addressString;
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
_isSendLocation = YES;
}
return self;
}
- (instancetype)initWithLocation:(CLLocationCoordinate2D)locationCoordinate {
self = [super initWithNibName:nil bundle:nil];
if (self) {
_isSendLocation = NO;
_currentLocationCoordinate = locationCoordinate;
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
float fOSVersion=[[[UIDevice currentDevice] systemVersion] floatValue];
if(fOSVersion>=8.0) {
[locationManager requestAlwaysAuthorization];
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status == kCLAuthorizationStatusNotDetermined) {
[locationManager requestWhenInUseAuthorization];
} else {
[locationManager startUpdatingLocation];
}
}
UIButton *backButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 44)];
[backButton setImage:[UIImage imageNamed:@"back.png"] forState:UIControlStateNormal];
// [backButton setTitle:NSLocalizedString(@"back", @"") forState:UIControlStateNormal];
[backButton addTarget:self.navigationController action:@selector(popViewControllerAnimated:) forControlEvents:UIControlEventTouchUpInside];
UIView *backButtonView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 63, 33)];
// backButtonView.backgroundColor=[UIColor whiteColor];
backButtonView.bounds = CGRectOffset(backButtonView.bounds, 45, 5);
[backButtonView addSubview:backButton];
UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithCustomView:backButtonView];
[self.navigationItem setLeftBarButtonItem:backItem];
_mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
_mapView.delegate = self;
_mapView.mapType = MKMapTypeStandard;
_mapView.zoomEnabled = YES;
[self.view addSubview:_mapView];
if (_isSendLocation) {
_mapView.showsUserLocation = YES;//显示当前位置
UIButton *sendButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 60, 44)];
UIView *avatarButtonView = [[UIView alloc] initWithFrame:CGRectMake(290, 0, 63, 33)];
[sendButton setTitle:@"发送" forState:UIControlStateNormal];
[sendButton setTitleColor:[UIColor whiteColor]forState:UIControlStateNormal];
[sendButton addTarget:self action:@selector(sendLocation) forControlEvents:UIControlEventTouchUpInside];
//avatarButtonView.backgroundColor=[UIColor whiteColor];
avatarButtonView.bounds = CGRectOffset(avatarButtonView.bounds, -25, 5);
[avatarButtonView addSubview:sendButton];
UIBarButtonItem *avatarItem = [[UIBarButtonItem alloc] initWithCustomView:avatarButtonView];
[self.navigationItem setRightBarButtonItem:avatarItem];
// self.navigationItem.rightBarButtonItem.enabled = ;
[self startLocation];
}
else {
[self removeToLocation:_currentLocationCoordinate];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma marks StatusBar
- (UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleLightContent;
}
- (BOOL)prefersStatusBarHidden {
return NO;
}
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:NO];
}
-(void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
}
#pragma mark - class methods
+ (instancetype)defaultLocation {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
defaultLocation = [[LocationViewController alloc] initWithNibName:nil bundle:nil];
});
return defaultLocation;
}
#pragma mark - MKMapViewDelegate
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
__weak typeof(self) weakSelf = self;
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:userLocation.location completionHandler:^(NSArray *array, NSError *error) {
if (!error && array.count > 0) {
CLPlacemark *placemark = [array objectAtIndex:0];
weakSelf.addressString = placemark.name;
[self removeToLocation:userLocation.coordinate];
}
}];
}
- (void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error
{
}
#pragma mark - public
- (void)startLocation {
if (_isSendLocation) {
self.navigationItem.rightBarButtonItem.enabled = NO;
}
}
-(void)createAnnotationWithCoords:(CLLocationCoordinate2D)coords {
if (_annotation == nil) {
_annotation = [[MKPointAnnotation alloc] init];
}
else{
[_mapView removeAnnotation:_annotation];
}
_annotation.coordinate = coords;
[_mapView addAnnotation:_annotation];
}
- (void)removeToLocation:(CLLocationCoordinate2D)locationCoordinate {
_currentLocationCoordinate = locationCoordinate;
float zoomLevel = 0.01;
MKCoordinateRegion region = MKCoordinateRegionMake(_currentLocationCoordinate, MKCoordinateSpanMake(zoomLevel, zoomLevel));
[_mapView setRegion:[_mapView regionThatFits:region] animated:YES];
if (_isSendLocation) {
self.navigationItem.rightBarButtonItem.enabled = YES;
}
[self createAnnotationWithCoords:_currentLocationCoordinate];
}
- (void)sendLocation {
if (_delegate && [_delegate respondsToSelector:@selector(sendLocationLatitude:longitude:andAddress:)]) {
[_delegate sendLocationLatitude:_currentLocationCoordinate.latitude longitude:_currentLocationCoordinate.longitude andAddress:_addressString];
}
[self.navigationController popViewControllerAnimated:YES];
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
if (status != kCLAuthorizationStatusNotDetermined) {
[locationManager startUpdatingLocation];
}
}
@end