I have create a custom delegate with CLLocationManagerDelegate when i call the delegate methods inside CLLocationManagerDelegate delegates are not working properly. i think the way i create the delegate was wrong can someone tell me what i have done wrong ?
.h file
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <UIKit/UIKit.h>
#protocol iBeaconDeligate<NSObject>
#required
-(void)getArray:(NSArray *)beaconArray;
#end
#interface iBeaconDeligate : NSObject <CLLocationManagerDelegate>
#property (strong, nonatomic) CLLocationManager *locationManager;
#property CLProximity lastProximity;
-(void) initiBeaconDeligate;
#end
this is .m file
#import "iBeaconDeligate.h"
#implementation iBeaconDeligate
-(void) initiBeaconDeligate
{
NSUUID *beaconUUID = [[NSUUID alloc] initWithUUIDString:
#"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"];
NSString *beaconIdentifier = #"iBeaconModules.us";
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:
beaconUUID identifier:beaconIdentifier];
self.locationManager = [[CLLocationManager alloc] init];
//[self.locationManager requestWhenInUseAuthorization];
//[self.locationManager requestAlwaysAuthorization];
// New iOS 8 request for Always Authorization, required for iBeacons to work!
if([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}
self.locationManager.delegate = self;
self.locationManager.pausesLocationUpdatesAutomatically = NO;
[self.locationManager startMonitoringForRegion:beaconRegion];
[self.locationManager startRangingBeaconsInRegion:beaconRegion];
[self.locationManager startUpdatingLocation];
}
-(void)sendLocalNotificationWithMessage:(NSString*)message {
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:60];
notification.alertBody = message;
notification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:
(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
NSString *message = #"";
if(beacons.count > 0) {
CLBeacon *nearestBeacon = beacons.firstObject;
if(nearestBeacon.proximity == self.lastProximity ||
nearestBeacon.proximity == CLProximityUnknown) {
return;
}
self.lastProximity = nearestBeacon.proximity;
switch(nearestBeacon.proximity) {
case CLProximityFar:
message = #"You are far away from the beacon";
break;
case CLProximityNear:
message = #"You are near the beacon";
break;
case CLProximityImmediate:
message = #"You are in the immediate proximity of the beacon";
break;
case CLProximityUnknown:
return;
}
} else {
message = #"No beacons are nearby";
}
[self performSelector:#selector(getArray:) withObject:beacons];
NSLog(#"%#", message);
[self sendLocalNotificationWithMessage:message];
}
-(void)locationManager:(CLLocationManager *)manager
didEnterRegion:(CLRegion *)region {
[manager startRangingBeaconsInRegion:(CLBeaconRegion*)region];
[self.locationManager startUpdatingLocation];
NSLog(#"You entered the region.");
[self sendLocalNotificationWithMessage:#"You entered the region."];
}
-(void)locationManager:(CLLocationManager *)manager
didExitRegion:(CLRegion *)region {
[manager stopRangingBeaconsInRegion:(CLBeaconRegion*)region];
[self.locationManager stopUpdatingLocation];
NSLog(#"You exited the region.");
[self sendLocalNotificationWithMessage:#"You exited the region."];
}
#end
this is how i called it in my controller class
.h
#interface HomeViewController : UIViewController<iBeaconDeligate>
.m
iBeaconDeligate *sampleProtocol = [[iBeaconDeligate alloc]init];
[sampleProtocol initiBeaconDeligate];
the problem was methodes that invoke automatically in CLLocationManagerDelegate are not calling in my custom delegate
As sampleProtocol is a local variable inside the method, it will be deallocated when the method exits.
You should create a (strong) #property to store this object to ensure it is retained.
Related
I have a problem with the refresh information on your GPS position.
The function given by me "locationManager" when you click the button does not refresh the information in the "Label".
My code: http://pastebin.com/hWeq6gTS
I am a novice programmer iOS. Please help.
The issue that is not always obvious with the location services is that you have to have one of these two keys in your Info.plist:
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
Then, when starting updating of your position, don't forget to request permissions first (again, depending on your requirements (when in use/always):
[self.locationManager requestWhenInUseAuthorization]
[self.locationManager requestAlwaysAuthorization]
Add these two properties in info.plist
'NSLocationAlwaysUsageDescription' and below property
Create CocoaTouch Class 'LocationManager' inherit from NSObject like below class.
Singleton Location Manager Class .h
#import <Foundation/Foundation.h>
#interface LocationManager : NSObject <CLLocationManagerDelegate>
{
CLLocationManager *locationManager;
}
#property (strong, nonatomic) NSString *longitude;
#property (strong, nonatomic) NSString *latitude;
#property (strong, nonatomic) CLLocation *currentLocation;
+ (instancetype)sharedInstance;
#end
Implementation here .m
#import "LocationManager.h"
#implementation LocationManager
- (id) init
{
self = [super init];
if (self != nil)
{
[self locationManager];
}
return self;
}
+ (instancetype)sharedInstance
{
static LocationManager *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[LocationManager alloc] init];
// Do any other initialisation stuff here
});
return sharedInstance;
}
- (void) locationManager
{
if ([CLLocationManager locationServicesEnabled])
{
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
if ([locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])
{
[locationManager requestWhenInUseAuthorization];
}
[locationManager startUpdatingLocation];
}
else{
UIAlertView *servicesDisabledAlert = [[UIAlertView alloc] initWithTitle:#"Location Services Disabled" message:#"You currently have all location services for this device disabled. If you proceed, you will be showing past informations. To enable, Settings->Location->location services->on" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:#"Continue",nil];
[servicesDisabledAlert show];
[servicesDisabledAlert setDelegate:self];
}
}
- (void)requestWhenInUseAuthorization
{
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
// If the status is denied or only granted for when in use, display an alert
if (status == kCLAuthorizationStatusAuthorizedWhenInUse || status == kCLAuthorizationStatusDenied) {
NSString *title;
title = (status == kCLAuthorizationStatusDenied) ? #"Location services are off" : #"Background location is not enabled";
NSString *message = #"To use background location you must turn on 'Always' in the Location Services Settings";
UIAlertView *alertViews = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Settings", nil];
[alertViews show];
}
// The user has not enabled any location services. Request background authorization.
else if (status == kCLAuthorizationStatusNotDetermined) {
[locationManager requestWhenInUseAuthorization];
}
}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"didFailWithError: %#", error);
UIAlertView *errorAlert = [[UIAlertView alloc]
initWithTitle:#"Error" message:#"Failed to Get Your Location" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
// [errorAlert show];
}
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
switch (status) {
case kCLAuthorizationStatusNotDetermined:
case kCLAuthorizationStatusRestricted:
case kCLAuthorizationStatusDenied:
{
// do some error handling
}
break;
default:{
[locationManager startUpdatingLocation];
}
break;
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
CLLocation *location;
location = [manager location];
CLLocationCoordinate2D coordinate = [location coordinate];
_currentLocation = [[CLLocation alloc] init];
_currentLocation = newLocation;
_longitude = [NSString stringWithFormat:#"%f",coordinate.longitude];
_latitude = [NSString stringWithFormat:#"%f",coordinate.latitude];
// globalObjects.longitude = [NSString stringWithFormat:#"%f",coordinate.longitude];
// globalObjects.latitude = [NSString stringWithFormat:#"%f",coordinate.latitude];
}
#end
import
#import "LocationManager.h"
in your AppDelegate.h
and call that in your AppDelegate.m's like this
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[LocationManager sharedInstance];
return true;
}
Then just get
[LocationManager sharedInstance].longitude or latitude for updated lat long.
Instead of using
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation{
// Location update code
}
use this function to get updated location
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
// Assigning the last object as the current location of the device
CLLocation *currentLocation = [locations lastObject];
}
Sometimes we do face problem when we do not check the authorisation status. You can check this code
// Custom initialization code
CLLocationManager *manager = [[CLLocationManager alloc]init];
manager.delegate = self;
manager.desiredAccuracy = kCLLocationAccuracyBest;
// Setting distance fiter to 10 to get notified only after location change about 10 meter
manager.distanceFilter = kCLDistanceFilterNone;
// Requesting for authorization
if ([manager respondsToSelector:#selector(requestWhenInUseAuthorization)]){
[manager requestWhenInUseAuthorization];
}
// Immediately starts updating the location
[manager startUpdatingLocation];
[manager startUpdatingHeading];
if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
// user activated automatic attraction info mode
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status == kCLAuthorizationStatusDenied ||
status == kCLAuthorizationStatusAuthorizedWhenInUse ||
status == kCLAuthorizationStatusNotDetermined) {
// present an alert indicating location authorization required
// and offer to take the user to Settings for the app via
// UIApplication -openUrl: and UIApplicationOpenSettingsURLString
[manager requestAlwaysAuthorization];
}
[manager requestWhenInUseAuthorization];
else
[manager requestAlwaysAuthorization];
endif
My customer asked if it is possible that when a customer walks by his store he receives an email with todays special prices, even if the app is not running.
My question is: Is it allowed by iOS to call a restservice if the app is wakened by the iBeacon event?
I tried to play a system sound to simulate the restservice call and this is not working. Only when the app is in foreground.
To give you an idea how I designed my Beaconhandler so far, here is my code. Perhaps someone has an idea to improve it:
#import "BeaconHandler.h"
#interface BeaconHandler ()
#property (strong, nonatomic) CLLocationManager *locationManager;
#property CLProximity lastProximity;
#end
#implementation BeaconHandler
-(void) startMonitoring{
if(![self monitoringIsAllowed]){
return;
}
[self initLocationManager];
[self startMonitoringBeacons:[self beaconIDsToMonitor]];
}
-(BOOL) monitoringIsAllowed{
//TODO configuration
return YES;
}
-(NSDictionary*) beaconIDsToMonitor{
//TODO: load beacons from server
return #{#"region1":[[NSUUID alloc] initWithUUIDString:#"B9407F30-F5F8-466E-AFF9-25556B57FE6D"],
#"region2":[[NSUUID alloc] initWithUUIDString:#"B9407F30-F5F8-466E-AFF9-25556B57FE6A"]
};
}
-(void) initLocationManager{
self.locationManager = [[CLLocationManager alloc] init];
if([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}
self.locationManager.delegate = self;
self.locationManager.pausesLocationUpdatesAutomatically = NO;
}
-(void) startMonitoringBeacons:(NSDictionary*)beacons{
for (NSString* beaconIdentifier in beacons.allKeys) {
NSUUID *beaconUUID = beacons[beaconIdentifier];
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:beaconUUID identifier:beaconIdentifier];
beaconRegion.notifyEntryStateOnDisplay = YES;
[self.locationManager startMonitoringForRegion:beaconRegion];
[self.locationManager startRangingBeaconsInRegion:beaconRegion];
}
[self.locationManager startUpdatingLocation];
}
//TODO replace by backend call
-(void)sendLocalNotificationWithMessage:(NSString*)message{
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.alertBody =message;
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}
#pragma CLLocationDelegate
-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
for (CLBeacon *beacon in beacons) {
if(beacon.proximity == self.lastProximity ||
beacon.proximity == CLProximityUnknown) {
return;
}
self.lastProximity = beacon.proximity;
[self sendLocalNotificationWithMessage:[NSString stringWithFormat:#"You are inside region %#", region.identifier]];
}
}
Yes, this is possible. I can confirm I have done this successfully on iOS. A couple of tips to get it running in the background:
Get this working in the foreground first.
You only have 5 seconds of background running time after entering/exiting a region, so make sure your web service returns quickly.
Add NSLog statements to your callbacks to figure out what is and is not completing in the background.
If the above does not help, post your code in the callback.
I'm trying to use core location in iOS 8 simulator, for that I added in my view an object of type 'MapKit View', In tab Atributtes inspector is checked the option show user location, In my project I'm using ARC, below is the structure of my code:
ViewController.h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>
#interface MeuPrimeiroViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate>{
IBOutlet MKMapView *mapView;
}
#property (nonatomic, strong) CLLocationManager *locationManager;
#end
ViewController.m
#synthesize locationManager;
- (void)viewDidLoad {
[super viewDidLoad];
if ([CLLocationManager locationServicesEnabled]) {
NSLog(#"CLLocationManager locationServicesEnabled == ON");
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
// Check for iOS 8 Vs earlier version like iOS7.Otherwise code will
// crash on ios 7
if ([locationManager respondsToSelector:#selector
(requestWhenInUseAuthorization)]) {
[locationManager requestAlwaysAuthorization];
}
[locationManager startUpdatingLocation];
}else{
NSLog(#"CLLocationManager locationServicesEnabled == OFF");
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
NSLog(#"It works this method is called");
}
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
NSLog(#"Error: %#",[error description]);
}
In my info.plist file I add this key (NSLocationAlwaysUsageDescription) with this value (String).
If I go to attributes inspector and enable the checkbox (shows user location) I receive this error message, and core location methods are not called:
Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.
If I disable the checkbox, this message disappear, and core location methods not called again. I try to change the navigation to londom, try to change location to free run but nothing I tried worked, the methods do not continue to be called and never showed an empowering message to use core location. I believe I've already tried everything, anyone have any suggestions or a solution to this problem?
This is what i am doing for my app and working perfectly
- (void)startSignificantChangeUpdates {
if (nil == self.locationManager) {
self.locationManager = [[CLLocationManager alloc] init];
}
self.locationManager.delegate = self;
[self.locationManager startMonitoringSignificantLocationChanges];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations {
CLLocation* location = [locations lastObject];
if (location) {
self.currentLocation = location;
NSString *latitude = [NSString stringWithFormat:#"%f", location.coordinate.latitude];
NSString *longitude = [NSString stringWithFormat:#"%f", location.coordinate.longitude];
self.latLong = [NSString stringWithFormat:#"%#,%#",latitude, longitude];
}
if (!self.geocoder)
self.geocoder = [[CLGeocoder alloc] init];
[self.geocoder reverseGeocodeLocation:location completionHandler:
^(NSArray* placemarks, NSError* error){
if ([placemarks count] > 0) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
if (placemark.postalCode) {
self.currentZipCode = placemark.postalCode;
}
[[NSNotificationCenter defaultCenter] postNotificationName:#"zipCodeFoundNotification" object:self.currentZipCode userInfo:nil];
} else {
[[NSNotificationCenter defaultCenter] postNotificationName:#"zipCodeFoundNotification" object:nil userInfo:nil];
}
}];
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
if (status != kCLAuthorizationStatusAuthorized && status != kCLAuthorizationStatusNotDetermined) {
if (status == kCLAuthorizationStatusDenied){
self.currentZipCode = #"kCLAuthorizationStatusDenied";
} else if (status == kCLAuthorizationStatusRestricted) {
self.currentZipCode = #"kCLAuthorizationStatusRestricted";
}
}
}
FIXED: I was creating my CLLocationManager in the viewDidLoad method, so it was being cleaned by ARC almost immediately. I changed my instance to be a class instance instead of method instance and the problem is solved.
I have a class, an NSObject, which I'm using to control the entering and exiting of beacon regions.
It's implementation is here:
#import "dcBeaconManager.h"
#implementation dcBeaconManager
-(id)init
{
self = [super init];
if (self != nil){}
return self;
}
bool testRanging = true;
bool firstRegionEntered = true;
- (void)initBeaconManager {
NSLog(#"initBeaconManager called");
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
NSUUID *uuid = [[NSUUID alloc]initWithUUIDString:#"B9407F30-F5F8-466E-AFF9-25556B57FE6D"];
self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:#"digiConsRegion"];
[self.locationManager startMonitoringForRegion:self.beaconRegion];
}
- (void)stopBeaconManager {
[self.locationManager stopMonitoringForRegion:self.beaconRegion];
}
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
NSLog(#"Started looking for regions");
[self.locationManager requestStateForRegion:self.beaconRegion];
}
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
NSLog(#"Region discovered");
if (firstRegionEntered) {
NSLog(#"First time in region");
firstRegionEntered = false;
}
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
NSLog(#"Region left");
[self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.alertBody = #"We hope you enjoyed the event, thank you for coming.";
notification.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}
- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
NSLog(#"locationManager initiated");
CLBeacon *beacon = [[CLBeacon alloc] init];
beacon = [beacons lastObject];
//Store some information about this beacon
NSNumber *currentBeaconMajor = beacon.major; //it's major (group) number
NSNumber *currentBeaconMinor = beacon.minor; //it's minor (individual) number
if (([currentBeaconMinor floatValue] == 59204) && ([currentBeaconMajor floatValue] == 33995) && (beacon.proximity == CLProximityNear)) {
NSLog(#"Mint discovered");
[[NSNotificationCenter defaultCenter] postNotificationName:#"didLocateMint" object:nil];
} else if (([currentBeaconMinor floatValue] == 7451) && ([currentBeaconMajor floatValue] == 63627) && (beacon.proximity == CLProximityNear)) {
NSLog(#"Blue discovered");
[[NSNotificationCenter defaultCenter] postNotificationName:#"didLocateBlue" object:nil];
} else if (([currentBeaconMinor floatValue] == 51657) && ([currentBeaconMajor floatValue] == 26976) && (beacon.proximity == CLProximityNear)) {
NSLog(#"Purple discovered");
[[NSNotificationCenter defaultCenter] postNotificationName:#"didLocatePurple" object:nil];
}
}
- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region {
if (testRanging) {
NSLog(#"Testing: forced ranging");
if ([region isEqual:self.beaconRegion] && state == CLRegionStateInside) {
[_locationManager startRangingBeaconsInRegion:(CLBeaconRegion *)region];
}
}
}
#end
Here's the header:
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <CoreBluetooth/CoreBluetooth.h>
#interface dcBeaconManager : NSObject <CLLocationManagerDelegate>
//properties
#property (strong, nonatomic) CLBeaconRegion *beaconRegion; //used to define which beacons we are looking for
#property (strong, nonatomic) CLLocationManager *locationManager; //set up location services and allow beacons to be found
//methods
- (void)initBeaconManager;
- (void)stopBeaconManager;
#end
Now, this code has worked fine before when included in the main view controller, but I'm trying to get better at OOP in Obj-C. The logs show the object is created and the main initBeaconManager is called, but from there is just stops. I cannot figure out why. Any thoughts?
Cheers.
I'm not sure this help but can you replace this line:
self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:#"digiConsRegion"];
with that one:
self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid major:1 minor:2 identifier:#"digiConsRegion"];
self.beaconRegion.notifyOnEntry = entry;
self.beaconRegion.notifyOnExit = exit;
self.beaconRegion.notifyEntryStateOnDisplay = YES;
I believe you need to provide major and minor values for bacon region.
I was creating my CLLocationManager in my viewDidLoad method, and ARC was killing it off almost immediately. Moving it to be a class instance instead of a method instance fixed the problem.
I've heard time and time again that there is always a better pattern than the singleton, but I can't understand how else my application could access the device location without waiting for the GPS to return data (I'm assuming that the location system is only running when explicitly called for, correct me if wrong).
So is there a better pattern for accessing CLLocation data from multiple (unrelated) controllers? Or can I expect the device location to be updating in the background even if I am not accessing it through a CLLocationManager?
Declare a single class . Like the following .
MyLocation.h
#protocol MyCLControllerDelegate <NSObject>
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;
#end
#interface MyLocation : NSObject <CLLocationManagerDelegate> {
CLLocationManager *locationManager;
id delegate;
}
#property (nonatomic, strong) CLLocationManager *locationManager;
#property (nonatomic, strong) id <MyCLControllerDelegate> delegate;
MyLocation.m
#import "MyLocation.h"
#implementation MyLocation
#synthesize locationManager;
#synthesize delegate;
- (id) init {
self = [super init];
if (self != nil) {
if([CLLocationManager locationServicesEnabled]) {
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusRestricted )
{
[self showAlertWithTitle:#"Warning" andWithMessage:#"Determining your current location cannot be performed at this time because location services are enabled but restricted" forTargetView:self];
NSlog(#"Determining your current location cannot be performed at this time because location services are enabled but restricted");
}
else
{
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self; // send loc updates to myself
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.locationManager setDistanceFilter:kThresholdDistance];
[self.locationManager startUpdatingLocation];
NSLog(#"Location sharing set ON!");
}
} else {
[MobileYakHelper showAlertWithTitle:#"Error" andWithMessage:#"Determining your current location cannot be performed at this time because location services are not enabled." forTargetView:self];
NSLog(#"Location sharing set OFF!");
}
}
return self;
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSDictionary *dictValue = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithDouble:newLocation.coordinate.latitude], #"latitude",
[NSNumber numberWithDouble:newLocation.coordinate.longitude], #"longitude",
nil];
[[NSUserDefaults standardUserDefaults] setValue:dictValue forKey:#"MY_LOCATION"];
CLLocationDistance meters = [newLocation distanceFromLocation:oldLocation];
if (meters >= kThresholdDistance ) {
[self.delegate locationUpdate:newLocation];
}
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
[self.delegate locationError:error];
}
#end
To use it in few controller .Adapt delegate in it's .h file and use like as follows :
- (void) initializeLocations
{
MyLocation _myLocation = [[MyLocation alloc] init];
_myLocation.delegate = self;
_myLocation.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
CLLocation * currentLocation = _myLocation.locationManager.location;
// Updating user's current location to server
[self sendUserCurrentCoordinate:currentLocation.coordinate];
// start updating current location
_myLocation.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[_myLocation.locationManager startUpdatingLocation];
[_myLocation.locationManager startUpdatingLocation];
}
- (void)locationUpdate:(CLLocation *)location {
NSLog(#"location %#", location);
}
- (void)locationError:(NSError *)error {
NSLog(#"locationdescription %#", [error description]);
}