I am trying to make a simple app the will get the users longitude and latitude
I followed the tutorial here:
http://www.appcoda.com/how-to-get-current-location-iphone-user/
and came with this:
.h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController <CLLocationManagerDelegate>
#property (strong, nonatomic) IBOutlet UILabel *longitudeLabel;
#property (strong, nonatomic) IBOutlet UILabel *latitudeLabel;
- (IBAction)getCurrentLocation:(id)sender;
#end
.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
{
CLLocationManager *locationManager;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
locationManager = [[CLLocationManager alloc] init];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)getCurrentLocation:(id)sender {
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"didFailWithError: %#", error);
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(#"didUpdateToLocation: %#", newLocation);
CLLocation *currentLocation = newLocation;
if (currentLocation != nil) {
_longitudeLabel.text = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.longitude];
_latitudeLabel.text = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.latitude];
}
}
#end
My issue is that "Would like to use your current location" popup.
and none of the delegate methods are being hit, at all. I put a break point at the beginning of each delegate method and nothing. Please help.
Please ensure you have following keys in your info.plist:
NSLocationAlwaysUsageDescription with value I need Location
NSLocationWhenInUseUsageDescription with value I need Location
privacy - location usage description with value I need Location
Ensure the info.plist details as answered earlier and then add the below code during your initialization;
if (IS_OS_8_OR_LATER) {
[locationmanager requestWhenInUseAuthorization];
//or (as per your app requirement)
[locationmanager requestAlwaysAuthorization];
}
Related
I am trying to get the user's current location using the Core Location Framework in Xcode 6.3.1, I did following things:
Added Core Location Framework under Target-> General-> Linked Frameworks & Libraries
My ViewController.h file is as shown below,
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController<CLLocationManagerDelegate>
#property (weak, nonatomic) IBOutlet UILabel *lblLatitude;
#property (weak, nonatomic) IBOutlet UILabel *lblLongitude;
#property (weak, nonatomic) IBOutlet UILabel *lblAddress;
#property (strong, nonatomic) CLLocationManager *locationManager;
#end
My ViewController.m file is as shown below,
- (void)viewDidLoad
{
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
if(IS_OS_8_OR_LATER){
NSUInteger code = [CLLocationManager authorizationStatus];
if (code == kCLAuthorizationStatusNotDetermined && ([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)] || [self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])) {
if([[NSBundle mainBundle] objectForInfoDictionaryKey:#"NSLocationAlwaysUsageDescription"]){
[self.locationManager requestAlwaysAuthorization];
} else if([[NSBundle mainBundle] objectForInfoDictionaryKey:#"NSLocationWhenInUseUsageDescription"]) {
[self.locationManager requestWhenInUseAuthorization];
} else {
NSLog(#"Info.plist does not contain NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription");
}
}
}
[self.locationManager startUpdatingLocation];
}
#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 didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(#"didUpdateToLocation: %#", newLocation);
CLLocation *currentLocation = newLocation;
if (currentLocation != nil) {
lblLatitude.text = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.longitude];
lblLongitude.text = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.latitude];
}
}
#end
I had also added the following keys in my info.plist file
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
Checked everything given here, here, here, here, and a lot more list
So, is anyone having a solution for this issue, kindly help. Have lost my mind searching for this for the whole day.
Yeah! Got the solution, Here is my whole code & things added to make it working. Special thanks to #MBarton for his great help. Also Thanks to # Vinh Nguyen for investing his precious time in solving my issue.
Added Core Location Framework under Target-> General-> Linked Frameworks & Libraries
Added in .plist file
NSLocationAlwaysUsageDescription
See Screenshot:
In my ViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <MapKit/MKAnnotation.h>
// #define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
#interface ViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate>
{
__weak IBOutlet UINavigationItem *navigationItem;
}
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
#property(nonatomic, retain) CLLocationManager *locationManager;
#end
Then in ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize mapView;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self setUpMap];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)setUpMap
{
mapView.delegate = self;
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
#ifdef __IPHONE_8_0
// if(IS_OS_8_OR_LATER) {
if ([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
// Use one or the other, not both. Depending on what you put in info.plist
[self.locationManager requestAlwaysAuthorization];
}
#endif
[self.locationManager startUpdatingLocation];
mapView.showsUserLocation = YES;
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
}
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:YES];
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
NSLog(#"%#", [self deviceLocation]);
//View Area
MKCoordinateRegion region = { { 0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = self.locationManager.location.coordinate.latitude;
region.center.longitude = self.locationManager.location.coordinate.longitude;
region.span.longitudeDelta = 0.005f;
region.span.longitudeDelta = 0.005f;
[mapView setRegion:region animated:YES];
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
}
- (NSString *)deviceLocation {
return [NSString stringWithFormat:#"latitude: %f longitude: %f", self.locationManager.location.coordinate.latitude, self.locationManager.location.coordinate.longitude];
}
Ufff...! Got the solution after fighting with many codes since last 5 days...
I'm creating an app that uses core location and this is my code:
the .h :
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController
<CLLocationManagerDelegate>
#property(strong,nonatomic) CLLocationManager *manager;
#end
the .m :
#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>
#interface ViewController ()
#end
#implementation ViewController
#synthesize manager;
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidLoad
{
[super viewDidLoad];
if (!self.manager)
{
self.manager=[CLLocationManager new];
}
self.manager.delegate = self;
self.manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
[self.manager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation * currentLocation = (CLLocation *)[locations lastObject];
NSLog(#"Location: %#", currentLocation);
if (currentLocation != nil)
{
NSLog([NSString stringWithFormat:#"%.8f", currentLocation.coordinate.latitude]);
NSLog([NSString stringWithFormat:#"%.8f", currentLocation.coordinate.longitude]);
}
}
#end
the problem is didUpdateToLocation is not being called.
I tried putting a breakpoint inside of it and nothing happened.
For iOS location tracking to work correctly, here are the prerequisites, and the order is of importance, too:
Define your class as CLLocationManagerDelegate.
Instantiate CLLocationManager instance.
Set its delegate to self.
Set its various properties (accuracy etc)
Call [CLLocationManagerDelegate startUpdatingLocation] when you intend to.
Listen to location updates within your delegate method didUpdateLocations, implemented within the class designated as CLLocationManagerDelegate.
With your code, here are the things you need to correct:
-(IBAction)submit
{
[self.manager startUpdatingLocation];
}
- (void)viewDidLoad
{
[super viewDidLoad];
if (!self.manager)
{
self.manager=[CLLocationManager new];
}
self.manager.delegate = self;
self.manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
}
In short, before telling it to start updating location, you need to instantiate it and set its properties right. Currently you are doing it the reverse way.
UPDATE
Also, your delegate method didUpdateToLocation is deprecated since iOS 6. You must replace it with newer method, like this:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation * currentLocation = (CLLocation *)[locations lastObject];
NSLog(#"Location: %#", currentLocation);
if (currentLocation != nil)
{
self.latitude.text = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.latitude];
self.longitude.text = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.longitude];
}
}
You need to add these keys to your Info.plist:
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
And also request for the type you want to authorise if iOS8:
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])
{
[self.locationManager requestWhenInUseAuthorization];
}
[self.locationManager startUpdatingLocation];
So the system will display the alert "Allow "app" to access your location...? Allowing will start your location manager and didUpdateLocations will be called.
been having this problem for a few days now and can't seem to find a solution for it. It's probably some very basic stuff but still can't come up with a solution. So I'm trying to have my uilabel update a user speed in a car or on bike. But When the UIlabel update, it doesn't update the correct value. Any help will be appreciated.
Heres my .h file
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface MainViewController : UIViewController <LoginDelegate,WEPopoverParentView,PopoverControllerDelegate,MainMenuDelegate,MKMapViewDelegate,UIActionSheetDelegate,UIAccelerometerDelegate, CLLocationManagerDelegate, NSObject>
{
AppDelegate *appDelegate;
IBOutlet MKMapView *userMap;
CLLocationManager *locationManager;
}
#property (strong, nonatomic) IBOutlet UILabel *speedView;
#property(nonatomic) int speedCount;
#property (nonatomic,retain) CLLocationManager *locationManager;
#property (nonatomic, strong) WEPopoverController *popoverController;
+ (NSString *) speedToMPH: (float) value;
- (IBAction)btnMenuTapped:(id)sender;
#end
and my .h file
#implementation MainViewController
#synthesize speedCount;
#synthesize speedView;
#synthesize popoverController;
#synthesize locationManager;
- (void)locationError:(NSError *)error {
speedView.text = [error description];
}
-(void)viewWillAppear:(BOOL)animated
{
[userMap setRegion:MKCoordinateRegionMakeWithDistance(userMap.userLocation.coordinate, 5, 5) animated:YES];
}
- (void)viewDidLoad
{
[super viewDidLoad];
appDelegate = [[UIApplication sharedApplication] delegate];
locationManager =[[CLLocationManager alloc] init];
// Do any additional setup after loading the view, typically from a nib.
[userMap setCenterCoordinate: userMap.userLocation.coordinate animated: YES];
[self performSelector:#selector(checkForLogin) withObject:nil afterDelay:1];
[self startLocationServices];
// create LM
self.locationManager = [CLLocationManager new];
// set its delegate
[self.locationManager setDelegate:self];
// set configuration
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.locationManager setDistanceFilter:kCLDistanceFilterNone];
// start location services
[self.locationManager startUpdatingLocation];
// create an oldLocation variable if one doesn't exist
}
- (void)startLocationServices
{
// create the Location Manager
if (self.locationManager == nil) {
self.locationManager = [CLLocationManager new];
}
// stop services
[self.locationManager stopUpdatingLocation];
[self.locationManager setDelegate:nil];
self.speedView.text = #"Location Services stopped.";
}
// locationManager didUpdateToLocation FromLocation
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
NSLog(#"%#", newLocation);
self.speedView.text = [NSString stringWithFormat:#"%d %.f ", speedCount, [newLocation speed]];
}
+ (NSString *) speedToMPH: (float) value
{
NSString *speedCount = #"0.0 ";
if (value>0) {
float mile = 1609.344f;
float mph = value / mile * 3600;
speedCount = [NSString stringWithFormat: #"%.f ", mph];
}
return speedCount;
}
CLLocation returns the speed in meters per second. So you will have to convert it to miles per hour by multiplying the value with 2.23694.
self.speedView.text = [NSString stringWithFormat:#"%d %.f ", speedCount, [newLocation speed] * 2.23694];
I'm trying to create a helper class to get the coordinates of the phone in any other class easily. I've followed a tutorial in which the UIViewController implemented the <CLLocationManagerDelegate> and it worked. I tried to do the same in a simple NSObject, but then my delegate was not called anymore.
This is the code I have :
PSCoordinates.h
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#interface PSCoordinates : NSObject <CLLocationManagerDelegate>
#property (nonatomic, retain) CLLocationManager* locationManager;
#end
PSCoordinates.m
#import "PSCoordinates.h"
#implementation PSCoordinates
- (id) init {
self = [super init];
if (self) {
self.locationManager = [[CLLocationManager alloc] init];
if ([CLLocationManager locationServicesEnabled])
{
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.distanceFilter = 100.0f;
NSLog(#"PSCoordinates init");
[self.locationManager startUpdatingLocation];
}
}
return self;
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
NSLog(#"Géolocalisation : %#",[newLocation description]);
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
NSLog(#"Géolocalisation (erreur) : %#",[error description]);
}
#end
I'm calling it by calling
PSCoordinates * coordinates = [[PSCoordinates alloc] init];
when pressing a button. The init is working as I can see the NSLog PSCoordinates init.
I've found other topics of people having the same problem but none of the answer solved it.
Your help would be really appreciated.
Make "PSCoordinates * coordinates" as global in your class. It will work :)
I was trying to implement a separate class for managing my location. I wanted to get my location whenever I click a button.
gpsFilter.h
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#interface gpsFilter : NSObject <CLLocationManagerDelegate>
#property (nonatomic, retain) CLLocationManager *gpsManager;
#property (nonatomic, retain) NSString * latitude;
#property (nonatomic, retain) NSString * longitude;
#end
gpsFilter.m.
#import "gpsFilter.h"
#implementation gpsFilter
- (id) init{
self = [super init];
if(self != nil){
self.gpsManager = [[CLLocationManager alloc] init];
self.gpsManager.delegate = self;
[self.gpsManager startUpdatingLocation];
BOOL enable = [CLLocationManager locationServicesEnabled];
NSLog(#"%#", enable? #"Enabled" : #"Not Enabled");
}
return self;
}
- (void)gpsManager:(CLLocationManager *) manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
NSLog(#"didUpdateToLocation: %#", newLocation);
CLLocation *currentLocation = newLocation;
if(currentLocation != nil){
self.latitude = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.longitude];
self.longitude = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.latitude];
}
}
- (void)gpsManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"didFailWithError: %#", error);
}
#end
I am using a separate class because I wanted to add smoothing filter in the future. I don't get any updates. The NSLog is never triggered. I think some variable is getting autoreleased, but I am not sure, which one.
The viewController code is as follows.
#import "gpstestViewController.h"
#interface gpstestViewController (){
}
#end
#implementation gpstestViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.location = [[gpsFilter alloc] init];
// Do any additional setup after loading the view, typically from a nib.
}
- (IBAction)getloca:(id)sender {
self.latitudeLabel.text = [self.location latitude];
self.longitudeLabel.text = [self.location longitude];
}
- (IBAction)getLocation:(id)sender {
self.latitudeLabel.text = [self.location latitude];
self.longitudeLabel.text = [self.location longitude];
}
#end
I am sorry that I am dumping a lot of code, but I am a newbie to ios programming and I am not able to find what the problem is.
EDIT: The updateLocation delegate method is not being called at all.
The delegate methods must be named locationManager:didUpdateToLocation:fromLocation: and locationManager:didFailWithError:.
You cannot use custom method names like gpsManager:didUpdateToLocation:fromLocation:.
Also note that locationManager:didUpdateToLocation:fromLocation: is deprecated as of iOS 6 and you should use locationManager:didUpdateLocations:.
The signature of your didUpdateToLocation is wrong:
This is my code:
/** Delegate method from the CLLocationManagerDelegate protocol. */
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
// here do
}
Further set the desiredAccuracy to CLLocationAccuracyBest.