Calling location from viewDidAppear method of viewController - iphone

My application gets the user's location in the appDelegate and calls that location in the viewDidAppear method of some viewControllers. My problem is that the first time the viewController's load, there hasn't been enough time to get the user's location.
Here is my AppDelegate:
- (NSString *)getUserCoordinates
{
NSString *userCoordinates = [NSString stringWithFormat:#"latitude: %f longitude: %f",
locationManager.location.coordinate.latitude, locationManager.location.coordinate.longitude];
locationManager = [[CLLocationManager alloc] init];
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
[locationManager startUpdatingLocation];
return userCoordinates;
}
- (NSString *)getUserLatitude
{
NSString *userLatitude = [NSString stringWithFormat:#"%f",
locationManager.location.coordinate.latitude];
return userLatitude;
}
- (NSString *)getUserLongitude
{
NSString *userLongitude = [NSString stringWithFormat:#"%f",
locationManager.location.coordinate.longitude];
return userLongitude;
}
Here is what I am using to call the location from the viewControllers:
- (void) viewDidAppear:(BOOL)animated
{
NSString *userLatitude =[(PDCAppDelegate *)[UIApplication sharedApplication].delegate
getUserLatitude];
NSString *userLongitude =[(PDCAppDelegate *)[UIApplication sharedApplication].delegate
getUserLongitude];
}
Anyone have any ideas on how to fix? Thanks so much!

Try to use global variables here. It will be updated as your location updates and you will have updated location cordinates all time.
-(void)didUpdateLocation // location update method of CLLocation Manager class
{
// assign current ordinates values to global variables.
}

Not sure why you posted the same question two times... but see my answer at your other post,
Pass Coordinates from locationManager in appDelegate to viewController
In short, you need to implement the delegate methods of CoreLocation, as those methods are called when a new location is found. In those delegate methods, fire off an NSNotification (which ViewControllers) subscribe to in order to get the new user's location.

Related

Posting current location to rails from iPhone

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.

User current Location on a mapkit in xcode

I need a good tutorial in which user's current location (latitude,longitude,city,state,country) is found and updated from time to time as the location changes and displayed on the map kit with the blue icon zooming.
I did it by placing an MKMapView on view.xib and it shows current location of user (default on simulator :SanFransisco) with blue dot zooming only for the first time. But when I run the app next time it is not showing any blue dot zooming. Should I write any code? Till now I didn't write any code. Just placed a mapkit with Show UserLocation checked in xib. How can I get a blue dot ?
I also need to find nearby doctors from the userlocation and display in the same map with red coloured markers pointing.
Gone through google but confused a lot. Please suggest to me some good tutorials in this regard.
EDIT:
- (void)viewDidLoad
{
[super viewDidLoad];
self.mapView.delegate = self;
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.mapView setShowsUserLocation:YES];
[locationManager startUpdatingLocation];
[self queryGooglePlaces:#"doctor"];
}
-(void) queryGooglePlaces: (NSString *) googleType {
// https://developers.google.com/maps/documentation/places/#Authentication
NSString *url = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/search/json?location=%f,%f&radius=300&types=doctor&sensor=true&key=%#", coord.latitude, coord.longitude,kGOOGLE_API_KEY];
NSURL *googleRequestURL=[NSURL URLWithString:url];
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL: googleRequestURL];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
//Here I'm getting array data as null because latitude and longitude are passed as 0.000 ..
How can I get both of them on viewDidLoad?
if you want to find the near doctor address you need to use "GOOGLE PLACE API"
//For user current location
CLLocationCoordinate2D location = [[[mapview userLocation] location] coordinate];
NSLog(#"Location found from Map: %f %f",location.latitude,location.longitude);
Check this link its good example of google place api
Add this Delegate method of ccl location manager
.h file
double currentLatitude;
double currentLongitude;
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
currentLatitude = newLocation.coordinate.latitude;
currentLongitude = newLocation.coordinate.longitude;
[self queryGooglePlaces:somestring];
}
-(void) queryGooglePlaces: (NSString *) googleType {
// https://developers.google.com/maps/documentation/places/#Authentication
NSString *url = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/search/json?location=%f,%f&radius=300&types=doctor&sensor=true&key=%#", currentLatitude , currentLongitude,kGOOGLE_API_KEY];
NSURL *googleRequestURL=[NSURL URLWithString:url];
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL: googleRequestURL];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
pass the current latitude and longitude in your -(void) queryGooglePlaces: (NSString *) googleType { } method

