I implement the following code in viewDidLoad
locationManager = [[CLLocationManager alloc] init];
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
and i try to get my location every second via
CLLocation *location = [locationManager location];
CLLocationCoordinate2D coordinate = [location coordinate];
NSLog(#"[%f,%f]",coordinate.latitude,coordinate.longitude);
i try to set the custom location in the iOS simulator, but the location never get updated,
i had also tried it on my iphone device and it seems it only capture the first location and subsequent location is not been updated.
Please advise me on how to resolve it
Try this method to get continuous updated latitude and longitude
(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *location_updated = [locations lastObject];
NSLog(#"updated coordinate are %#",location_updated);
}
Related
I temporarily disabled the location services, and the permissions for my app, so that I could test some code which dealt with the scenario where they're not available. Upon turning them on again, my location now can't be fetched, using this code:
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
[locationManager startUpdatingLocation];
CLLocation *currentLocation = locationManager.location;
[locationManager stopUpdatingLocation];
The locationManager.location is equal to nil after running this code.
I'm running this on an iPad running iOS 6.
Set the delegate for CLLocationManager
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager startUpdatingLocation];
Try the delegates of CLLocationManager.
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
self.currentLocation = newLocation;
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
// The location "unknown" error simply means the manager is currently unable to get the location.
// We can ignore this error for the scenario of getting a single location fix, because we already have a
// timeout that will stop the location manager to save power.
if ([error code] != kCLErrorLocationUnknown) {
[self stopUpdatingLocation:NSLocalizedString(#"Error", #"Error")];
}
}
I am building a rails-backed iphone app that uses AFNetworking to create posts at specific locations. So the post model has lat/lng parameters that should be filled in with the client's current location.
At this point, the posts can be made, but the lat/lng comes up as null.
In my (save:) method I pass a conditional to see if a location was found- this is what is failing i.e. "No Location" is logged.
- (void)save:(id)sender {
[self getLocation];
NSArray *locations;
CLLocation *location = [locations objectAtIndex:0];
Post *post = [[Post alloc] init];
post.content = self.contentTextView.text;
post.photoData = UIImagePNGRepresentation(self.imageView.image);
[self.view endEditing:YES];
ProgressView *progressView = [ProgressView presentInWindow:self.view.window];
if (location) {
[post savePostAtLocation:location withBlock:^(CGFloat progress) {
[progressView setProgress:progress];
} completion:^(BOOL success, NSError *error) {
[progressView dismiss];
if (success) {
[self.navigationController popViewControllerAnimated:YES];
} else {
NSLog(#"ERROR: %#", error);
}
}];
} else {
NSLog(#"No Location");
}
}
I have also attempted to implement a locationManager like so
-(void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations {
[self getLocation];
}
-(CLLocation *) getLocation{
CLLocationManager * locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
self.locationManager.distanceFilter = 80.0f;
[locationManager startUpdatingLocation];
CLLocation * location = [locationManager location];
return location;
}
I think ideally I would implement the savePostAtlocation in the CLLocationManagerDelegate where I could pass in the locations array like this:
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations
{
CLLocation *location = [locations objectAtIndex:0 /* firstObject */];
if (location) {
[Post createPostAtLocation:location...
But I want to have the post created onSave so I am trying to identify the location but running into some problems..
How do I properly get the current location and pass it into the dictionary?
Any advice on this would be greatly appreciated. Thanks!
Looking at your code, I think you have a slight misunderstanding about how CLLocationManager is designed to work. It looks like you are trying to call [self getLocation] from inside locationManager:didUpdateLocations. This is not correct. Try something like this, inside your save method that is called when you press your button (I would remove the code that's currently in there while testing):
CLLocationManager * locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
self.locationManager.distanceFilter = 80.0f;
[locationManager startUpdatingLocation];
Then it will start generating location data. When that happens, the phone will automatically call locationManager:didUpdateLocations very rapidly. Then, in locationManager:didUpdateLocations you could use:
CLLocation * location = [manager location];
NSLog(#"%#", location);
To see your location data in the console.
What I have written here should get the phone generating location data for you. What you say about createPostAtLocation: in locationManager:didUpdateLocations is probably the correct way to go. When you get the location data, call [manager stopUpdatingLocation] to make the phone stop, then post the location data you got back to your server.
I want to find the current location of user based on latitude and longitude. Prevoiusly I have done it using MKReverseGeocoder but as it is depracated in ios5 ,I going with CLGeocoder.But unable to get the current location .
- (void)viewDidLoad
{
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
CLLocation *currentLocation = newLocation;
locationLabelOne=newLocation.coordinate.latitude;
locationLabelTwo=newLocation.coordinate.longitude;
geocoder = [[CLGeocoder alloc] init];
[locationManager stopUpdatingLocation];
[geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {
NSLog(#"Found placemarks: %#, error: %#", placemarks, error);
if (error == nil && [placemarks count] > 0) {
placemark = [placemarks lastObject];
NSString *get = [NSString stringWithFormat:#"%# %#\n%# %#\n%#\n%#",
placemark.subThoroughfare, placemark.thoroughfare,
placemark.postalCode, placemark.locality,
placemark.administrativeArea,
placemark.country];
} else {
NSLog(#"%#", error.debugDescription);
}
} ];
NSLog(#"%#",placemark);
}
When I NSLog placemark it is returning null.Where I m going wrong?
Possible issues:
1) locationManager:didUpdateToLocation:fromLocation is deprecated iOS 6.0 you should use locationManager:didUpdateLocations: instead.
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations
{
currentLocation=[locations lastObject];
// rest code will be same
}
2) Also [locationManager stopUpdatingLocation]; sounds fishy. IMO you should not use that in CLLocationManagerDelegatemethod.
P.S.
i) For more details in Forward/Reverse geocoding you can look into Apple's sample code GeocoderDemo
ii) If you use Google API for Reverse Geocoding it will have all data available it has been for years but CLGeocoder will not have complete data like street name, pin code for countries like India. What happens is, when you do Reverse Geocoding requests, you pass co ordinates to Core Location which connects to web service in background(which developer won't come to know) and returns a user-readable address. So it may be possible this web service may not be able to return data as accurate as GOOGLE API.
I had the same problem, then with some experimentation I solved my problem…
Make sure:
-90 < latitude < 90
-180 < longitude < 180
It doesn't seem to perform a basic mod function. Hope that helps...
Currently I am working in a project , its requirement is to get the current location information specially latitude and longitude value in every 200m interval using wifi network or Cellular network without using gps as it is consuming more battery life.
Is this possible in ios latest version .
If any one having any idea ,please share with me ,
Thank you.
Have a look in to CLLocationManager, That will be able to tell you where the user is located.
.h
#import <CoreLocation/CoreLocation.h>
#property(nonatomic,retain) CLLocationManager *locationManager;
.m
- (void)viewDidLoad
{
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
//let the user know the purpose
locationManager.purpose = #"Enable location services";
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
NSLog(#"User latitude: %f",locationManager.location.coordinate.latitude);
NSLog(#"User longitude: %f",locationManager.location.coordinate.longitude);
[locationManager startUpdatingLocation];
}
It only way to get your location info in every 200m that is CLLocationManager's startUpdatingLocation. But it is comsuming a lot of battery.
But there is a little different way to get your location when it is changed.
CLLocationManager's startMonitoringSignificantLocationChanges.
Here is a Link
The location manager protocol reference
https://developer.apple.com/library/mac/#documentation/CoreLocation/Reference/CLLocationManagerDelegate_Protocol/CLLocationManagerDelegate/CLLocationManagerDelegate.html
1.In Appdelegate
#import <CoreLocation/CoreLocation.h>
In #interface file
CLLocationManager *locationManager;
#property (nonatomic, retain) CLLocationManager *locationManager;
and add protocol CLLocationManagerDelegate protocol.
2.Impliment these functions in .m.
#synthesize locationManager;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.distanceFilter = 1.0;
[self.locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
// Show an alert or otherwise notify the user
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
}
- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error
{
}
Note:If you want to debug first set current location in simulator
At Debug--->Location--->Custom Location.
its requirement is to get the current location information specially latitude and longitude value in every 200m interval using wifi network or Cellular network without using gps as it is consuming more battery life
The documentation for CLLocationManager has this to say about distance and the GPS hardware:
... setting the desired accuracy for location events to one kilometer gives the location manager the flexibility to turn off GPS hardware and rely solely on the WiFi or cell radios.
For less than 200 meters you'll probably need to roll-your-own solution here.
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
[locationManager stopUpdatingLocation];
[locationManager stopMonitoringSignificantLocationChanges];
[self performSelector:#selector(stopUpadateLocation)];
CLLocation *location = [locationManager location];
CLLocationCoordinate2D coord;
coord=[location coordinate];
NSLog(#"coord %f %f", coord.latitude, coord.longitude);
NSString *urlString = [NSString stringWithFormat:#"http://maps.google.com/maps/geo?q=%f,%f&output=json", newLocation.coordinate.latitude, newLocation.coordinate.longitude];
NSURL *url = [NSURL URLWithString:urlString];
NSString *locationString = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
NSDictionary *dic=[locationString JSONValue];
NSLog(#"locationString:%#",locationString );
[strAddr setString:[AppUtility removeNull:[NSString stringWithFormat:#"%#",[[[dic valueForKey:#"Placemark"] objectAtIndex:0] valueForKey:#"address"]]]];
[txtNear setText:strAddr];
}
- (void)startUpdateLocation{
[locationManager startUpdatingLocation];
}
- (void)stopUpadateLocation{
[locationManager stopUpdatingLocation];
[locationManager stopMonitoringSignificantLocationChanges];
}
You have to use the Core Location method startMonitoringSignificantLocationChanges which uses only the wifi or cellular networks!
How to remove cached data which is sent by CLLocationManager and how to increase its accuracy.Every time i launch the app it gives me cached data and updates it after some time.I have seen several threads but i am not able to get a concrete sol .can anybody provide me the code?
I am using the following method to get position data....
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
I have set the delegate and accuracy here.....
- (void)viewDidLoad {
[super viewDidLoad];
bestEffortAtLocation = nil;
latLocationArray = [[NSMutableArray alloc]init];
longLocationArray = [[NSMutableArray alloc]init];
locationManager =[[CLLocationManager alloc]init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
Also can i use CLLocationManager to compute the distance travelled by person?
There doesn't seem to be a way to dump the cached data. The docs recommend using the timestamp property of the CLLocation object to determine how recent the data is, which is what I do.
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
//wait until we get a recent location, no more than 2 minutes old
if([newLocation.timestamp timeIntervalSinceNow] <= (60 * 2)){
DLog(#"New location:\n\tLat: %f\n\tLon: %f", newLocation.coordinate.latitude, newLocation.coordinate.longitude)
//turn off location updates
[self.locManager stopUpdatingLocation];
DLog(#"Stopping Location Updates");
//Do stuff
}
}
In my testing I haven't had to wait more than a second or two before I get new data.
On your second point, you could have a variable that you add to whenever you get a location update. The distance between updates can be pretty easy to get using CLLocation's distanceFromLocation: method.
Instead of set the distanceFilter to kCLDistanceFilterNone
i.e. locationManager.distanceFilter = kCLDistanceFilterNone;
You may give some value to distanceFilter and check
For e.g. locationManager.distanceFilter =0.5f;
And to calculate distance travel you have to implement the didUpdateToLocation: fromLocation:
where you have to find the new latitude and longitude
Finally
CLLocationObject = newLocation;
CLLocationDistance yourdistance = [newLocation getDistanceFrom:CLLocationObject];
NSString *distance = [[NSString alloc]
initWithFormat:#"%gm", yourdistance ];
NSLog(#"you have travel=%#",distance);