I want to get users current location. Here is my code
// In LoginViewController.h
#interface LoginViewController : UIViewController <UserLocationDelegate,UIAlertViewDelegate> {
CLLocation *usersLocation;
}
#property (nonatomic,strong) CLLocation *usersCurrentLocation;
#end
// In LoginViewController.m
#implementation LoginViewController
#synthesize usersCurrentLocation;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.usersCurrentLocation = nil;
[self currentLocationOfUser];
}
-(void)currentLocationOfUser {
UserLocation *userLocation = [[UserLocation alloc]init];//UserLocation];
userLocation.delegate = self;
[userLocation getCurrentLocationOfUser];
}
#pragma mark - User Location Delegate Methods
- (void)locationUpdate:(CLLocation *)location
{
self.usersCurrentLocation = location;
NSLog(#"Latitude:- %.6f",self.usersCurrentLocation.coordinate.latitude);
NSLog(#"Longitude:- %.6f",self.usersCurrentLocation.coordinate.longitude);
}
- (void)locationError:(NSString *)errorMsg
{
[Common showAlertWithTitle:#"Error" andMessage:errorMsg];
}
// In UserLocation.h
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#protocol UserLocationDelegate <NSObject>
#required
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSString *)errorMsg;
#end
#interface UserLocation : NSObject <CLLocationManagerDelegate> {
CLLocationManager *locationManager;
__weak id<UserLocationDelegate>delegate;
}
#property (nonatomic,strong) CLLocationManager *locationManager;
#property (nonatomic,weak) id<UserLocationDelegate>delegate;
-(id)initUserLocation;
-(void)getCurrentLocationOfUser;
#end
// In UserLocation.m
#import "UserLocation.h"
#implementation UserLocation
#synthesize locationManager;
#synthesize delegate;
#synthesize geoCodingDelegate;
-(id)initUserLocation
{
if (self == [super init]) {
self.locationManager = [[CLLocationManager alloc]init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
}
return self;
}
-(void)getCurrentLocationOfUser {
self.locationManager = [[CLLocationManager alloc]init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
if ([CLLocationManager locationServicesEnabled]) {
//[self.locationManager startMonitoringSignificantLocationChanges];
[self performSelector:#selector(startLocationUpdate) withObject:nil afterDelay:2.0];
}
else {
if ([delegate respondsToSelector:#selector(locationError:)]) {
[self.delegate locationError:#"Please Turn On Location Services in Settings To Retrive User's Current Location"];
}
else {
[Common showAlertWithTitle:#"Error" andMessage:#"Please Turn On Location Services in Settings To Retrive User's Current Location"];
}
}
}
-(void)startLocationUpdate
{
[self.locationManager startMonitoringSignificantLocationChanges];
}
#pragma mark CLLocationManagerDelegate
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
if ([delegate respondsToSelector:#selector(locationUpdate:)]) {
[delegate locationUpdate:newLocation];
}
}
-(void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
if ([delegate respondsToSelector:#selector(locationError:)]) {
[delegate locationError:#"Some Error Occured While Retriving Users's Location"];
}
else {
[Common showAlertWithTitle:#"Error" andMessage:#"Some Error Occured While Retriving Users's Location"];
}
}
#end
But it is not returning any location update.
Also its not asking user permission to use location. My app is not listed in Location Services. How can I add my app in Location Serverices ?
What's worong in above code ?
I solved this problem by declaring UserLocation *userLocation in .h & writing property.
Since I am using ARC , its deallocating userLocation so I am not getting location updates.
Related
I am working on an iOS 6.1 iPhone app with ARC enabled which will be using a CLLocationManager to track the devices position.
UPDATE
I have a DestinationViewController which implements the CLLocationManagerDelegate. It creates the CLLocationManager and does the setup. I have imported the CoreLocation framework to my project.
I have tried to debug a lot and can see that the CLLocationManager is created and no errors are present. But the problem is that the [CLLocationManager authorizationStatus] is kCLAuthorizationStatusNotDetermined
both before [self.locationManager startUpdatingLocation]; and also after.
So there is no prompt about asking permission to use location services for this app. Because of that this method is never fired.
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:
(NSArray *)locations
I have also tried to search the web for hours to look for similar examples but with no luck. Code from DestinationViewController is posted below.
Interface
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface DestinationViewController : UIViewController <CLLocationManagerDelegate>
Implementation
#import "DestinationViewController.h"
#interface DestinationViewController ()
#property (strong, nonatomic) CLLocationManager *locationManager;
#end
#implementation DestinationViewController
// Initializer
- (CLLocationManager *)locationManager
{
if (!_locationManager) {
_locationManager = [[CLLocationManager alloc] init];
}
return _locationManager;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self startLocation];
}
- (void)startLocation
{
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.distanceFilter = 1;
NSString *error;
if (![CLLocationManager locationServicesEnabled]) {
error = #"Error message";
}
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status == kCLAuthorizationStatusRestricted ||
status == kCLAuthorizationStatusDenied ||) {
error = #"Error message";
}
if (error) {
NSLog(error);
}
else
{
status = [CLLocationManager authorizationStatus];
self.locationManager.pausesLocationUpdatesAutomatically = NO;
[self.locationManager startUpdatingLocation];
status = [CLLocationManager authorizationStatus];
NSLog(#"CLLocationManager is %#", self.locationManager);
NSLog(#"Location is %#", self.locationManager.location);
[self updateUI];
}
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations
{
CLLocation *recentLocation = [locations lastObject];
NSLog(#"Found location");
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"didFailWithError");
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
NSLog(#"Change in authorization status");
}
Your code should work.
Make sure your application is authorized to use location services.
You can use following method to check authorization status in code
+ (CLAuthorizationStatus)authorizationStatus
Edit
kCLAuthorizationStatusNotDetermined is most likely caused by location services being disabled. You should check location services status first. Code should be like this
if([CLLocationManager locationServicesEnabled]) {
// Location Services Are Enabled
switch([CLLocationManager authorizationStatus]) {
case kCLAuthorizationStatusNotDetermined:
// User has not yet made a choice with regards to this application
break;
case kCLAuthorizationStatusRestricted:
// This application is not authorized to use location services. Due
// to active restrictions on location services, the user cannot change
// this status, and may not have personally denied authorization
break;
case kCLAuthorizationStatusDenied:
// User has explicitly denied authorization for this application, or
// location services are disabled in Settings
break;
case kCLAuthorizationStatusAuthorized:
// User has authorized this application to use location services
break;
}
} else {
// Location Services Disabled
}
I finally solved it! My delegate wasn't set properly.
Instead of doing:
self.locationManager.delegate = self;
I changed it to:
[self.locationManager setDelegate:self];
And now my delegate methods get fired.
Thanks to those who helped!
I am following a tutorial to integrate GPS to my application. I want to display the Latitude and Longitude values in the viewDidLoad method. According to the tutorial they have displayed it from another method. But i need it to be displayed in viewDidLoad. How can i modify the following code to display it in viewDidLoad ?
The HelloThereController.h view controller
#import "MyCLController.h"
#interface HelloThereViewController : UIViewController <MyCLControllerDelegate> {
MyCLController *locationController;
}
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;
#end
The HelloThereController.m view controller
#import "HelloThereViewController.h"
#implementation HelloThereViewController
- (void)viewDidLoad {
locationController = [[MyCLController alloc] init];
locationController.delegate = self;
[locationController.locationManager startUpdatingLocation];
//I need to print the latitude and logitude values here..
}
My MyCLController.h class
#protocol MyCLControllerDelegate
#required
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;
#end
#interface MyCLController : NSObject {
CLLocationManager *locationManager;
id delegate;
}
#property (nonatomic, retain) CLLocationManager *locationManager;
#property (nonatomic, assign) id delegate;
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation;
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error;
#end
My MyCLController.m class
#import "MyCLController.h"
#implementation MyCLController
#synthesize locationManager;
#synthesize delegate;
- (id) init {
self = [super init];
if (self != nil) {
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.delegate = self;
}
return self;
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
[self.delegate locationUpdate:newLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
[self.delegate locationError:error];
}
- (void)dealloc {
[self.locationManager release];
[super dealloc];
}
#end
If this view controller loads as soon as the app loads, you can't.
it takes time for the location manager to get gps updates.
you'll need to display some ui component that lets the user know you're getting the location, such as UIActivityIndicatorView, and setup another method for displaying the coordinates when you get them.
In general you can accelerate the process sacrificing some accuracy setting the desiredAccuracy property. According to the documentation the values are:
kCLLocationAccuracyBestForNavigation
kCLLocationAccuracyBest
kCLLocationAccuracyNearestTenMeters
kCLLocationAccuracyHundredMeters
kCLLocationAccuracyKilometer
kCLLocationAccuracyThreeKilometers
Anyway you are interested in the first location, so still according to the documentation:
When requesting high-accuracy location data, the initial event delivered by the location
service may not have the accuracy you requested. The location service delivers the initial
event as quickly as possible. It then continues to determine the location with the accuracy
you requested and delivers additional events, as necessary, when that data is available.
You can try starting the location manager in the AppDelegate didFinishLaunchingWithOptions to have some more time before the view appears. As said by Frederick Cheung, locationManager.location can be nil, so it's better do the operations in the location manager delegate.
I am using CLLocationManager *locationManager and getting coordinates but these coordinates are not exact as google map coordinates.
iPhone coordinates are the following
<+26.86126232,+75.75962328>+/-100.00m(speed -1.00 mps/course-1.00)
google map coordinates for same device's location place coordinates are following
<+26.860524,+75.761569>
Google map coordinates are right but iPhone coordinates are wrong these are 100 meter away from google map's exact coordinates.
How do I get the exact coordinates.
// MyCLController.h
// mapCurrentLocation
//
// Created by mac on 18/11/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import <Foundation/Foundation.h>
#protocol MyCLControllerDelegate
#required
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;
#end
#interface MyCLController : NSObject<CLLocationManagerDelegate> {
IBOutlet UILabel *locationLabel;
CLLocationManager *locationManager;
id delegate;
}
#property (nonatomic, retain) CLLocationManager *locationManager;
#property (nonatomic, assign) id delegate;
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation;
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error;
#end
//
// MyCLController.m
// mapCurrentLocation
//
// Created by mac on 18/11/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "MyCLController.h"
#implementation MyCLController
#synthesize locationManager;
#synthesize delegate;
- (id) init {
self = [super init];
if (self != nil) {
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.delegate = self; // send loc updates to myself
}
return self;
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
// NSLog(#"Location: %#", [newLocation description]);
[self.delegate locationUpdate:newLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
//NSLog(#"Error: %#", [error description]);
[self.delegate locationError:error];
}
- (void)dealloc {
[self.locationManager release];
[super dealloc];
}
#end
and here i am using this class--
#import "mapCurrentLocationViewController.h"
#implementation mapCurrentLocationViewController
/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
*/
- (void)viewDidLoad {
locationController = [[MyCLController alloc] init];
locationController.delegate = self;
[locationController.locationManager startUpdatingLocation];
}
- (void)locationUpdate:(CLLocation *)location {
locationLabel.text = [location description];
}
- (void)locationError:(NSError *)error {
locationLabel.text = [error description];
}
- (void)dealloc {
[locationController release];
[super dealloc];
}
#end
To get the most accurate possible location measurements, set locationManager.desiredAccuracy = kCLLocationAccuracyBest; before you startUpdatingLocation.
Also, check the timestamp and horizontalAccuracy of the CLLocation objects that get delivered to locationManager:didUpdateToLocation:fromLocation:. If the location measurement seems like it's older or less accurate than you'd like, set a timer and wait for some more location measurements to be delivered. Core Location will often deliver a cached and/or imprecise location quickly, and then follow up with refined location measurements that are more accurate.
I'm implementing a CLLocationManager right as described in several tutorials.
Everything works fine up to the point where the LocationManager receives a second update. Then a memory leak occurs.
Instruments tells me, that the leaked objects are NSCFTimer, GeneralBlock-16 and NSCFSet
Any ideas?
Thanks for any help
[Edit]
After repeatingly starting and stopping the locationManager, the updated seem to come faster. This makes me think that the CLLocationManager initializes a new timer every time a location-update occurs... VERY strange...
And - so you don't need to read my comment - the app crashes after a while
[Edit]
Ok - I don't get it here's some code...
I'm using a separate class for the locationManager, as described here: http://www.vellios.com/2010/08/16/core-location-gps-tutorial/
locationManager.h
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#protocol locationManagerDelegate
#required
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;
#end
#interface locationManager : NSObject <CLLocationManagerDelegate>{
CLLocationManager *myLocationManager;
id delegate;
CLLocation *bestEffortAtLocation;
BOOL outOfRange;
}
#property (nonatomic, retain) CLLocationManager *myLocationManager;
#property (nonatomic, retain) CLLocation *bestEffortAtLocation;
#property (nonatomic, assign) id delegate;
#property (nonatomic, assign) BOOL outOfRange;
#end
locationManager.m
#import "locationManager.h"
#implementation locationManager
#synthesize myLocationManager;
#synthesize delegate;
#synthesize bestEffortAtLocation;
#synthesize outOfRange;
- (id) init {
self = [super init];
NSLog(#"initializing CLLocationManager");
if (self != nil) {
outOfRange = NO;
self.myLocationManager = [[[CLLocationManager alloc] init] autorelease];
self.myLocationManager.delegate = self;
self.myLocationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
[self performSelector:#selector(stopUpdatingLocation:) withObject:#"Timed Out" afterDelay:100.0];
}else{
NSLog(#"Location Manager could not be initialized");
}
return self;
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
if(outOfRange == NO){
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(stopUpdatingLocation:) object:nil];
NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
if (locationAge > 5.0) return;
// test that the horizontal accuracy does not indicate an invalid measurement
if (newLocation.horizontalAccuracy < 0) return;
[self.delegate locationUpdate:newLocation];
}else{
[self.myLocationManager stopUpdatingLocation];
}
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
NSLog(#"error!!!!");
[self.myLocationManager stopUpdatingLocation];
[self.delegate locationError:error];
}
- (void)dealloc {
[myLocationManager release];
[bestEffortAtLocation release];
[super dealloc];
}
#end
then, in the main-class I call:
mainFile.h (exerpt)
#import "locationManager.h"
#interface mainFile : UIViewController <locationManagerDelegate , UIAlertViewDelegate>{
locationManager *locationController;
CLLocation *myLocation;
}
#end
mainFile.m (exerpt)
#import "locationManager.h"
#implementation mainFile
#synthesize locationController;
#synthesize myLocation;
- (void)locationError:(NSError *)error{
// Do alert-Stuff
}
- (void)locationUpdate:(CLLocation *)location {
// Do location-Stuff
}
- (void)viewDidLoad
{
[super viewDidLoad];
locationController = [[[locationManager alloc] init] autorelease];
locationController.delegate = self;
[locationController.myLocationManager startUpdatingLocation];
}
- (void)dealloc {
self.locationController = nil;
[locationController release];
}
#end
It's driving me kinda crazy :)
My advice is to not be obsessed with one-time memory leaks that the iOS itself generates. It does this in many places and the leaks are all pretty harmless.
Ah, a long dead problem, I love them.
locationController is an iVar, not a property, so when you create it in viewDidLoad, assigning it to _locationController doesn't take on ownership.
You've autoreleased the object, so next time around the event loop, the auto-release pool is drained and it is released.
You could fix it by making it a retain property ( which would fit with your locationManager = nil ), or getting rid of the auto-release, and using an explicit [locationManager release] in dealloc.
Try doing a Build and Analyze. I usually find memory leaks and other non-syntax errors that way.
I've been working to iron out memory leaks in my program and I'm down to a few stragglers. The strange thing is that they're coming from when I use CoreLocation to get a gps location. The code is properly returning the location, but it's leaking all over the place: CFHTTPMessage, CFURLConnection, CFURLRequest, CFURLResponse, GeneralBlock-16,-32,-48, HTTPRequest, etc... Could anyone please guide me how to fix this?
Initialization of MyCLController
locationController = [[MyCLController alloc] init];
locationController.delegate = self;
[locationController.locationManager startUpdatingLocation];
Do some things and get a call back through the delegate:
[locationController release];
MyCLController.h:
#import <Foundation/Foundation.h>
#protocol MyCLControllerDelegate
#required
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;
#end
#interface MyCLController : NSObject {
CLLocationManager *locationManager;
id delegate;
}
#property (nonatomic, retain) CLLocationManager *locationManager;
#property (nonatomic, assign) id delegate;
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation;
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error;
#end
MyCLController.m:
#import "MyCLController.h"
#implementation MyCLController
#synthesize locationManager;
#synthesize delegate;
- (id) init {
self = [super init];
if (self != nil) {
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.delegate = self; // send loc updates to myself
}
return self;
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
[locationManager stopUpdatingLocation];
[self.delegate locationUpdate:newLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error {
[self.delegate locationError:error];
}
- (void)dealloc {
[super dealloc];
}
#end
You need to release the LocationManager. Make sure that you set its delegate to NULL prior to releasing. And also, it's not a good idea to just return the first result. Make sure horizontal accuracy is not < 0 and is also below some threshold, like 5000 meters. And to make it more robust, you might want to add a timer to make it stop after a given amount of time, if it couldn't find your location accurately enough.
you never release locationController