Location services in iOS5.1 not working as it should - ios

I have a simply app written in Objective-C that gets my current position using CLLocationManager, etc. The code works fine on the iPhone 6.1 Simulator, but it doesn't work on my actual iPod touch. The iPod Touch 3rd Gen is running iOS5.1, and it does ask for the user to enable location services, however it does not get updated. I can post code if you ask, but I thought that there would just be a glaring compatibility issue that would be a rather simple fix.
Any help would be appreciated!
Thanks!
~Carpetfizz
ViewController.h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController <CLLocationManagerDelegate>
{
CLLocationManager* locationManager;
}
#property (weak, nonatomic) IBOutlet UILabel *labelLong;
#property (weak, nonatomic) IBOutlet UILabel *labelLat;
-(IBAction)updateLocaitonButtonAction:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize labelLong,labelLat;
- (void)viewDidLoad
{
[super viewDidLoad];
locationManager = [[CLLocationManager alloc]init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *location = [locations lastObject];
NSLog(#"%f,%f",location.coordinate.latitude,location.coordinate.longitude);
self.labelLong.text = [NSString stringWithFormat:#"%f",location.coordinate.longitude];
self.labelLat.text = [NSString stringWithFormat:#"%f",location.coordinate.latitude];
[locationManager stopUpdatingLocation];
}
-(IBAction)updateLocaitonButtonAction:(id)sender
{
[locationManager startUpdatingLocation];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end

Simply use this delegate
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
CLLocation *location = newLocation;
NSLog(#"%f,%f",location.coordinate.latitude,location.coordinate.longitude);
}

Related

How to get CLLocationManager's current coordinate

I have a UIViewController where I want to display a map centered on current position.
AppDelegate's didFinishLaunchingWithOptions method looks like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.locationManager = [[CLLocationManager alloc] init];
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {
[self.locationManager requestAlwaysAuthorization];
}
[self.locationManager startUpdatingLocation];
return YES;
}
My UIViewController.m class looks like this:
#interface GMapViewController ()<CLLocationManagerDelegate>
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
#property (strong, nonatomic) CLLocation *currentLocation;
#end
#implementation GMapViewController
#pragma mark - Lifecycle methods
- (void)viewDidLoad {
[super viewDidLoad];
self.currentLocation = [CLLocation new];
[[[AppDelegate appDelegate] locationManager] setDelegate:self];
MKCoordinateRegion visibleRegion;
visibleRegion.center = self.currentLocation.coordinate;
visibleRegion.span = MKCoordinateSpanMake(200, 200);
[self.mapView setRegion:visibleRegion animated:YES];
}
#pragma mark - CLLocationManagerDelegate's methods
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
self.currentLocation = [locations lastObject];
}
The thing is the CLLocationManager's didUpdateLocations delegate method is called too late as the currentLocation property has no value when the viewDidLoad is called.
How can I get the current coordinate before viewDidLoad being called ?
You need to refresh your map view once the location has been updated; this will take some time.
You also have a potential race condition, because you call startUpdatingLocation in your AppDelegate, but the view controller isn't set as the delegate until viewDidLoad. The delegate will almost certainly be set before the location is updated, but you can't guarantee this.
I would suggest that you move everything into your view controller and if you only want to update the map once, use requestLocation:
#interface GMapViewController ()<CLLocationManagerDelegate>
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
#property (strong, nonatomic) CLLocation *currentLocation;
#property (strong, nonatomic) CLLocationManager *locationManager;
#end
#implementation GMapViewController
#pragma mark - Lifecycle methods
- (void)viewDidLoad {
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc] init];
self.currentLocation = nil;
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {
[self.locationManager requestAlwaysAuthorization];
} else {
[self.locationManager requestLocation];
}
-(void) setMapTo:(CLLocation *)location {
MKCoordinateRegion visibleRegion;
visibleRegion.center =location.coordinate;
visibleRegion.span = MKCoordinateSpanMake(200, 200);
[self.mapView setRegion:visibleRegion animated:YES];
}
#pragma mark - CLLocationManagerDelegate's methods
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
CLLocation *currentLocation = [locations lastObject];
dispatch_async(dispatch_get_main_queue(), ^{
[self setMapTo:currentLocation];
});
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
if (status != kCLAuthorizationStatusRestricted && status != kCLAuthorizationStatusDenied) {
[manager requestLocation];
}
}
If you just want the map to track the user's location continually then you can simply set the map view's userTrackingMode property to MKUserTrackingModeFollow

How to Compare CurrentLocation to GPS Coordinate and Display a Message if Equal?

I'm trying to create an app that ultimately will vibrate at certain locations. I just started learning Objective-C this week, and found this tutorial which seemed useful for initial testing: http://www.appcoda.com/how-to-get-current-location-iphone-user/
Instead of vibrating, I'm testing it so that the label changes at a designated coordinate. However, when I run the app it does not change the labels. In the bottom debug output bar in xCode it displays the coordinates, and they're the same as what I want them to be, but instead of changing the label "For Latitude Value" to "Success" it changes nothing. Here's the current code:
// ViewController.m
#import "ViewController.h"
#import CoreLocation;
#interface ViewController ()<CLLocationManagerDelegate>
#property (strong, nonatomic) CLLocationManager *locationManager;
#property (strong, nonatomic) CLGeocoder *geocoder;
#property (strong, nonatomic) CLPlacemark *placemark;
#end
#implementation ViewController {
CLLocationManager *locationManager;
}
- (void)requestAlwaysAuthorization{
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
locationManager = [[CLLocationManager alloc] init];
if ([locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
[locationManager requestAlwaysAuthorization];
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(#"%#", [locations lastObject]);
}
- (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);
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(#"didUpdateLocations: %#", newLocation);
CLLocation *currentLocation = newLocation;
if ((currentLocation.coordinate.longitude == 51.50998000)&&(currentLocation.coordinate.latitude == -0.13370000)) {
self.longitudeLabel.text = [NSString stringWithFormat:#"success"];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
And here's the .h if that helps:
// ViewController.h
#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioToolbox.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController <CLLocationManagerDelegate>
#property (weak, nonatomic) IBOutlet UILabel *latitudeLabel;
#property (weak, nonatomic) IBOutlet UILabel *longitudeLabel;
#property (weak, nonatomic) IBOutlet UILabel *addressLabel;
- (IBAction)getCurrentLocation:(id)sender;
#end
I've also tried it with:
if (currentLocation != nil) {
longitudeLabel.text = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.longitude];
latitudeLabel.text = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.latitude];
}
like they do in the tutorial where it should change the labels to display the GPS coordinates, but they don't change either. Again, it just shows the GPS coordinates in the debug bar.
Any ideas on why this isn't working? I apologize if this has already been covered somewhere, I've spent a few hours searching for and trying solutions online but since I'm new to this I may not know the right terms to search for. Any advice is greatly appreciated!
I would not recommend comparing two double values for equality. In theory they are never going to be equal. A better approach is to check whether the location is close enough to your reference location. Below an example from my code base. This is from a C file I use with utility functions. Here it handles float values, but you can do the same with double values.
int relativelyClose(CGFloat value, CGFloat reference, CGFloat precision)
{
return fabs(value - reference) / reference < range;
}
int relativelyClosePoints(CGPoint point, CGPoint r, CGFloat precision)
{
CGFloat dx = point.x -r.x;
CGFloat dy = point.y-r.y;
CGFloat distance = sqrt(dx*dx + dy*dy);
CGFloat reflength = sqrt(r.x*r.x + r.y*r.y);
return (distance < reflength * precision);
}
Additionally, to ensure that setting the label value is executed on the main thread, you can wrap those calls like this:
dispatch_async(dispatch_get_main_queue(), ^ {
longitudeLabel.text = ...;
latitudeLabel.text = ....;
});

Map won't update to new location in iOS 7

I'm doing the homework from the Big Nerd Ranch Guide. I can't get my map to show a new location. I know I'm using one deprecated method but I was having a problem using NSArray (the deprecated method is locationManager:didUpdateToLocation:fromLocation). Any pointers would be appreciated.
Here's my code:
WhereamiViewController.h:
// WhereamiViewController.h
// Whereami
//
// Created by Meghan on 2/28/14.
// Copyright (c) 2014 Meghan. All rights reserved.
//
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>
#interface WhereamiViewController : UIViewController <CLLocationManagerDelegate, MKMapViewDelegate, UITextFieldDelegate>
{
CLLocationManager *locationManager;
IBOutlet UITextField *locationTitleField;
IBOutlet UIActivityIndicatorView *activityIndicator;
IBOutlet MKMapView *worldView;
}
- (void)findLocation;
- (void)foundLocation:(CLLocation *)loc;
#end
WhereamiViewController.m:
// WhereamiViewController.m
// Whereami
//
// Created by Meghan on 2/28/14.
// Copyright (c) 2014 Meghan. All rights reserved.
//
#import "WhereamiViewController.h"
#import "BNRMapPoint.h"
#interface WhereamiViewController ()
#end
#implementation WhereamiViewController
- (void)findLocation
{
[locationManager startUpdatingLocation];
[activityIndicator startAnimating];
[locationTitleField setHidden:YES];
}
- (void)foundLocation:(CLLocation *)loc
{
CLLocationCoordinate2D coord = [loc coordinate];
//Create an instance of BNRMapPoint with the current data
BNRMapPoint *mp = [[BNRMapPoint alloc]initWithCoordinate:coord
title:[locationTitleField text]];
//Add it to the map view
[worldView addAnnotation:mp];
//Zoom the region to this location
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(coord, 250, 250);
[worldView setRegion:region animated:YES];
//Reset the UI
[locationTitleField setText:#""];
[activityIndicator stopAnimating];
[locationTitleField setHidden:NO];
[locationManager stopUpdatingLocation];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
//Create location manager object
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
//We want the most accuracy
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
//Tell our manager to start looking for location immediately
[locationManager startUpdatingHeading];
[locationManager setDistanceFilter:50];
}
return self;
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
NSLog(#"%#", newLocation);
//How many seconds ago was this new location created?
NSTimeInterval t = [[newLocation timestamp] timeIntervalSinceNow];
//CLLocationManagers will return the last found location of the
//device first, you don't want that data in this case.
//If this location was made > 3 minutes ago, ignore it
if (t < -180) {
//This is cached data, you don't want it. Keep looking.
return;
}
[self foundLocation:newLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
NSLog(#"Could not find location: %#", error);
}
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
int degrees = (int)locationManager.heading.magneticHeading;
NSLog(#"from delegate method: %i", degrees);
}
- (void)dealloc
{
//Tell loc manager to stop sending messages
[locationManager setDelegate:nil];
}
- (void)viewDidLoad
{
[worldView setShowsUserLocation:YES];
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
CLLocationCoordinate2D loc = [userLocation coordinate];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(loc, 250, 250);
[worldView setRegion:region animated:YES];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
//This method isn't implemented yet - but will be soon.
[self findLocation];
[textField resignFirstResponder];
return YES;
}
#end
BNRMapPoint.h:
// BNRMapPoint.h
// Whereami
//
// Created by Meghan on 3/4/14.
// Copyright (c) 2014 Meghan. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>
#interface BNRMapPoint : NSObject <MKAnnotation>
{
}
//A new designated initializer for instances of BNRMapPoint
- (id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t;
//This is a required property from MKAnnotation
#property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
//This is an optional property from MKAnnotation
#property (nonatomic, copy) NSString *title;
#end
BNRMapPoint.m:
// BNRMapPoint.m
// Whereami
//
// Created by Meghan on 3/4/14.
// Copyright (c) 2014 Meghan. All rights reserved.
//
#import "BNRMapPoint.h"
#implementation BNRMapPoint
- (id)initWithCoordinate:(CLLocationCoordinate2D)c title:(NSString *)t
{
self = [super init];
if (self) {
_coordinate = c;
[self setTitle:t];
}
return self;
}
- (id)init
{
return [self initWithCoordinate:CLLocationCoordinate2DMake(43.07, -89.32)
title:#"Hometown"];
}
#end
In the initWithNibName method, you're not calling startUpdatingLocation on the locationManager (you're only calling startUpdatingHeading).
(You are calling startUpdatingLocation in findLocation but that's only called from textFieldShouldReturn.)
The didUpdateToLocation delegate method is only called if you do startUpdatingLocation.
Also, make sure the initWithNibName method is actually getting called.
Depending on how this view controller is being created, you may need to move that startup code to initWithCoder: or viewDidLoad.
Hey you can get updated location from this method in iOS
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
location_updated = [locations lastObject];
NSLog(#"updated coordinate are %#",location_updated);
}

How to keep update user Location blue point using ios MapKit

I checked many links and googled it a lot. I tried those codes too but didn't succeeded so at last i am posting it here.
can any one help me regarding user location update.
I know how to show user current location it's just a check
showUserLocation.
I know there is location Manage and delegate for location keep updates.
I tried few code in which people are updating the map in location manager update delegate. But it's not working for me.It just show the blue point on user current location but it's not keep updating if i move.
So, can any one guide me from start that what should i do. How to show the User current location keep update on map when ever or where ever user move.
please try using this method
Don't forget to add CLLocationManagerDelegate and MKMapviewDelegate in your header File.
first implement the below line into your reload map method or viewDidload or viewWillappear method:
[mapView setShowsUserLocation:YES]
Than change the below methods like this:
(MKAnnotationView *) mapView:(MKMapView *)mapsView viewForAnnotation:(id <MKAnnotation>) annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
}
You can do it by yourself without using showUserLocation
You should use CLLocationManager to get current location and add it into mapView
Implement MKAnnotation
#interface MyAnnotation : NSObject<MKAnnotation>{
CLLocationCoordinate2D _coordinate;
NSString *_title;
NSString *_subtitle;
}
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate title:(NSString *)title subtitle:(NSString *)subtitle;
#end
#implementation MyAnnotation
- (NSString *)title {return _title;}
- (NSString *)subtitle {return _subtitle;}
- (CLLocationCoordinate2D)coordinate {return _coordinate;}
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate {_coordinate = newCoordinate;}
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate title:(NSString *)title subtitle:(NSString *)subtitle {
if (self = [super init]) {
_title = title.copy;
_subtitle = subtitle.copy;
_coordinate = coordinate;
}
return self;
}
#end
Create 1 UIViewController
#interface MyViewController () <CLLocationManagerDelegate>{
CLLocationManager *locationManager;
MyAnnotation *userAnnotation;
}
#property (strong, nonatomic) MKMapView *mapView;
#end
#implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
self.mapView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
[self.view addSubview:self.mapView];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
#pragma mark - DELEGATE
//for iOS 5
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
// [manager stopUpdatingLocation];
if (newLocation) {
if (!userAnnotation) {
userAnnotation = [[MyAnnotation alloc]
initWithCoordinate:newLocation.coordinate
title:#"I'm here"
subtitle:nil];
[self.mapView addAnnotation:userAnnotation];
} else {
[self.mapView removeAnnotation:userAnnotation];
[userAnnotation setCoordinate:newLocation.coordinate];
[self.mapView addAnnotation:userAnnotation];
}
}
}
//for iOS 6
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
CLLocation *loc = locations.lastObject;
[self locationManager:manager didUpdateToLocation:loc fromLocation:nil];
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error {
//open GPS services please
}
- (void)dealloc {
[locationManager stopUpdatingLocation];
}
#end
Note:
Remember remove old annotation and add it again when receiving new
location
Please use iOS 5 and ARC

startUpdatingLocation not being fired in iOS

I'm trying to write a simple geolocation app that find the users position in iOS. When the user presses a button, the user's position is found and displayed, and should be changing when startUpdatingLocation is fired. But startUpdatingLocation isn't being fired. Here's my code:
In my ViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface CGViewController : UIViewController<CLLocationManagerDelegate>
#property (strong, nonatomic) IBOutlet UITextField *nameField;
- (IBAction)butStart:(id)sender;
#property (strong, nonatomic) IBOutlet MKMapView *map;
#property (strong, nonatomic) CLLocationManager *locationManager;
#property (strong, nonatomic) IBOutlet UILabel *latitude;
#property (strong, nonatomic) IBOutlet UILabel *longitude;
#property (strong, nonatomic) IBOutlet UILabel *altitude;
#end
And in my ViewController.m:
- (IBAction)butStart:(id)sender {
self.locationManager=[[CLLocationManager alloc] init];
if([CLLocationManager locationServicesEnabled]){
self.locationManager.delegate=self;
self.locationManager.distanceFilter=1;
[self.locationManager startUpdatingLocation];
}
}
(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSLog( #"new location = %#", [newLocation description] );
MKCoordinateSpan span;
span.latitudeDelta = 0.2;
span.longitudeDelta = 0.2;
MKCoordinateRegion region;
region.span = span;
region.center = newLocation.coordinate;
map.showsUserLocation = YES;
self.latitude.text = [NSString stringWithFormat:#"%.3f", newLocation.coordinate.latitude];
self.longitude.text = [NSString stringWithFormat:#"%.3f", newLocation.coordinate.longitude];
}
I've tried to leave out unnecessary code, like a map that I have. Every sample I've seen has the locationManager stuff being set in the AppDelegate.h/.m, whereas I'm trying to call it when the user presses a button. I'm not sure why its not being called.
The method which you have used is deprecated in SDK 6. You should use below method instead:
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations;
There are chances that if you are using iOS 6.0 and above the method which you have written may not get called.
I have also implement your code in my project and it is working fine .
-If you run your project in simulator first time then location service allow and disallow message comes and if you allow then this method get called please replace yoyr method with this
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
float currentLangitude = newLocation.coordinate.longitude;
float currentLatitude = newLocation.coordinate.latitude;
NSLog( #"new location lat = %f long = %f", currentLangitude,currentLatitude );
}
thanks.

Resources