Core Location didEnterRegion didn't work

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
works only if the UIView corresponding to class that implement CLLocationManagerDelegate is active.
If I changed the view it wont trigger didEnterRegion. Anyone can help me?
My code look like this
- (void)enableRegionMonitoring {
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
CLLocationCoordinate2D myMonLocation = CLLocationCoordinate2DMake(10.766699790955, 76.650101525879);
CLRegion *myRegion = [[CLRegion alloc]
initCircularRegionWithCenter:myMonLocation
radius:100
identifier:#"MyLoc"];
//NSLog(#"reg=%#",myRegion);
// Start monitoring for our CLRegion using best accuracy
[locationManager startMonitoringForRegion:myRegion
desiredAccuracy:kCLLocationAccuracyBest];
}
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
NSLog(#"Entered Region");
NSDate *nowx=[NSDate date];
UILocalNotification *localNotification=[[UILocalNotification alloc]init];
if (!localNotification)
return;
NSDictionary *data = [NSDictionary dictionaryWithObject:#"qw" forKey:#"mykey"];
[localNotification setUserInfo:data];
[localNotification setFireDate:nowx];
[localNotification setTimeZone:[NSTimeZone defaultTimeZone]];
NSMutableString *message=[[NSMutableString alloc]init];
message = #"Local Not Triggered By didEnterRegion";
[localNotification setAlertBody:[nowx description]];
[localNotification setAlertAction:#"Open App"];
[localNotification setHasAction:YES];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
From looking at your code I guess you are using ARC, depending on your controller/view hierarchy your view and controller might get deallocated when you switch to a different view, when this happens the locationManager will be deallocated too.
Just to move the whole CLLocationManager code to your AppDelegate and let the AppDelegate be the CLLocationManager delegate. Where you are now calling "enableRegionMonitoring" you would call it on your AppDelegate instead. This will stay active even if the ViewController isn't visible anymore.

iphone : using Background location services is stopped after a little time

i'm trying to get a location and compare it with a location online all that happen in background
the method i create is working fine using background location service but after a minute or so the location icon in the status bar is getting disappear and the method is not getting called any longer
here is the code
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
double lat = newLocation.coordinate.latitude;
double lon = newLocation.coordinate.longitude;
NSURL * locationURL = [NSURL URLWithString:[NSString stringWithFormat:#"http://somedomainname.com/iphoneLocation?lat=%f&lon=%f",lat,lon]];
NSData * responseData = [NSData dataWithContentsOfURL:locationURL];
NSString* aStr;
aStr = [[NSString alloc] initWithData:responseData encoding:NSASCIIStringEncoding];
if ([aStr isEqualToString:#"out Of Any Knowen Range"] ){
UILocalNotification *notify =[[UILocalNotification alloc] init];
notify.alertAction = [[NSString alloc] initWithString: #"View"];
notify.fireDate=nil;
notify.alertBody = [NSString stringWithFormat:#"New Data Occured"];
notify.soundName = UILocalNotificationDefaultSoundName;
NSLog(#"Local notification should display");
[[UIApplication sharedApplication] presentLocalNotificationNow:notify];
}
}
and in the viewDid load i'm using something like this
locationManager = [[CLLocationManager alloc] init];
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.delegate = self;
[locationManager startUpdatingLocation];
CLLocation *userLocation = [locationManager location];
so what is the wrong with it
You need to modify your AppName-Info.plist file by adding a key Required background modes with an item with value App registers for location updates. Another thing I think you should do as you connect online and this may not happen very fast, so the operation that you connect online, post the location and wait for response should start in another thread and meanwhile if you have received another location from CLLocationManager and your previous request has not finished yet to skip posting the new location...
I wonder if the Location Manager is getting released somewhere and therefore not sending any more updates.
Have you tried setting the location manager to a retained property in your view controller?
#property (nonatomic, strong) CLLocationManager *locationManager

CLLocationManagerDelegate, when will the method be invoke: locationManager:didUpdateToLocation:fromLocation:

in CLLocationManagerDelegate, when will the method be invoke: locationManager:didUpdateToLocation:fromLocation:
could you explain more detail, if possible could you explain with example? thanks very much
if my current location is changing(eg, I am on a train), does this method be invoked? if yes, how many times or how frequently it is be invoked?
if I stay at one place and not move, does this method be invoked? if yes, how many times or how frequently it is be invoked?
This method is called whenever your iOS device has moved past the distance filter you have set. For example if you set it to
[self.locationManager setDistanceFilter:kCLDistanceFilterNone];
The method will be called every time the device is moved.
A code example of this would be finding the coordinates then assigning those values to labels
- (void)viewDidLoad{
[super viewDidLoad];
altitudeLabel.text = #"0 ft";
ftOrM = YES;
// Note: we are using Core Location directly to get the user location updates.
// We could normally use MKMapView's user location update delegation but this does not work in
// the background. Plus we want "kCLLocationAccuracyBestForNavigation" which gives us a better accuracy.
//
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.delegate = self; // Tells the location manager to send updates to this object
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyBestForNavigation];
[self.locationManager setDistanceFilter:kCLDistanceFilterNone];
[self.locationManager startUpdatingLocation];
}
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation: (CLLocation*)newLocation fromLocation:(CLLocation *)oldLocation {
tLatitude = [NSString stringWithFormat:#"%3.5f", newLocation.coordinate.latitude];
tLongitude = [NSString stringWithFormat:#"%3.5f", newLocation.coordinate.longitude];
/* the following returns 0 */
float distanceMeters;
float distanceFeet;
if (ftOrM == YES) {
distanceMeters = newLocation.altitude;
distanceFeet = distanceMeters * 3.2808399;
tAltitude = [NSString stringWithFormat:#"%.02f ft", distanceFeet];
altitudeLabel.text = tAltitude;
}
else {
tAltitude = [NSString stringWithFormat:#"%.02f m", newLocation.altitude];
NSLog(#"Altitude:");
NSLog(#"%#", tAltitude);
altitudeLabel.text = tAltitude;
NSLog(#"Altitude:");
NSLog(#"%#", tAltitude);
}
//[manager stopUpdatingLocation];
}
For the first one this method will invoked, and the frequency depends on the speed.
And if don't change your location then this method will not invoked.
And how much time your location is changing this method will call.