I am just playing with CLLocation class. i successfully done the below code. When i press a button it displays the location in ALert msg. When i click the same button again the location is displayed wrongly. And also i have noted eveytime i have to go to Setting - Privacy -Location services to enable access always everytime. When ever the app shows the current location correctly the Location access in Setting of iPhone goes to Blank. again i have to set it to Always to run the app . I have not added anything in .plists. I have wrote just the below code. My problem is It is showing correct location only for the first time after setting location accress to Always
-(CLLocationCoordinate2D) getLocation{
CLLocationCoordinate2D coordinate;
if ([CLLocationManager locationServicesEnabled])
{
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager requestWhenInUseAuthorization];
[locationManager startUpdatingLocation];
CLLocation *location = [locationManager location];
coordinate = [location coordinate];
}
return coordinate;
}
- (void)startTimer {
// if ([Run isEqualToString:#"can"]) {
i++;
NSLog(#"the i value %d", i);
Run =#"cant";
CLLocationCoordinate2D coordinate = [self getLocation];
CLGeocoder *ceo = [[CLGeocoder alloc]init];
CLLocation *loc = [[CLLocation alloc]initWithLatitude:coordinate.latitude longitude:coordinate.longitude]; //insert your coordinates
[ceo reverseGeocodeLocation:loc
completionHandler:^(NSArray placemarks, NSError error)
{
CLPlacemark *placemark = [placemarks objectAtIndex:0];
NSDictionary *eventLocation = [NSDictionary dictionaryWithObjectsAndKeys:placemark.name,#"NAME",placemark.subLocality,#"SUBLOCALITY" ,placemark.postalCode,#"POSTALCODE" ,nil];
LocationDetails= [NSMutableDictionary dictionaryWithObjectsAndKeys:eventLocation,#"value", nil];
NSString *name=placemark.name;
NSString *subLocality=placemark.subLocality;
NSString *postalCode=placemark.postalCode;
NSMutableArray *listData;
if (!listData) listData = [[NSMutableArray alloc] init];
[listData addObject:LocationDetails];
NSLog(#"the Location details %#", listData);
NSString *location=[NSString stringWithFormat:#"You are now in %# inside the sublocality of %# and pin code is %#",name,subLocality,postalCode];
UIAlertView *Alert=[[UIAlertView alloc]initWithTitle:#"Location Update" message:location delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[Alert show];
}
];
// }
// contains the code you posted to start the timer
}
- (IBAction)getLocation:(id)sender {
[ self startTimer];
}
Instead of using your getLocation method, do all your CLLocationManager initializations when the class is initialized. In your #interface set a property to hold the user's current location:
#property (nonatomic, strong) CLLocation *currentLocation;
And implement the delegate method -locationManager:didUpdateLocations: like so:
- (void)locationManager:(CLLocationManager*)manager didUpdateLocations:(NSArray*)locations
{
// set the current location. The most recent location is always at the end of the
// if there are multiple locations
_currentLocation = locations[locations.count - 1];
}
Then, instead of CLLocationCoordinate2D coordinate = [self getLocation];, get the location with:
CLLocationCoordinate2D coordinate = _currentLocation.coordinate; // I think that's the right property.
Note: Make sure you class conforms to CLLocationManagerDelegate
Related
I am trying to compose an email with a Google Maps link using Core Location and MessageUI. Presently my code produces this string: https://maps.google.com?saddr=Current+Location&daddr=0.000000,0.000000.
I would like to append the device's longitude and latitude with the URL.
Here is my implementation:
#import "ViewController.h"
#interface ViewController () <CLLocationManagerDelegate>
#end
#implementation ViewController{
NSString *currentLongitude;
NSString *currentLatitude;
NSString *googleMapsURL;
CLLocationManager *locationManager_;
}
- (void)viewDidLoad {
[super viewDidLoad];
locationManager_ = [[CLLocationManager alloc] init];
locationManager_.delegate = self;
locationManager_.distanceFilter = kCLDistanceFilterNone;
locationManager_.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager_ requestAlwaysAuthorization];
[locationManager_ startUpdatingLocation];
}
- (IBAction)composeMailButton:(id)sender {
NSString *bodyHeader = #"Here are you directions:";
NSString *mailBody = [NSString stringWithFormat:#"%#\n%#", bodyHeader, googleMapsURL];
MFMailComposeViewController *emailComposer = [[MFMailComposeViewController alloc] init];
[emailComposer setSubject:#"Google Maps Directions"];
[emailComposer setMessageBody:mailBody isHTML:NO];
[emailComposer setToRecipients:#[#"castro.michael87#gmail.com"]];
[emailComposer setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self presentViewController:emailComposer animated:YES completion:nil];
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
CLLocation *newLocation = [locations lastObject];
NSString *googleMapsURL = [[NSString alloc] initWithFormat:#"https://maps.google.com?saddr=Current+Location&daddr=%1.6f,%1.6f",newLocation.coordinate.latitude, newLocation.coordinate.longitude];
}
I am guessing that I have not correctly implemented the locationManager. Any input is very much appreciated!
First, you need to make use that you added the NSLocationWhenInUseUsageDescription and NSLocationAlwaysUsageDescription in your info.plist file.
Second, your viewController need to implement the <CLLocationManagerDelegate>
#interface ViewController ()<CLLocationManagerDelegate>
Third, setup your locationManager in your viewDidLoad method.
locationManager_ = [[CLLocationManager alloc] init];
locationManager_.delegate = self;
locationManager_.distanceFilter = kCLDistanceFilterNone;
locationManager_.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager_ requestAlwaysAuthorization];
[locationManager_ startUpdatingLocation];
Fourth, implement the -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations method:
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
CLLocation *newLocation = [locations lastObject];
NSString *googleMapsURL = [[NSString alloc] initWithFormat:#"https://maps.google.com?saddr=Current+Location&daddr=%1.6f,%1.6f",newLocation.coordinate.latitude, newLocation.coordinate.longitude];
NSLog(#"%#", googleMapsURL);
}
Finally, if you test in simulator, you need to simulate a location:
Code Snippet: https://gist.github.com/ziyang0621/b1be760596da54873f81
I am using below code to get current lat long in iOS 8.
.h
#interface DirectionViewController : UIViewController<CLLocationManagerDelegate,GMSMapViewDelegate>
{
CLLocationManager *locationManager;
}
#property (nonatomic, retain) CLLocationManager *locationManager;
.m
#synthesize locationManager;
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager startUpdatingLocation];
CLLocation *location = [locationManager location];
// Configure the new event with information from the location
CLLocationCoordinate2D coordinate = [location coordinate];
NSString *latitude = [NSString stringWithFormat:#"%f", coordinate.latitude];
NSString *longitude = [NSString stringWithFormat:#"%f", coordinate.longitude];
NSLog(#"dLatitude : %#", latitude);
NSLog(#"dLongitude : %#",longitude);
But here, I am getting 0.00000 value for both latitude and longitude.
Can anybody help me here. How to get current lat long in iOS 8?
Thanks in advance!
AppDelegte.h
#interface AppDelegate : UIResponder <UIApplicationDelegate,CLLocationManagerDelegate>
{
CLLocation *currentLocation;
}
#property (strong, nonatomic) CLLocationManager *locationManager;
#property (nonatomic, assign) CLLocationCoordinate2D currentLocationCoordinate;
Appdelget.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
locationManager = [[CLLocationManager alloc]init]; // initializing locationManager
locationManager.delegate = self; // we set the delegate of locationManager to self.
locationManager.desiredAccuracy = kCLLocationAccuracyBest; // setting the accuracy
[locationManager startUpdatingLocation];
}
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
CurrentLatitude=newLocation.coordinate.latitude;
CurrentLongitude=newLocation.coordinate.longitude;
NSLog(#"%f",CurrentLatitude);
NSLog(#"%f",CurrentLongitude);
[locationManager stopUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"didFailWithError: %#", error);
UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Failed to Get Your Location" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
}
.Plsit add
NSLocationAlwaysUsageDescription
NSLocationWhenInUseUsageDescription
You're not using the proper method to get your coordinates.
once you call startUpdatingLocation, it calls the location manager methods (that you must implement in order for this to work).
There are two of them, [locationManager:didFailWithError:][1]
and [-locationManager:didUpdateLocations:][2]. You should have warnings asking you to add those methods in your .m, with the proper spelling if you haven't done it yet.
didUpdateLocation is called every X seconds and returns coordinates. You have to build your coordinate strings in this very specific method, where the coordinates are set.
From what I could gather,
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations
Will give you an array of CLLocation objects containing the location data.
This array always contains at least one object representing the current location.
If updates were deferred or if multiple locations arrived before they could be delivered, the array may contain additional entries.
The objects in the array are organized in the order in which they occurred. Therefore, the most recent location update is at the end of the array.
This means you'll have to get the lastObject of that array for the most recent location.
Here is an example i've found on the web, for what the inside of that method could look. :
CLLocation *newLocation = [locations lastObject];
CLLocation *oldLocation;
if (locations.count > 1) {
oldLocation = [locations objectAtIndex:locations.count-2];
} else {
oldLocation = nil;
}
NSLog(#"didUpdateToLocation %# from %#", newLocation, oldLocation);
MKCoordinateRegion userLocation = MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 1500.0, 1500.0);
[regionsMapView setRegion:userLocation animated:YES];
Make sure to ask for the different permissions beforehand, and that you have them.
Also note that this method is only available since iOS5 and is different in the previous versions. Though it is very unlikely that you still support iOS5, I thought I should mention it.
My Xcode app that I am developing needs to get the latitude and longitude of the users iOS device. Although currently all I get is 0 for both values. It does not ask for permission to have the location, and I am on a real device not a simulator.
NSLocationAlwaysUsageDescription is in my info.plist
I have also imported CoreLocation and in my .h file
#interface LocationViewController : UIViewController <CLLocationManagerDelegate>
in my .m file
#interface LocationViewController () <CLLocationManagerDelegate>
Here is my code:
#implementation LocationViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self getCurrentLocation];
}
-(CLLocationCoordinate2D) getLocation{
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager startUpdatingLocation];
CLLocation *location = [locationManager location];
CLLocationCoordinate2D coordinate = [location coordinate];
return coordinate;
}
- (void)getCurrentLocation{
CLLocationCoordinate2D coordinate = [self getLocation];
NSString *latitude = [NSString stringWithFormat:#"%f", coordinate.latitude];
NSString *longitude = [NSString stringWithFormat:#"%f", coordinate.longitude];
NSLog(#"Latitude = %#", latitude);
NSLog(#"Longitude = %#", longitude);
}
Refer this answer. Hope, this helps.
Make this changes :
-(CLLocationCoordinate2D) getLocation{
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager requestWhenInUseAuthorization];
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager startUpdatingLocation];
CLLocation *location = [locationManager location];
CLLocationCoordinate2D coordinate = [location coordinate];
return coordinate;
}
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
NSLog(#"Status : %d", status);
}
Goto Settings > Privacy > Location > Your App > Always
And see how 'Status' value gets changes.
Put below before startUpdatingLocation
#ifdef __IPHONE_8_0
if(IS_OS_8_OR_LATER) {
// Use one or the other, not both. Depending on what you put in info.plist
[self.locationManager requestWhenInUseAuthorization];
}
#endif
[self.locationManager startUpdatingLocation];
Also call [self getCurrentLocation]; in viewDidLoad & viewDidAppear both.
It will work.
Also make sure you have entry for requestWhenInUseAuthorization in info.plist file too.
check this for more info
For learning purposes I'm trying to develop an app which will show directions to a specific point on a MKMapView.
However, the DirectionsResponse gives me the following error everytime, no matter the address:
2013-12-28 17:52:23.100 routingApp[378:70b] ERROR
2013-12-28 17:52:23.102 routingApp[378:70b] Directions Not Available
I only have a View Controller with a map view and the following code:
routingAppViewController.h
#interface routingAppViewController : UIViewController
#property (strong, nonatomic) IBOutlet MKMapView *mapView;
#property (strong, nonatomic) MKPlacemark *destination;
#end
routingAppViewController.m
#import "routingAppViewController.h"
#interface routingAppViewController ()
#end
#implementation routingAppViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *Location = #"385 Mid Avenue Weston";
_mapView.showsUserLocation = YES;
[self getDirections:Location];
}
-(void)getDirections:(NSString *)address{
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:address
completionHandler:^(NSArray* placemarks, NSError* error){
// Check for returned placemarks
if (placemarks && placemarks.count > 0) {
CLPlacemark *topResult = [placemarks objectAtIndex:0];
// Create a MLPlacemark and add it to the map view
MKPlacemark *placemark = [[MKPlacemark alloc] initWithPlacemark:topResult];
[self.mapView addAnnotation:placemark];
_destination = placemark;
}
}];
MKMapItem *mapItem = [[MKMapItem alloc] initWithPlacemark:_destination];
MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];
request.source = [MKMapItem mapItemForCurrentLocation];
request.destination = mapItem;
request.requestsAlternateRoutes = NO;
MKDirections *directions = [[MKDirections alloc] initWithRequest:request];
[directions calculateDirectionsWithCompletionHandler:
^(MKDirectionsResponse *response, NSError *error) {
if (error) {
NSLog(#"ERROR");
NSLog(#"%#",[error localizedDescription]);
} else {
[self showRoute:response];
}
}];
}
-(void)showRoute:(MKDirectionsResponse *)response
{
for (MKRoute *route in response.routes)
{
[_mapView
addOverlay:route.polyline level:MKOverlayLevelAboveRoads];
for (MKRouteStep *step in route.steps)
{
NSLog(#"%#", step.instructions);
}
}
}
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id < MKOverlay >)overlay
{
MKPolylineRenderer *renderer =
[[MKPolylineRenderer alloc] initWithOverlay:overlay];
renderer.strokeColor = [UIColor blueColor];
renderer.lineWidth = 5.0;
return renderer;
}
The error is given in the getDirections method.
I googled it and mostly the error means that the direction service is not available for this country. However i'm using an USA address, so I can't see why it's not working.
The annotation is added correctly and my location is set to "Apple".
Help much appreciated!
The completionHandler block called by geocodeAddressString is asynchronous.
This means that the code that tries to get the directions from the current location to _destination runs immediately after the geocodeAddressString line and executes before _destination is set.
So when mapItem is created, it is using _destination still set to nil (the geocoder block hasn't finished and set _destination yet).
Trying to get directions from the current location to nil results in the get directions error.
The simplest fix is to move the code that gets the directions request inside the completionHandler block of geocodeAddressString (right after _destination is actually set):
[self.mapView addAnnotation:placemark];
_destination = placemark;
//move the code that gets the directions here,
//inside this block...
MKMapItem *mapItem = [[MKMapItem alloc] init...
...
[directions calculateDirections...
}
i'am new to iphone MapView,when user moves the Map i need to get latitude and longitude of the visible region in iphone
You can get the coordinates of the point at the center of the map with the properties of the MKMapView :
centerCoordinate.latitude and centerCoordinate.longitude.
For example :
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(
map.centerCoordinate.latitude, map.centerCoordinate.longitude);
That's theses latitude and longitude you mean by "i need latitude and longitude when user moves map" ?
Hope this helps…
Use the .region property of your MKMapView.
MKMapView *myMapView = [[MKMapView alloc] initWithFrame:...];
MKCoordinateRegion region = myMapView.region;
// Center of the screen as lat/long
// region.center.latitude
// region.center.longitude
// width and height of viewing area as lat/long
// region.span.latitudeDelta
// region.span.longitudeDelta
Max
Add this in your Appdelegate.h
CLLocationManager *locationManager;
and then add these lines in your Appdelegate.m (didFinishLaunchingWithOptions)
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startMonitoringSignificantLocationChanges];
[locationManager startUpdatingLocation];
this will call a method when you move with device,
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *currentLocation = [locations lastObject];
NSString *latitude = [NSString stringWithFormat:#"%g", currentLocation.coordinate.latitude];
NSString *longitude = [NSString stringWithFormat:#"%g", currentLocation.coordinate.longitude];
NSMutableArray *temp = [[NSMutableArray alloc] initWithCapacity:0];
[temp addObject:latitude];
[temp addObject:longitude];
NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
[def setObject:temp forKey:#"CLocation"];
[temp release];
}
Use from this.