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
Related
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.
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!
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.
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
in my app in map view i want to show the nearest 10 stores for the user's current location
but first i have to take current location first then i can show the stores according to user's location
in first start of the app the app ask user if he allow to get current location or not so i must do something like
if user allow
list stores on map
else
go back to main page
now i am using the code below:
mtMap.showsUserLocation=YES;
mymanager=[[CLLocationManager alloc] init];
mymanager.delegate=self;
CLLocation *location = [mymanager location];
CLLocationCoordinate2D coordinate2 = [location coordinate];
NSString *latitude1 = [NSString stringWithFormat:#"%f", coordinate2.latitude];
NSString *longitude1 = [NSString stringWithFormat:#"%f", coordinate2.longitude];
NSString *myURL = [[NSString alloc] initWithFormat:#"http://www.xxxx.com/xxxx/aaaaa.ashx?term=%#,%#",latitude1,longitude1];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:myURL]];
NSInputStream *dataStream=[[NSInputStream alloc]initWithData:data];
[dataStream open];
if(dataStream)
{
NSError *err=nil;
id jsonobject=[NSJSONSerialization JSONObjectWithStream:dataStream options:NSJSONReadingAllowFragments error:&err];
if([jsonobject respondsToSelector:#selector(objectForKey:)])
{
//fill arr
}
}
but it doesn't work for the first time when the user opens the app because of late allowing or getting current location late i can't reach where he is so i can't show nearest places
there can be a problem with my logic. i mean may be i shouldn't do all the job in viewDidload
so could anyone help how can i solve this problem?
Instead of doing it under the viewDidLoad section, what about inserting the code in this method?
// Delegate method from the CLLocationManagerDelegate protocol.
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
CLLocation *location = newLocation;
...
That would make the code run once the user's location was updated.
You could also add an if statement inside the method to check if it is the first time the code has been run and if not to return.