使用CLLocationManager定制位置管理器类 [英] custom Location Manager class using CLLocationManager

查看:190
本文介绍了使用CLLocationManager定制位置管理器类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很熟悉iOS开发(我的第一个应用程序),我遇到了这个问题。



我有一个iPhone应用程序,应该将用户的当前位置多个用户按钮触摸ViewController。为了防止冗余代码(在不同的视图控制器中实现 locationManager:didFailWithError locationManager:didUpdateToLocation:fromLocation 等多次)我决定创建一个名为 LocationManager 的自定义类:



LocationManager.h / p>

  @interface LocationManager:NSObject&CLLocationManagerDelegate> {
@private
CLLocationManager * CLLocationManagerInstance;
id< LocationManagerAssigneeProtocol>受让人;
}

- (void)getUserLocationWithDelegate:(id)delegate;

LocationManager.m

  @implementation LocationManager 

- (id)init {
self = [super init];
if(self){
CLLocationManagerInstance = [[CLLocationManager alloc] init];
CLLocationManagerInstance.desiredAccuracy = kCLLocationAccuracyBest;
CLLocationManagerInstance.delegate = self;
}
return self;
}

- (void)getUserLocationWithDelegate:(id)delegate {
if([CLLocationManager locationServicesEnabled]){
assignee = delegate;
[CLLocationManagerInstance startUpdatingLocation];



#pragma CLLocationManagerDelegate

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {$ b (CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
[CLLocationManagerInstance()) stopUpdatingLocation];
[受让人didUpdateToLocation:newLocation];
}

我有一个名为 LocationManagerAssigneeProtocol 的协议,我的ViewController实现

  @protocol LocationManagerAssigneeProtocol< NSObject> 

@required
- (void)didUpdateToLocation:(CLLocation *)location;

@end

在需要的视图控制器中

   - (IBAction)getMyLocation:(id)sender {

[locationMgr getUserLocationWithDelegate:self];
}

这段代码很好用,但是我感觉到我违反了通过让 LocationManager 能够调用本身发起对位置管理器的呼叫的类的功能,这里的一些设计模式。另一方面,我不想为所有应用于地理位置的视图控制器实施 CLLocationManagerDelegate



是有什么更好的解决方案吗?

解决方案

我同意@CarlVeazey就这一个。任何时候,代表对于1到1的关系是非常好的,但是在您的情况下,您可能需要多个视图控件来响应任何给定时间的位置事件。所以只需删除与您的委托及其相关协议相关的任何内容。



我可能会将LocationManager类设为单例,并修改更新方法:

 code> +(LocationManager *)sharedInstance 
{
static LocationManager * _sharedInstance = nil;
static dispatch_once_t oncePredicate;
dispatch_once(& oncePredicate,^ {
_sharedInstance = [[self alloc] init];
});

return _sharedInstance;


- (void)getUserLocation
{
if([CLLocationManager locationServicesEnabled])
[CLLocationManager startUpdatingLocation]; (CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
[CLLocationManagerInstance stopUpdatingLocation ]。
[[NSNotificationCenter defaultCenter] postNotificationWithName:@LocationManagerDidUpdateLocation对象:newLocation];
}

...那么需要使用这个类的任何viewController都会有类似的东西:

   - (void)viewDidLoad 
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserverForName:@LocationManagerDidUpdateLocation对象:self queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * note){
CLLocation * location = note.object;
...
}];
}

- (IBAction)getMyLocation:(id)sender {
[[LocationManager sharedInstance] getUserLocation];
}

希望有所帮助,有意义。


I'm pretty new to iOS development (my first app) and I faced this issue.

I have an iPhone app that should get user's current location in multiple ViewControllers upon user button touch. To prevent redundant code (implementing locationManager:didFailWithError, locationManager:didUpdateToLocation:fromLocation, etc. multiple times in different view controllers) I decided to create a custom class called LocationManager:

LocationManager.h

@interface LocationManager : NSObject <CLLocationManagerDelegate> {
@private
    CLLocationManager *CLLocationManagerInstance;
    id<LocationManagerAssigneeProtocol> assignee;
}

-(void) getUserLocationWithDelegate:(id) delegate;

LocationManager.m

@implementation LocationManager

-(id)init {
    self = [super init];
    if(self) {
        CLLocationManagerInstance = [[CLLocationManager alloc] init];
        CLLocationManagerInstance.desiredAccuracy = kCLLocationAccuracyBest;
        CLLocationManagerInstance.delegate = self;
    }
    return self;
}

-(void) getUserLocationWithDelegate:(id) delegate {
    if([CLLocationManager locationServicesEnabled]) {
        assignee = delegate;
        [CLLocationManagerInstance startUpdatingLocation];
    }
}

#pragma CLLocationManagerDelegate

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
...
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
    [CLLocationManagerInstance stopUpdatingLocation];
    [assignee didUpdateToLocation:newLocation];
}

and I have a protocol called LocationManagerAssigneeProtocol that my ViewControllers implement

@protocol LocationManagerAssigneeProtocol <NSObject>

@required
-(void) didUpdateToLocation:(CLLocation *) location;

@end

and in my viewcontroller where needed

- (IBAction)getMyLocation:(id)sender {

    [locationMgr getUserLocationWithDelegate:self];
}

This code works perfectly, however, I have a feeling that I'm violating some design patterns here by letting LocationManager be able to call a function of the class that itself initiated a call to Location Manager. On the other hand, I don't want to go with implementing CLLocationManagerDelegate for all my viewcontrollers that are supposed to work with locations.

Are there any better solution to this issue?

解决方案

I agree with @CarlVeazey on this one. Delegate are great for a 1 to 1 relationship existing at any one time, however in your case it seems that you may need multiple viewControllers to respond to location events at any given time. So just remove anything related to your delegate and its associated protocol.

I'd probably make LocationManager class a singleton and modify the methods for updating:

+(LocationManager *)sharedInstance
{
    static LocationManager *_sharedInstance = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        _sharedInstance = [[self alloc] init];
    });

    return _sharedInstance;
}

-(void)getUserLocation
{
    if ([CLLocationManager locationServicesEnabled])
        [CLLocationManager startUpdatingLocation];
}

-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation 
{
    [CLLocationManagerInstance stopUpdatingLocation];
    [[NSNotificationCenter defaultCenter] postNotificationWithName:@"LocationManagerDidUpdateLocation" object:newLocation];
}

... Then any viewController that needs to use this class would have something like:

-(void)viewDidLoad
{
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserverForName:@"LocationManagerDidUpdateLocation" object:self queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
        CLLocation *location = note.object;
        ...
    }];
}

-(IBAction)getMyLocation:(id)sender {
    [[LocationManager sharedInstance] getUserLocation];
}

Hope that helps and makes sense.

这篇关于使用CLLocationManager定制位置管理器类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