Since the new iOS 8 beta release, I have not been able to successfully get a user's location. Prior to the update to iOS 8 I had no issues, but now it always returns 0.000000 as the current latitude and longitude. Is this just a bug in the new release? My code is listed below:
//from the .h file
#interface MasterViewController : PFQueryTableViewController<CLLocationManagerDelegate,UITextFieldDelegate, UISearchBarDelegate, UISearchDisplayDelegate> {
}
#property (nonatomic, strong) CLLocationManager *locationManager;
//from the .m file
#synthesize locationManager = _locationManager;
- (void)viewDidLoad {
[super viewDidLoad];
[self.locationManager startUpdatingLocation];
}
- (CLLocationManager *)locationManager {
if (_locationManager != nil) {
return _locationManager;
}
_locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
return _locationManager;
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error {
}
UPDATE
This question has been answered (Location Services not working in iOS 8). For anyone still struggling with this, to maintain backwards compatibility with iOS 7, I used the code below:
if ([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) { }
As mentioned in your update/comment, iOS8 requires you to use requestAlwaysAuthorization or requestWhenInUseAuthorization as well as a new NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription key in Info.plist
But there is something else which is wrong in your code:
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
It has been deprecated in iOS6 and you should now use this new delegate method instead:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
You can then get the latest location with something like this:
CLLocation *newLocation = [locations lastObject];
Related
I have a problem in converting a CCLocationManager method to a block.
My CLLocationManager method looks like this:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(#"didUpdateToLocation: %#", newLocation);
}
else{NSLog(#"current location is nil");};
}
I am trying to convert this method to a block but having difficulty in trying to do so. Kind of new to objective c and ios development.
what I am doing is something like this:
double (^getSpeed)(*CLLocation, *CLLocation) = ^(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(#"didUpdateToLocation: %#", newLocation);
CLLocation *currentLocation = newLocation;
mSpeed = currentLocation.speed;
}
else{NSLog(#"current location is nil");};
return mSpeed;
};
but it gives me an error saying that it expects an expression in the first line of block. What does it mean?
Any help would be appreciated.
You can try this way,
// 1. Declare methods and blocks in .h file like this
typedef void (^currentLocation)(CLLocation *currentLocation);
// Create property using typedef
#property (strong) currentLocation objBlock;
- (void)updateCurrentLocation:(currentLocation)completionBlock;
// 2. in delegate method be like this
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray<CLLocation *> *)locations {
CLLocation *location = [locations lastObject];
_objBlock(location);
[locManager stopUpdatingLocation];
locManager = nil;
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error {
NSLog(#"%#",[error localizedDescription]);
}
- (void)updateCurrentLocation:(currentLocation)completionBlock {
_objBlock = completionBlock;
}
// 3. Calling would be like this, when ever location get called block will get trigger.
[self updateCurrentLocation:^(CLLocation *currentLocation) {
NSLog(#"%#", currentLocation);
}];
Why I can get the direction but I can't get the latitude and longitude?
Do I need to get user's location information admission and write in my code?
Here's my code
#import "ViewController.h"
#interface ViewController ()<CLLocationManagerDelegate>
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
[self.locationManager startMonitoringSignificantLocationChanges];
[self.locationManager startUpdatingLocation];
[self.locationManager startUpdatingHeading];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
[self.locationManager stopUpdatingLocation];
self.Lat.text = [NSString stringWithFormat:#"%f", manager.location.coordinate.latitude];
NSLog(#"%f",manager.location.coordinate.longitude);
self.Long.text = [NSString stringWithFormat:#"%f", manager.location.coordinate.longitude];
}
-(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {
self.Mag_heading.text = [NSString stringWithFormat:#"%f",newHeading.magneticHeading];
self.True_heading.text = [NSString stringWithFormat:#"%f", newHeading.trueHeading];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
Once configured, the location manager must be "started"
for iOS 8, specific user level permission is required,
"when-in-use" authorization grants access to the user's location
important: be sure to include NSLocationWhenInUseUsageDescription along with its
explanation string in your Info.plist or startUpdatingLocation will not work.
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])
{
[self.locationManager requestWhenInUseAuthorization];
}
you have to replace below code.
Use newLocation instead of manager
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
self.Lat.text = [NSString stringWithFormat:#"%f", newLocation.coordinate.latitude];
NSLog(#"%f",newLocation.coordinate.latitude);
self.Long.text = [NSString stringWithFormat:#"%f", newLocation.coordinate.longitude];
[self.locationManager stopUpdatingLocation];
}
I'am new in Objective-C world. I try developing simple location application on iOS 6.1 on simulator. But when i try simulate location it doesn't work at all. I don't receive any event, but delegate object is registered properly and PositionProvider is startUpdate.
What is wrong?
I have following code:
PositionProvider
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import "LocationListener.h"
#interface PositionProvider : NSObject
{
#public
LocationListener<CLLocationManagerDelegate> *listener;
#protected
CLLocationManager *manager;
}
#pragma mark -
#pragma mark on/off
-(void) startUpdate;
-(void) stopUpdate;
#end
Implementation
#implementation PositionProvider
{
#private
CLLocation *lastLocation;
}
-(void) startUpdate{
manager = [[CLLocationManager alloc] init];
LocationListener *listener2 = [[LocationListener alloc]init];
manager.delegate = listener2;
manager.desiredAccuracy = kCLLocationAccuracyBest;
if(manager == nil)
NSLog(#"Manager is NULL");
if(listener == nil || manager.delegate == nil)
NSLog(#"Listener is NULL");
NSLog(#"startUpdate");
if ([CLLocationManager locationServicesEnabled]) {
NSLog(#"Location Services Enabled");
switch ([CLLocationManager authorizationStatus]) {
case kCLAuthorizationStatusAuthorized:
NSLog(#"We have access to location services");
break;
case kCLAuthorizationStatusDenied:
NSLog(#"Location services denied by user");
break;
case kCLAuthorizationStatusRestricted:
NSLog(#"Parental controls restrict location services");
break;
case kCLAuthorizationStatusNotDetermined:
NSLog(#"Unable to determine, possibly not available");
break;
default:
break;
}
}
else {
NSLog(#"Location Services Are Disabled");
}
[manager startUpdatingHeading];
[manager startUpdatingLocation];
}
-(void) stopUpdate{
}
#end
LocationListener
#interface LocationListener : NSObject<CLLocationManagerDelegate>
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation;
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status;
#end
Implementation
#implementation LocationListener
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
// newLocation.coordinate;
NSLog(#"Logging Location");
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
NSLog(#"Logging Location");
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus) status{
NSLog(#"Status");
}
#end
Have you tried
[manager setDelegate:listener2];
Alternatively, you may have a memory management issue. Try adding the dealloc method with a debugger-breakpoint and see if it gets called before you expected:
- (void)dealloc {
NSLog(#"Dealloc called");
self.locationManager = nil;
}
I have the following code:
- (void) viewWillAppear {
[self startSignificantChangeUpdates];
}
- (void)startSignificantChangeUpdates
{
if ([CLLocationManager locationServicesEnabled])
{
NSLog(#"start significant changes");
if (nil == locationManager)
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager startMonitoringSignificantLocationChanges];
}
}
problem is that the location manage is not calling its delegate function
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
What can I do?
In your .h file:
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController <CLLocationManagerDelegate>
In your .m file:
#implementation ViewController {
// This is a private variable, used within this file only
CLLocationManager *locationManager;
}
-(void)viewDidLoad {
locationManager = [[CLLocationManager alloc] init];
}
-(void)viewWillAppear {
// If the delegate is still not being set, try putting this code into viewDidAppear
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
-(void)locationManger:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(#"didFailWithError: %#", error);
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
NSLog(#"didUpdateToLocation: %#", [locations lastObject]);
CLLocation *currentLocation = [locations lastObject];
[locationManager stopUpdatingLocation];
}
For more information about getting the user's location, look at this guide, which I used to implement location into an app of mine: http://www.appcoda.com/how-to-get-current-location-iphone-user/
How are you testing this? If you are running this in the simulator, you can go to Debug->Location->Freeway Drive. You can put a break point in locationManager:didUpdateToLocation method or even put a log statement to log the current location coordinates. You should see it work.
Please replace this line
[locationManager startMonitoringSignificantLocationChanges];
with this code
[locationController.locationManager startUpdatingLocation];
and then check
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
}
I am developing an app which involves tracking the new location and updates to the server in X mins. I am stopping the location updating when the time diff is equal to or greater than X mins, then sending to the server and then start updating the location if it is less than X mins. But the didUpdateToLocation delegate methos is not called when it is less than X mins.
I am posting my code here:
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
if (theDiff > 10.0f || myDate == nil)
{
[self stopUpdating];
}
else
{
[self.mLocationManager startUpdatingLocation];
}
}
try this.,
//in your .h
CLLocationManager *locationManager;
#property (nonatomic,retain) CLLocationManager *locationManager;
// Then synthesize it in your .m
#synthesize locationManager;
//in your viewDidLoad
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
[locationManager startUpdatingLocation];
This will call the method whwnever you move with your phone. You can check this by changing simulator locatin also.
Hope this helps., Thanks, happy coding.
try this in .m add this method , or if you have any other custom code post it
-(void)LocationWithTime
{
[CLController sharedInstance].locationManager.desiredAccuracy = 100.0;
[CLController sharedInstance].delegate = self;
BOOL locationAccessAllowed = NO ;
if( [CLLocationManager respondsToSelector:#selector(locationServicesEnabled)] )
{
locationAccessAllowed = [CLLocationManager locationServicesEnabled] ;
}
if(locationAccessAllowed == YES)
{
[[CLController sharedInstance].locationManager startUpdatingLocation];
}
}
this is the delegate method i have used -
-(void)newLocationUpdate:(NSString *)latvalue longValue:(NSString*)longvalue Error:(int) errCode
{
DebugLog(#"LatLong values %# %#", [UserContext sharedInstance].strLat, [UserContext sharedInstance].strLong);
self.strLALat = latvalue;
self.strLALong = longvalue;
[[CLController sharedInstance].locationManager stopUpdatingLocation];
[CLController sharedInstance].delegate=nil ;
}
Excerpt from Apple API Documentation,
/*
* locationManager:didUpdateToLocation:fromLocation:
*
* This method is deprecated. If locationManager:didUpdateLocations: is
* implemented, this method will not be called.
*/
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6, __MAC_NA, __IPHONE_2_0, __IPHONE_6_0);
Use the below delegate method instead,
/*
* locationManager:didUpdateLocations:
* locations is an array of CLLocation objects in chronological order.
*/
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_6_0);
This will work once you set the delegate.
Hope this helps.