0

我是 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
4

1 回答 1

0

在这里更改

 if (status != kCLAuthorizationStatusNotDetermined) {
        [locationManager startUpdatingLocation];
    }

if (status == kCLAuthorizationStatusAuthorized) {
            [locationManager startUpdatingLocation];
        }

并删除

CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
    if (status == kCLAuthorizationStatusNotDetermined) {
        [locationManager requestWhenInUseAuthorization];
    } else {
        [locationManager startUpdatingLocation];
    }

如果你没有在你的 plist 中添加 NSLocationAlwaysUsageDescription ,添加它来描述你为什么要使用定位服务

于 2015-04-09T04:42:11.377 回答