当前位置不会在真实设备上更新

时间:2015-04-09 03:53:56

标签: ios objective-c mapkit xcode-6.2 ios8.2

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

1 个答案:

答案 0 :(得分: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 添加它以描述您要使用位置服务的原因