LocationManager - 实现自定义封装定位类

相信很多app都需要用到定位这个功能,不知道大家写的时候有没有遇到这个问题:

LocationManager的代理方法在控制器中写的话可以进入,但是当自己自定义封装成一个类写成shareManager的时候,就不会进代理方法。

反复断点调试,发现shareManager是初始化了两次,此时猜想,可能是两个LocationManager的shareManager对象不一样,第二个把第一个覆盖了。

最后的解决方法是将shareManager用线程锁保证唯一性,终于可以进入代理方法。

在以后的shareManager中,应当保证其唯一性,再进行操作。

下面是代码:

#import <Foundation/Foundation.h>

#import <CoreLocation/CoreLocation.h>

 

typedef void (^SaveLocationCallback) (NSString *cityName);

@interface LocationManager : NSObject<CLLocationManagerDelegate> {

    

    CLLocationManager *_manager;

    SaveLocationCallback _saveLocationCallback;

}

 

//获取定位城市名称

+ (void) getCityName:(  SaveLocationCallback )cb;

//停止定位

+ (void) stop;

@end

 

#import "LocationManager.h"

 

@implementation LocationManager

+ (id) sharedGpsManager {

    static id s;

    static dispatch_once_t token;

    dispatch_once(&token, ^{

        s = [[LocationManager alloc] init];

    });

    return s;

}

- (id)init {

    self = [super init];

    if (self) {

        // 打开定位 然后得到数据

        _manager = [[CLLocationManager alloc] init];

        _manager.delegate = self;

        _manager.desiredAccuracy = kCLLocationAccuracyBest;

        _manager.distanceFilter = kCLDistanceFilterNone;

        float osVersion = [[[UIDevice currentDevice] systemVersion] floatValue];

        if (osVersion >= 8) {

            [_manager requestWhenInUseAuthorization];

           

        }

    }

    return self;

}

- (void) getCityName:(SaveLocationCallback)cb {

    if (![CLLocationManager locationServicesEnabled]) {

        return;

    }

    // block赋值

    _saveLocationCallback = [cb copy];

    // 停止上一次,开始新的数据定位

    [_manager stopUpdatingLocation];

    

    [_manager startUpdatingLocation];

}

//获取定位

+ (void) getCityName:(SaveLocationCallback)cb {

    [[LocationManager sharedGpsManager] getCityName:cb];

}

//结束定位

- (void) stop {

    [_manager stopUpdatingLocation];

}

+ (void) stop {

    [[LocationManager sharedGpsManager] stop];

}

#pragma mark - locationManagerDelegate

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {

    

    CLGeocoder *geoCoder = [[CLGeocoder alloc]init];//反向解析,根据及纬度反向解析出地址

    CLLocation *location = [locations objectAtIndex:0];

    [geoCoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {

        

        for(CLPlacemark *place in placemarks)

        {

           

            NSDictionary *dict = [place addressDictionary];

            if (_saveLocationCallback) {

                _saveLocationCallback(dict[@"City"]);

            }

        }

    }];

    

 

}

- (void)locationManager:(CLLocationManager *)manager

       didFailWithError:(NSError *)error{

    

switch([error code]) { case kCLErrorNetwork: // general, network-related error { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Please check your network connection or that you are not in airplane mode" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil]; [alert show]; [alert release]; } break; case kCLErrorDenied:{ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"User has denied to use current Location " delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil]; [alert show]; [alert release]; } break; default: { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Unknown network error" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil]; [alert show]; [alert release]; } break; } }

}

这里我们也需要关注一下locationManager:(CLLocationManager *)manager didFailWithError方法,error.code

kCLErrorNetwork网络错误
kCLErrorDenied用户拒绝访问(本来我以为[CLLocationManager locationServicesEnabled]会判断出来,但是,在给予了授权之后,用户手动关闭app获取位置的权限,就会触发这个错误。)

 

转载于:https://www.cnblogs.com/hansIOS/p/5209098.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值