sobota, 27 lipca 2013

Lokalizacja - CLLocationManager, CLLocation

Czasami w projektach potrzebny są nam współrzędne użytkownika, poniżej chciałbym przedstawić bardzo prosty menadżer, który pozwoli bardzo łatwo korzystać z dostepnych funkcji bez konieczności kopiowania kodu w kilka miejsc w naszym projekcie, szczególnie jeżeli chcemy używać CLLocationManager w kilku kontrolerach.


#import <Foundation/Foundation.h>
#import <CoreLocation/CLLocation.h>
#import <CoreLocation/CLAvailability.h>
#import <MapKit/MapKit.h>

typedef void (^CLLocationManagerCompletion)(NSArray *locations);
typedef void (^CLLocationManagerError)(NSError *error);





@interface LocationService : NSObject<CLLocationManagerDelegate>

@property(nonatomic, retain) CLLocation *userLocation;
@property(nonatomic, retain) CLLocationManager *locationManager;
@property (copy, nonatomic) CLLocationManagerCompletion callbackCompletion;
@property (copy, nonatomic) CLLocationManagerError callbackError;


+ (LocationService*) sharedInstance;
- (void) updateUserLocationsOnCompletion:(CLLocationManagerCompletion) completion onError:(CLLocationManagerError) error;
- (void)startUpdateUserLocation;
- (void) stopUpdatingUserLocation;
@end




#import "LocationService.h"

@implementation LocationService
@synthesize userLocation = _userLocation;
static LocationService *instance = nil;

+(LocationService*) sharedInstance
{
    if (!instance)
    {
        instance = [[self alloc] init];
        instance.userLocation = [[[CLLocation alloc] init] autorelease];
    }
    return instance;
}

- (void)dealloc
{
    instance.locationManager = nil;
    instance = nil;
    [super dealloc];
}

- (void)startUpdateUserLocation{
    if (instance.locationManager == nil) {
        instance.locationManager = [[[CLLocationManager alloc] init] autorelease];
        instance.locationManager.delegate = instance;
    }
    [instance.locationManager startUpdatingLocation];
}

- (void) stopUpdatingUserLocation{
    [instance.locationManager stopUpdatingLocation];
}
- (void) updateUserLocationsOnCompletion:(CLLocationManagerCompletion) completion onError:(CLLocationManagerError) error{
    [self startUpdateUserLocation];
    self.callbackCompletion = completion;
    self.callbackError = error;
}

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
    self.callbackCompletion(locations);
    self.userLocation = [locations lastObject];
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
    self.callbackError(error);

}



Tutaj w bardzo prostu sposób możemy zobaczyć, że przy użyciu bloków ( o których też zamierzam trochę więcej napisać ) można szybko i przyjemnie obsłużyć implementacje interfejsu wymuszonego przez delegate.

W korzystając z takiego rozwiązania w bardzo prosty obsłużyć metody zwracające dane z gps'a. Rozszerzając ową klasę możemy zaimplementować geolokalizację, sami ustalić interwał odświeżania dodając odpowiedni timer.


    [[LocationService sharedInstance] updateUserLocationsOnCompletion:^(NSArray *locations) {
        CLLocation *location = (CLLocation*) [locations lastObject];
        
    } onError:^(NSError *error) {
        
    }];



Powyżej znajduje się przykład zastosowania owego menadżera już w gotowym projekcie, w sekcji onCompletion otrzymujemy lokalizacje użytkownika, jeżeli "coś" poszło nie tak  z lokalizacją obsłużona zostanie sekcja onError.





0 komentarze:

Prześlij komentarz