使用CLLocationManager定制位置管理器类 [英] custom Location Manager class using CLLocationManager
问题描述
我有一个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屋!