Why I am not able to get Latitude and longitude on real device in Objective C - objective-c

I am new in iOS and I am facing problem to get current Latitude and Longitude on the real device where as I am able to get latitude and Longitude on simulator.
My code is like this
if (nil == locationManager)
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
//Configure Accuracy depending on your needs, default is kCLLocationAccuracyBest
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
// Set a movement threshold for new events.
locationManager.distanceFilter = kCLDistanceFilterNone; // meters
[locationManager startUpdatingLocation];
Currentlatitude = locationManager.location.coordinate.latitude;
Currentlongitude = locationManager.location.coordinate.longitude;
NSLog(#"Latitude =%f",Currentlatitude);
NSLog(#"Longitude =%f",Currentlongitude);
CheckString=#"2";
// Your location from latitude and longitude
CLLocation *location = [[CLLocation alloc] initWithLatitude:Currentlatitude longitude:Currentlongitude];
// Call the method to find the address
[self getAddressFromLocation:location completionHandler:^(NSMutableDictionary *d) {
NSLog(#"address informations : %#", d);
// NSLog(#"formatted address : %#", [placemark.addressDictionary valueForKey:#"FormattedAddressLines"]);
NSLog(#"Street : %#", [d valueForKey:#"Street"]);
NSLog(#"ZIP code : %#", [d valueForKey:#"ZIP"]);
NSLog(#"City : %#", [d valueForKey:#"City"]);
CityNameCurrent=[d valueForKey:#"City"];
// etc.
} failureHandler:^(NSError *error) {
NSLog(#"Error : %#", error);
}];
- (void)getAddressFromLocation:(CLLocation *)location completionHandler:(void (^)(NSMutableDictionary *placemark))completionHandler failureHandler:(void (^)(NSError *error))failureHandler
{
NSMutableDictionary *d = [NSMutableDictionary new];
CLGeocoder *geocoder = [CLGeocoder new];
[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
if (failureHandler && (error || placemarks.count == 0)) {
failureHandler(error);
} else {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
if(completionHandler) {
completionHandler(placemark.addressDictionary);
}
}
}];
}
In ViewDidLod()
mapViewMap.delegate=self;
mapViewMap.myLocationEnabled=YES;
locationtbl.hidden=YES;
if (nil == locationManager)
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
//Configure Accuracy depending on your needs, default is kCLLocationAccuracyBest
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
// Set a movement threshold for new events.
locationManager.distanceFilter = kCLDistanceFilterNone; // meters
[locationManager startUpdatingLocation];
Currentlatitude = locationManager.location.coordinate.latitude;
Currentlongitude = locationManager.location.coordinate.longitude;
NSLog(#"Latitude =%f",Currentlatitude);
NSLog(#"Longitude =%f",Currentlongitude);
mapViewMap.settings.myLocationButton = YES;
mapViewMap.settings.scrollGestures = YES;
mapViewMap.settings.zoomGestures = YES;
mapViewMap.settings.tiltGestures=YES;
mapViewMap.settings.rotateGestures=NO;
mapViewMap.settings.compassButton = YES;
I am not getting what I am doing wrong.Please help.Thanks in Advance!

The simulator doesn't have to wait for a fix before generating a location. The device does. You have to implement a delegate for the location manager and wait for the delegate to be called with an update.

You need to implement CLLocationManager delegate method didUpdateLocations, it is where you get location updates.
You can do it like this.
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
// latest location
self.currentLocation = [locations lastObject];
float longitude = self.currentLocation.coordinate.longitude;
float latitude = self.currentLocation.coordinate.latitude;
// Here you can perform operations with your location coordinates
}
You also need to add following entries in your .plist file based on your location need.
NSLocationWhenInUseUsageDescription
or
NSLocationAlwaysUsageDescription
And request the permission for location usage by calling
[locationManager requestWhenInUseAuthorization];
or
[locationManager requestAlwaysAuthorization]
Documentation link Location and Maps Programming Guide

You also need to add one (or both) of the following keys to you plist:
NSLocationWhenInUseUsageDescription
or
NSLocationAlwaysUsageDescription
and call correspondingly either
[self.locationManager requestWhenInUseAuthorization]
or
[self.locationManager requestAlwaysAuthorization]

Related

kindly advice me to display x number of annotation points in mkmap

Good morning, I am very new to objective-c now I am developing my first app. It's a vehicle tracking app. I received the x-number of lat & long from the json service. Now I displayed a single annotation but I need to display all the annotation points which i received from the service here I search for a whole day to find this but am fails to find displaying x-num of annotations. So kindly advice me by using some sample codes. Thanks in Advance... My code is..
- (void)viewDidLoad
{
[super viewDidLoad];
//MAP VIEW WebService
NSString *urlMapString=[NSString stringWithFormat:#"http://www.logix.com/logix_webservice/map.php?format=json&truckno=%#",nam2];
NSURL *urlMap=[NSURL URLWithString:urlMapString];
NSData *dataMap=[NSData dataWithContentsOfURL:urlMap];
NSError *errorMap;
NSDictionary *jsonMap = [NSJSONSerialization JSONObjectWithData:dataMap options:kNilOptions error:&errorMap]; NSArray *resultsMap = [jsonMap valueForKey:#"posts"];
NSArray *resMap = [resultsMap valueForKey:#"post"];
NSArray *latitudeString=[resMap valueForKey:#"latitude"];
if([resMap count]){
NSString *latOrgstring = [latitudeString objectAtIndex:0];
double latitude=[latOrgstring doubleValue];
NSArray *longitudeString=[resMap valueForKey:#"longitude"];
NSString *longOrgstring = [longitudeString objectAtIndex:0];
double longitude=[longOrgstring doubleValue];
NSString *ignation=[[resMap valueForKey:#"ignition"]objectAtIndex:0];
i=[ignation intValue];
//MAP VIEW Point
MKCoordinateRegion myRegion;
//Center
CLLocationCoordinate2D center;
center.latitude=latitude;
center.longitude=longitude;
//Span
MKCoordinateSpan span;
span.latitudeDelta=0.01f;
span.longitudeDelta=0.01f;
myRegion.center=center;
myRegion.span=span;
//Set our mapView
[MapViewC setRegion:myRegion animated:YES];
//Annotation
//1.create coordinate for use with the annotation
CLLocationCoordinate2D wimbLocation;
wimbLocation.latitude=latitude;
wimbLocation.longitude=longitude;
Annotation * myAnnotation= [Annotation alloc];
CLLocation *someLocation=[[CLLocation alloc]initWithLatitude:latitude longitude:longitude];
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:someLocation completionHandler:^(NSArray *placemarks, NSError *error) {
NSDictionary *dictionary = [[placemarks objectAtIndex:0] addressDictionary];
addressOutlet=[dictionary valueForKey:#"Street"];
City=[dictionary valueForKey:#"City"];
State=[dictionary valueForKey:#"State"];
myAnnotation.coordinate=wimbLocation;
if (addressOutlet!=NULL&&City!=NULL)
{
myAnnotation.title=addressOutlet;
myAnnotation.subtitle=[NSString stringWithFormat:#"%#,%#", City, State];
}
else if (addressOutlet==NULL&&City!=NULL)
{
myAnnotation.title=City;
myAnnotation.subtitle=[NSString stringWithFormat:#"%#,%#", City, State];
}
else if (addressOutlet!=NULL&&City==NULL)
{
myAnnotation.title=addressOutlet;
myAnnotation.subtitle=[NSString stringWithFormat:#"%#", State];
}
else if(addressOutlet==NULL&&City==NULL)
{
myAnnotation.title=State;
myAnnotation.subtitle=[NSString stringWithFormat:#"%#",State];
}
[self.MapViewC addAnnotation:myAnnotation];
}];
}
}
Please make an individual class and use by importing .
Now use
-(id)initWithCoordinate:(CLLocationCoordinate2D)c;
and its .m file
-(id)initWithCoordinate:(CLLocationCoordinate2D)c
{
coordinate=c;
}
Now call this class anywhere and call this method and send your location coordinates.
and then add its objects into NSArray.
Now call [YourMapView addAnnotations:arrayOfAnnotations];
You will get it what you want.It works in my case I hope you will find it supportive.
Now add annotations on mapView:
-(MKAnnotationView *) mapView:(MKMapView *)mapV
viewForAnnotation:(id<MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[pinAnnotation class]])
{
static NSString *defaultPinID = #"com.ABC.pin";//Your unique identifier anything
MKAnnotationView *pinView = nil;
if(!pinView)
{
pinView = (MKAnnotationView *)
[self.mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
pinView = [[MKAnnotationView alloc] initWithAnnotation:
annotation reuseIdentifier:defaultPinID] ;
return pinView;
}
static NSString *AnnotationViewID = #"annotationViewID";
MKAnnotationView* pin =
(MKAnnotationView*) [mapV dequeueReusableAnnotationViewWithIdentifier:
AnnotationViewID];
if ( pin == nil ) {
pin = [(MKAnnotationView*) [MKAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier: AnnotationViewID] ;
pin.canShowCallout = YES;
}
else
{
[pin setAnnotation: annotation];
}
((MKUserLocation *)annotation).title = #"You are here";
return pin;
}

Finding place name from google Place search

I want to find the place name from lat and long.I am using google place api.
How can I achieve this
Now I can search for nearby with that lat and long using this
https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=-33.8670522,151.1957362&radius=500&types=food&name=harbour&sensor=false&key=AddYourOwnKeyHere
You can use MKReverseGeoCoder to get the name, district, info, etc. of a given latitude and longtitude. However, notice that it is deprecated.
The ViewController should be the delegate of MKReverseGeocoderDelegate. A sample usage of MKReverseGeoCoder is;
- (void)viewDidLoad {
CLLocationCoordinate2D coordinates;
coordinates.latitude = 33.8670522;
coordinates.longitude = 151.1957362;
CLLocation *location = [[CLLocation alloc] initWithLatitude:coordinates.latitude longitude:coordinates.longitude];
MKReverseGeocoder* rev = [[MKReverseGeocoder alloc] initWithCoordinate:location.coordinate];
rev.delegate = self;
[rev start];
[super viewDidLoad];
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error {
NSLog(#"Error with reverse geo coder.");
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark {
NSLog(#"Geo coder finished successfully");
NSString *administrativeArea = placemark.administrativeArea;
NSString *thoroughfare = placemark.thoroughfare;
NSLog(#"%# %#", administrativeArea, thoroughfare);
}

How do you use Core Location without User sharing/granting permission?

I have implemented core location in my app.
Everything works perfect when user allows sharing the location at start of the app.
But when user does not share his location "South atlantic" is shown in the location field in the app.
What should be done to avoid this and what should be displayed when the user does not share his location.
I am using this code for getting the location:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
[self.window makeKeyAndVisible];
locationManager = [[CLLocationManager alloc] init];
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
CLGeocoder *ceo = [[CLGeocoder alloc]init];
CLLocation *loc = [[CLLocation alloc]initWithLatitude:locationManager.location.coordinate.latitude longitude:locationManager.location.coordinate.longitude]; //insert your coordinates
[ceo reverseGeocodeLocation: loc completionHandler:
^(NSArray *placemarks, NSError *error)
{
CLPlacemark *placemark = [placemarks objectAtIndex:0];
NSLog(#"placemark %#",placemark);
//String to hold address
locatedAt = [[placemark.addressDictionary valueForKey:#"FormattedAddressLines"] componentsJoinedByString:#", "];
NSLog(#"addressDictionary %#", placemark.addressDictionary);
NSLog(#"placemark %#",placemark.region);
NSLog(#"placemark %#",placemark.country); // Give Country Name
NSLog(#"placemark %#",placemark.locality); // Extract the city name
NSLog(#"location %#",placemark.name);
NSLog(#"location %#",placemark.ocean);
NSLog(#"location %#",placemark.postalCode);
NSLog(#"location %#",placemark.subLocality);
NSLog(#"location %#",placemark.location);
//Print the location to console
NSLog(#"I am currently at %#",locatedAt);
}];
return YES;
}
- (NSString *)deviceLocation
{
NSString *theLocation = [NSString stringWithFormat:#"latitude: %f longitude: %f", locationManager.location.coordinate.latitude, locationManager.location.coordinate.longitude];
return theLocation;
}
You can check [CLLocationManager authorizationStatus] to verify that the user has allowed location services using something like
int result = [CLLocationManager authorizationStatus];
It has return values in
typedef enum {
kCLAuthorizationStatusNotDetermined = 0,
kCLAuthorizationStatusRestricted,
kCLAuthorizationStatusDenied,
kCLAuthorizationStatusAuthorized
} CLAuthorizationStatus;
See the Location Awareness Programming Guide for information on how to get the user's location. Bottom line, you have to create the CLLocationManager location manager (like you are), but then start a location service (either the low-power significant-change location service or the standard location service) and wait for the CLLocationManagerDelegate method didUpdateLocations to return a location (or for didFailWithError to report an error, either because the app failed authorization, or because the device couldn't satisfy the location request for some reason). You can't, though, just grab the location from the CLLocationManager. You have to wait for the service to call didUpdateLocations before you reliably start using longitudes and latitudes.
The Location Awareness Programming Guide will walk you through all of this, including some very helpful code samples.

GPS routing (Shortest path) in iPhone using Mapkit and Google map

I am developing on Xcode 4.3.3, iOS 5 and using Mapkit library.
The app should show current location on Google map, get the destination address and finally draw the shortest path between those two points.
I used this tutorial for implementing the app and I have current location now:
http://blog.objectgraph.com/index.php/2009/04/02/iphone-sdk-30-playing-with-map-kit/
I looked for routing but I haven't found any resource.
Please guide me how I can draw the shortest path between the current location and the destination.
Thanks!
You can try this will only work for ios 6.
Class itemClass = [MKMapItem class];
if (itemClass && [itemClass respondsToSelector:#selector(openMapsWithItems:launchOptions:)]) {
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
CLLocation *newLocation = [[CLLocation alloc]initWithLatitude:getLatitude
longitude:getLongitude];
[geocoder reverseGeocodeLocation:newLocation
completionHandler:^(NSArray *placemarks, NSError *error) {
MKPlacemark *placeMark = [[MKPlacemark alloc] initWithPlacemark:[placemarks objectAtIndex:0]];
MKMapItem *mapItem = [[MKMapItem alloc]initWithPlacemark:placeMark];
MKMapItem *mapItem2 = [MKMapItem mapItemForCurrentLocation];
NSArray *mapItems = #[mapItem, mapItem2];
NSDictionary *options = #{
MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving,
MKLaunchOptionsMapTypeKey:
[NSNumber numberWithInteger:MKMapTypeStandard],
MKLaunchOptionsShowsTrafficKey:#YES
};
[MKMapItem openMapsWithItems:mapItems launchOptions:options];
} ];
}
else
{
UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Failed to Get Your Location"delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
}
}
Did you google for map kit and route?
You'd find this: http://inlight.com.au/posts/mapkit which explains how to use Google Maps and decode the response to extract points to get a route.
There's also a commercial kit: http://mtdirectionsk.it/
iOS MapKit does not provide routing information for Apps as a service. Instead, your choices now are either to get routing information from a third-party mechanism, or to build the routes yourself (which, if you don't have the underlying street data is basically impossible).
You might look at CloudMade as an alternative map system if you need to provide routing information in your own App, or consider just calling Maps to route to a location if you want to take advantage of Apple's Map for navigation.
If you want to call out to the Map App for navigation, you basically need to open a URL with the source and destination location. Here's an example:
CLLocationManager *manager = [[[CLLocationManager alloc] init] autorelease];
CLLocationCoordinate2D currentLocation = [manager location].coordinate;
NSString *from = [NSString stringWithFormat: #"%f,%f",
currentLocation.latitude, currentLocation.longitude];
// used to be able to (3.2 iPad) "Current+Location", now we have to send: lat,long
NSString *encodedAddress = [address stringByAddingPercentEscapesUsingEncoding:
NSUTF8StringEncoding];
NSString *url = [NSString stringWithFormat:
#"http://maps.google.com/maps?saddr=%#&daddr=%#", from, encodedAddress];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];
Below ans work for all ios:
NSString *deviceVersion = [[UIDevice currentDevice] systemVersion];
NSLog(#"My Device version is :%# ",deviceVersion);
//********* For ios 6 supporting devices *********
if ([deviceVersion isEqualToString:#"6.0"])
{
Class itemClass = [MKMapItem class];
if (itemClass && [itemClass respondsToSelector:#selector(openMapsWithItems:launchOptions:)]) {
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
CLLocation *newLocation = [[CLLocation alloc]initWithLatitude:getLatitude
longitude:getLongitude];
[geocoder reverseGeocodeLocation:newLocation
completionHandler:^(NSArray *placemarks, NSError *error) {
MKPlacemark *placeMark = [[MKPlacemark alloc] initWithPlacemark:[placemarks objectAtIndex:0]];
MKMapItem *mapItem = [[MKMapItem alloc]initWithPlacemark:placeMark];
MKMapItem *mapItem2 = [MKMapItem mapItemForCurrentLocation];
NSArray *mapItems = #[mapItem, mapItem2];
NSDictionary *options = #{
MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving,
MKLaunchOptionsMapTypeKey:
[NSNumber numberWithInteger:MKMapTypeStandard],
MKLaunchOptionsShowsTrafficKey:#YES
};
[MKMapItem openMapsWithItems:mapItems launchOptions:options];
} ];
}
else
{
UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Failed to Get Your Location"delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
}
}
//********* For other ios supporting devices *********
else {
MKCoordinateRegion region = { {0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = getLatitude;
region.center.longitude = getLongitude;
MKCoordinateRegion currentRegion = { {0.0, 0.0 }, { 0.0, 0.0 } };
currentRegion.center.latitude = currentLatitude;
currentRegion.center.longitude = currentLongitude;
region.span.longitudeDelta = 4.0f;
region.span.latitudeDelta = 4.0f;
currentRegion.span.longitudeDelta = 4.0f;
currentRegion.span.latitudeDelta = 4.0f;
CLLocationCoordinate2D start = { currentRegion.center.latitude, currentRegion.center.longitude };
CLLocationCoordinate2D destination = { region.center.latitude, region.center.longitude };
NSString *googleMapsURLString = [NSString stringWithFormat:#"http://maps.google.com/?saddr=%1.6f,%1.6f&daddr=%1.6f,%1.6f",start.latitude, start.longitude, destination.latitude, destination.longitude];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:googleMapsURLString]];
}
}

Issue forward-geocoding multiple addresses

I am connecting to a remote web service which basically returns an XML back. I am then parsing that XML into a Property object (think real state sort of thing)
But now, the web service returns a postal code for each property alone. It does not provide a coordinate which is what I need to place an annotation in the map. I am able to geocode an address provided a postal code. However, my problem is it is not allowing me to do multiple requests
Here's my code
- (void)processProperties:(Property *)property {
[geocoder geocodeAddressString:property.postalCode
completionHandler:^(NSArray* placemarks, NSError* error){
placemark = [placemarks lastObject];
for (CLPlacemark* aPlacemark in placemarks)
{
[sublet setLatitude:aPlacemark.location.coordinate.latitude];
[sublet setLongitude:aPlacemark.location.coordinate.longitude];
}
}];
}
- (void)addAnnotations:(NSArray *)objects {
CLLocationDegrees lat;
CLLocationDegrees longitude;
CLLocationCoordinate2D mCoords;
NSString *fullAddress;
// Add the annotations found nearby
for (Property *property in objects) {
[self processProperties:property];
lat = property.latitude;
longitude = property.longitude;
fullAddress = [NSString stringWithFormat:#"%# %# %#", property.houseNumber, #" ", property.streetName];
[self createAnnotationWithCoords:mCoords :fullAddress :[NSString stringWithFormat:#"$%.2f", property.rent]];
}
zoomLevel = 0.1;
mCoords = CLLocationCoordinate2DMake(lat,longitude);
MKCoordinateRegion region = MKCoordinateRegionMake(mCoords,MKCoordinateSpanMake(zoomLevel,zoomLevel));
[self.mapView setRegion:region animated:YES];
}
For some reason it's just geocoding 1 property. Is not going through the loop accordingly.
Any ideas folks?
Use this on your Forward Geo Function. geocoder needs to be release and initialized again to start a new address, hope this helps.
- (void)processProperties:(Property *)property {
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:property.postalCode
completionHandler:^(NSArray* placemarks, NSError* error){
placemark = [placemarks lastObject];
for (CLPlacemark* aPlacemark in placemarks)
{
[sublet setLatitude:aPlacemark.location.coordinate.latitude];
[sublet setLongitude:aPlacemark.location.coordinate.longitude];
}
[geocoder release];
}];
}