The goal I want to achieve:
I want to display the user address in a view. The view is taken care of by a view controller . This VC is using the GeoAPI to get access to the user location. The GeoAPI is wrapped around the LocationManager-Class which in turn is taking care of all the locationmanager stuff. In this location Manager class I would like to reversegeocode as mentioned above.
The geoAPI has some convenience methods that can be used to get the information I want.
GeoAPI:
#import <Foundation/Foundation.h>
#interface MFGeoAPI : NSObject
#property (nonatomic, strong) NSDictionary *userLocationInfoDict;
+ (MFGeoAPI *)sharedInstance;
- (CLLocation *)getCurrentUserLocation;
#end
#interface MFGeoAPI () {
LocationManager *locationManager;
MotionManager *motionManager;
}
#end
#implementation MFGeoAPI
+(MFGeoAPI *)sharedInstance {
static MFGeoAPI *_sharedInstance = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_sharedInstance = [[MFGeoAPI alloc] init];
});
return _sharedInstance;
}
- (id)init {
if (self = [super init]) {
locationManager = [[LocationManager alloc] initLocationManager];
motionManager = [[MotionManager alloc] initMotionManager];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(getUserLocationInformation:) name:#"UserLocationInfo" object:nil];
return self;
}
- (CLLocation *)getCurrentUserLocation {
return [locationManager getCurrentUserLocation];
}
- (void)getUserLocationInformation:(NSNotification *)notification {
NSLog(#"OK");
self.userLocationInfoDict = [[NSDictionary alloc] initWithDictionary:notification.userInfo];
}
#end
Now.. due to the fact of the async character of the reverse geocode function I won't be sure when the dictionary with the user address will be available.
The Location Manager class contains the following:
Location Manager:
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#interface LocationManager : NSObject <CLLocationManagerDelegate>
#property (nonatomic, strong) CLLocationManager *locationManager;
#property (nonatomic, strong) CLLocation *userLocation;
#property (nonatomic, strong) NSDictionary *userLocDict;
- (id)initLocationManager;
- (CLLocation *)getCurrentUserLocation;
#end
#import "LocationManager.h"
#implementation LocationManager
- (id)initLocationManager {
if (self = [super init]) {
if (self.locationManager == nil) {
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
if (![self.locationManager locationServicesEnabled]) {
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 asked to confirm whether location services should be reenabled." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[servicesDisabledAlert show];
}
}
[self startUpdatingLocation];
[self startFetchingCurrentUserLocationInformation];
}
return self;
}
- (void)startUpdatingLocation {
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.headingFilter = kCLHeadingFilterNone;
[self.locationManager startUpdatingHeading];
[self.locationManager startUpdatingLocation];
self.userLocation = self.locationManager.location;
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(#"FAILED");
}
- (CLLocation *)getCurrentUserLocation {
return self.userLocation;
}
- (void)startFetchingCurrentUserLocationInformation {
[self delayedReverseGeocodeLocation];
}
- (void)delayedReverseGeocodeLocation {
[NSObject cancelPreviousPerformRequestsWithTarget:self];
[self reverseGeocodeLocation];
}
- (void)reverseGeocodeLocation {
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:self.userLocation completionHandler:^(NSArray *placemarks, NSError *error) {
NSDictionary *dict = [[placemarks firstObject] addressDictionary];
if (placemarks.count > 0) {
NSDictionary *info = [NSDictionary dictionaryWithObject:dict forKey:#"transferDict"];
[[NSNotificationCenter defaultCenter] postNotificationName:#"UserLocationInfo" object:self userInfo:info];
}
}];
}
In the view Controller I would like to get access to the userLocation Information Dictionary that I am passing through the API
View Controller
- (id)init {
if (self = [super init]) {
self.userLocation = [[MFGeoAPI sharedInstance] getCurrentUserLocation];
NSLog(#"%#", [[MFGeoAPI sharedInstance].userLocationInfoDict description]);
}
return self;
}
But the userlocationInfoDict is empty. I guess this is due to the fact that my function-call "startFetchingCurrentUserLocationInformation" is returning before the async block returns the values I need. Then I thought by taking care of this through NSNotificationCenter I will be informed when the data is available. But now I am stuck:
What do I have to do to get access to the userLocationInformation passed by the GeoAPI to do it in time when the data has arrived?
Any help appreciated!
Thank you
Sebastian
Related
Calling class...
#implementation MenuViewController
- (void)viewDidLoad {
[super viewDidLoad];
FuelSiteLocator *siteLocator = [[FuelSiteLocator alloc]init];
[siteLocator getStations:#"Unleaded Regular"];
...
}
And this is the class that isn't working...
#implementation FuelSiteLocator {
CLLocationManager *locationManager;
}
-(id) initWithSearchType {
locationManager = [CLLocationManager new];
[locationManager setDelegate:self];
return self;
}
-(void) getStations:(NSString *)search {
[self setSearchType:search];
[locationManager startMonitoringSignificantLocationChanges];
}
-(void) locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(#"%#", error.description);
}
-(void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
[self getGasStations:[locations lastObject]];
}
-(void) getGasStations:(CLLocation *) currentLocation {
NSLog(#"Hello Gas Stations..");
}
The delegate methods are not being called and I have no idea why... In FuelSiteLocator.h I'm using the CLLocationManagerDelegate protocol
****Problem Solved*******
ARC is releasing the siteLoactor object after getStations is called. The delegate methods never had a chance
As mentioned earlier in the comments, your init method is not correct.
try:
-(id) initWithSearchType:(NSString *)search {
self = [super init];
if (self) {
self.searchType = search;
self.locationManager = [CLLocationManager new];
self.locationManager.delegate = self;
}
return self;
}
(This assumes the class inherits from NSObject, as I haven't seen the class definition).
I want to receive location updates. I have added a location delegate to the header file but didUpdateToLocation method not fire my code is
#interface FirstViewController : UIViewController <CLLocationManagerDelegate>
{
UILabel *myLabel;
CLLocationManager *manager;
CLGeocoder *geocoder;
CLPlacemark *placemark;
}
-(void) showCurrentLocation;
#end
and .m file like this:
#import "FirstViewController.h"
#interface FirstViewController ()
#end
#implementation FirstViewController
-(id) init
{
self=[super init];
if (self) {
self.view.backgroundColor=[UIColor purpleColor];
self.edgesForExtendedLayout=UIRectEdgeNone;
[self showCurrentLocation];
}
return self;
}
-(void) showCurrentLocation{
manager=[[CLLocationManager alloc] init];
manager.pausesLocationUpdatesAutomatically=NO;
geocoder=[[CLGeocoder alloc] init];
manager.delegate=self;
manager.desiredAccuracy=kCLLocationAccuracyBest;
}
-(void) locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"Error %#",error);
NSLog(#"Faild to get location");
}
-(void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(#"Location %#",newLocation);
CLLocation *currentlocation=newLocation;
if (currentlocation!=nil)
{
myLabel=[[UILabel alloc] initWithFrame:CGRectMake(30, 30, 200, 200)];
[myLabel setText:[NSString stringWithFormat:#"Latit %8f",currentlocation.coordinate.latitude]];
myLabel.textColor=[UIColor whiteColor];
[self.view addSubview:myLabel];
[geocoder reverseGeocodeLocation:currentlocation completionHandler:^(NSArray *placemark1 ,NSError *erroe){
if (erroe==nil && [placemark1 count]>0)
{
NSLog(#"Location");
}
else
{
NSLog(#"error 2 %#",erroe.debugDescription);
}
}];
}
}
You need to start location manager
manager = [CLLocationManager new];
manager.delegate = self;
[manager startUpdatingLocation]; // forgotten in the code above
Also be sure that you setup your scheme properly to simulate location in test mode via Simulator
I am able to obtain latitude and longitude values in one ViewController .Now i want to pass these values to AppDelegate where i can use them.I don't want to use Core Location in AppDelegate..so that approach is not of use.How can i achieve his?
Here is my Appdelegate code -
-(void)updatePresence
{
NSString *string = self.userLocationVC.locationInfo;// lat and long values as string.
NSLog(#"value of string in appDelegate - %#", string); // This shows null.
}
'userLocationVC' is my ViewController where i calculate location values and 'locationInfo' is NSString property of that controller where i store the obtained values.
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(#"didUpdateToLocation: %#", newLocation);
CLLocation *currentLocation = newLocation;
if (currentLocation != nil)
{
longitude = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.longitude];
latitude = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.latitude];
self.locationInfo = [NSString stringWithFormat:#"latitude - %# , longitude - %#",latitude,longitude];
NSLog(#"current location is - %#", locationInfo);
AppDelegate *myappDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[myappDelegate updatePresence];
Use notifications, where you send a notification from the view controller and it is observed by your app delegate. Pass the location string along with the notification.
This has the advantage that if you later decide to move the location data to another model class, then you just need to add an observer there, and stop observing in the app delegate.
If the reason you want to do this is to make use of the background/foreground delegate methods in the app delegate, then consider using the notification equivalents of these in your view controller instead.
There are many ways to do this, but the most simple solution would be to have add an instance variable to your Application Delegate, then in your location ViewController get a reference to your Application Delegate and set the ivar retrospectively.
However I think it's bad practice to use the app delegate in this fashion.
I have only once added an instance variable to the app delegate and that was to store a device ID, when I was implementing push notifications.
Create a LocationManager singleton class to retrieve your location and call it whenever you need
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
static NSString * const LocationManagerDidGetFirstAccurateLocationNotification = #"LocationManagerDidGetFirstAccurateLocationNotification";
#interface LocationManager : CLLocationManager <CLLocationManagerDelegate>
#property (readonly, nonatomic) CLPlacemark * currentPlacemark;
#property (readonly, nonatomic) CLLocation * currentLocation;
#property (readonly, nonatomic) NSNumber * latitude;
#property (readonly, nonatomic) NSNumber * longitude;
+ (LocationManager *)sharedManager;
- (void)start;
- (double)currentDistanceFromLatitude:(NSNumber *)latitude
longitude:(NSNumber *)longitude;
#end
//
// LocationManager.m
// Post
//
// Created by Nicolas Manzini on 26.01.13.
// Copyright (c) 2013 MySo. All rights reserved.
//
#import "LocationManager.h"
#interface LocationManager ()
#property (assign, nonatomic, getter = isWaitingFirstLocation) BOOL waitingFirstLocation;
#property (strong, nonatomic) NSTimer * timer;
#property (assign, nonatomic, getter = isStarted) BOOL started;
- (void)restartLocationUpdates:(NSTimer *)timer;
- (void)addObservers;
- (void)addTimer;
- (void)updatePlacemarkFromLocation:(CLLocation *)location;
#end
#implementation LocationManager
#dynamic latitude;
#dynamic longitude;
+ (LocationManager *)sharedManager
{
static dispatch_once_t pred;
static LocationManager * sharedManager = nil;
dispatch_once(&pred, ^{
sharedManager = [[self alloc] init];
});
return sharedManager;
}
- (void)start
{
if (self.isStarted) {return;}
_currentLocation = nil;
self.desiredAccuracy = kCLLocationAccuracyBest;
self.distanceFilter = kCLDistanceFilterNone;
self.delegate = self;
self.started = YES;
self.waitingFirstLocation = YES;
[self startUpdatingLocation];
[self addObservers];
[self addTimer];
}
- (void)addObservers
{
NSNotificationCenter * center = [NSNotificationCenter defaultCenter];
[center addObserverForName:UIApplicationDidEnterBackgroundNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note)
{
[self stopUpdatingLocation];
[self.timer invalidate];
self.timer = nil;
_currentPlacemark = nil;
_currentLocation = nil;
}];
[center addObserverForName:UIApplicationWillEnterForegroundNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note)
{
self.waitingFirstLocation = YES;
[self startUpdatingLocation];
[self addTimer];
}];
}
- (void)addTimer
{
self.timer =
[NSTimer scheduledTimerWithTimeInterval:300
target:self
selector:#selector(restartLocationUpdates:)
userInfo:nil
repeats:YES];
}
#pragma mark - delegate
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations
{
CLLocation * location = [locations lastObject];
_currentLocation = location;
if (location.horizontalAccuracy < 30.0)
{
[self stopUpdatingLocation];
[self updatePlacemarkFromLocation:location];
}
else if (location.horizontalAccuracy < 100.0 && self.isWaitingFirstLocation)
{
self.waitingFirstLocation = NO;
[[NSNotificationCenter defaultCenter] postNotificationName:LocationManagerDidGetFirstAccurateLocationNotification
object:nil];
[self updatePlacemarkFromLocation:location];
}
}
#pragma mark - timer
- (void)restartLocationUpdates:(NSTimer *)timer
{
[self startUpdatingLocation];
}
#pragma mark - NSNumber Coordinates
- (NSNumber *)latitude
{
return [NSNumber numberWithDouble:self.currentLocation.coordinate.latitude];
}
- (NSNumber *)longitude
{
return [NSNumber numberWithDouble:self.currentLocation.coordinate.longitude];
}
#pragma mark - Distance From location
- (double)currentDistanceFromLatitude:(NSNumber *)latitude
longitude:(NSNumber *)longitude
{
CLLocation * distantLocation =
[[CLLocation alloc] initWithLatitude:[latitude doubleValue]
longitude:[longitude doubleValue]];
double meters =
[self.currentLocation distanceFromLocation:distantLocation];
return meters;
}
#pragma mark - Placemark Lookup
- (void)updatePlacemarkFromLocation:(CLLocation *)location
{
[[[CLGeocoder alloc] init] reverseGeocodeLocation:location
completionHandler:^(NSArray *placemark, NSError *error)
{
if (error)
{
NSLog(#"could not get current geolocation infos %#",error);
}
_currentPlacemark = [placemark firstObject];
}];
}
#pragma mark - dealloc
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#end
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]);
}
So I am new to iOS development, and I am just trying to get a label updated with my current GPS Coordinates. I am not having an issue compiling, but my coordinates are coming up as 0.00000, 0.00000.
Here is the code for my .h file:
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController{
IBOutlet CLLocationManager *locationManager;
IBOutlet UILabel *location;
}
//#property (nonatomic, retain) IBOutlet CLLocationManager *locationManager;
//#property (weak, nonatomic) IBOutlet UILabel *location;
#end
Here is the code for my .m file:
#implementation ViewController
- (void) updateLabel
{
NSObject *latitude = [NSString stringWithFormat:#"%f", locationManager.location.coordinate.latitude];
NSObject *longitude = [NSString stringWithFormat:#"%f", locationManager.location.coordinate.longitude];
location.text = [NSString stringWithFormat: #"%#,%#", latitude, longitude];
}
- (void)viewDidLoad
{
locationManager = [[CLLocationManager alloc] init];
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
[self updateLabel];
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Fixed it:
I wasn't implementing any delegate methods, and I was not implementing [locationManager startUpdatingLocation]. Now I know better.
.h File:
#interface MapViewController : UIViewController <CLLocationManagerDelegate>
#property (nonatomic, retain) IBOutlet CLLocationManager *locationManager;
#property (strong, nonatomic) IBOutlet UILabel *location;
#end
.m File:
- (void) updateCurrentLabel
{
NSObject *latitude = [NSString stringWithFormat:#"%f", locationManager.location.coordinate.latitude];
NSObject *longitude = [NSString stringWithFormat:#"%f", locationManager.location.coordinate.longitude];
self.location.text = [NSString stringWithFormat: #"Current Location: %#,%#", latitude, longitude];
}
- (void)viewDidLoad
{
[self getCurrentLocation];
[super viewDidLoad];
}
-(void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
[self updateCurrentLabel];
}
-(void) getCurrentLocation
{
self.locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager startUpdatingLocation];
}
Thanks for pointing out how nooby I was. Figured it out. Thanks guys!
once try like this,in ViewDidLoad:
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = (id)self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
[locationManager startUpdatingLocation];
[self updateLabel];
Use this Delegate Method otherwise you will get 0 values:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
//No need to do any code...
// NSLog(#"Got location %f,%f", newLocation.coordinate.latitude, newLocation.coordinate.longitude);
}
In Updating Label Method :
- (void) updateLabel
{
//Getting Current Latitude and longitude..
CLLocation *location = [locationManager location];
float longitude=location.coordinate.longitude;
float latitude=location.coordinate.latitude;
NSLog(#"latitude,longitudes are >> %f,%f",latitude,longitude);
locationlabel.text = [NSString stringWithFormat:#"%f,%f",longitude,latitude];
}
Instead of using locationManager.location.coordinate.latitude, keep an instance variable of type CLLocationCoordinate2D. You can call it something like currentLocation. Then when you get a value in the delegate method locationManager:didUpdateLocations:, set the value of currentLocation.
You'll have to call [locationManager startUpdatingLocation] and set its delegate too (as well as implementing that delegate method).
The way you're using the location manager at the moment is wrong and I think you'd be better off following a tutorial to get the basics down.
I find this is fascinating to use location as singleton, and save the values into default user . I am young programmer and am trying to code all in oop. I use this as follow ( this code still need to be refactored and alertUserWithTitle: is a class method of NYMessageToUser to alert user):
//##Header file:
#interface NYLocationManager : NSObject<CLLocationManagerDelegate>
{
CLLocationManager *locationManager;
float lonngitude;
float latitude;
float altitude;
}
#property(nonatomic,retain)CLLocationManager *locationManager;
#property(nonatomic,readwrite)float longitude;
#property(nonatomic,readwrite)float latitude;
#property(nonatomic,readwrite)float altitude;
+(NYLocationManager *) getInstance;
-(void)startUpdatingLocation;
-(void)stopUpdatingLocation;
-(double)getDistanceFromUserLocationToCordinatesLatitude:(float)lat Longitude:(float)lon;
#end
//### implementation file:
#implementation NYLocationManager
#synthesize locationManager;
#synthesize latitude;
#synthesize longitude;
#synthesize altitude;
+ (id)getInstance
{
static NYLocationManager *Instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Instance = [[self alloc] init];
});
[Instance startUpdatingLocation];
return Instance;
}
- (id)init
{
if (self = [super init])
{
latitude =0.0;
longitude =0.0;
altitude =0.0;
if([[NSUserDefaults standardUserDefaults] objectForKey:#"locationLongitude"] != nil)
{
NSUserDefaults *savedLocation=[NSUserDefaults standardUserDefaults];
latitude =[[savedLocation objectForKey:#"locationLatitude"] floatValue];
longitude =[[savedLocation objectForKey:#"locationLongitude"] floatValue];
altitude =[[savedLocation objectForKey:#"locationAltitude"] floatValue];
}
locationManager = [[CLLocationManager alloc] init];
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
locationManager.delegate = self;
if ([CLLocationManager locationServicesEnabled])
{
[locationManager startUpdatingLocation];
} else
{
[NYMessageToUser alertUserWithTitle:#"Location Services is Disabled!!!" withMessage:#"This app is designed to share images with location, Please enable location for this app and relucnh the app"];
}
}
return self;
}
- (void)dealloc
{
// Should never be called, but just here for clarity really.
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *loc =[locations lastObject];
self.longitude =loc.coordinate.longitude;
self.latitude =loc.coordinate.latitude;
self.altitude =loc.altitude;
NSUserDefaults *savedLocation=[NSUserDefaults standardUserDefaults];
[savedLocation setObject: [NSString stringWithFormat:#"%f", self.longitude] forKey:#"locationLongitude"];
[savedLocation setObject: [NSString stringWithFormat:#"%f", self.latitude] forKey:#"locationLatitude"];
[savedLocation setObject: [NSString stringWithFormat:#"%f", self.altitude ] forKey:#"locationAltitude"];
[savedLocation synchronize];
[locationManager stopUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
[locationManager stopUpdatingLocation];
[NYMessageToUser alertUserWithTitle:#"Location Error!!!" withMessage:#"This app is designed to use with valid location, Please enable location for this app and relucnh the app"];
}
-(void)startUpdatingLocation
{
if ([CLLocationManager locationServicesEnabled])
{
[locationManager startUpdatingLocation];
} else
{
[NYMessageToUser alertUserWithTitle:#"Location Services is Disabled!!!" withMessage:#"This app is designed to share images with location, Please enable location for this app and relucnh the app"];
}
}
-(void)stopUpdatingLocation
{
[locationManager stopUpdatingLocation];
}
-(double)getDistanceFromUserLocationToCordinatesLatitude:(float)lat Longitude:(float)lon
{
CLLocation *locA = [[CLLocation alloc] initWithLatitude:self.latitude longitude:self.longitude];
CLLocation *locB = [[CLLocation alloc] initWithLatitude:lat longitude:lon];
CLLocationDistance distance = [locA distanceFromLocation:locB];
return distance;
}
#end
//### How to use
NYLocationManager *loc =[NYLocationManager getInstance];
NSLog(#"longitude: %f, latitude: %f, altitude: %f",loc.longitude,loc.latitude,loc.altitude);