Loop should run 4 times but doing only once - ios

I am making an application based on geolocalisation. Here is my code :
-(void)gettingDataSQL {
NSURL *url = [NSURL URLWithString:#"http://www.xxx.fr/xxx/xxx/script_xxx_localisation.php"];
NSData *data = [NSData dataWithContentsOfURL:url];
if (data != nil)
{
jsonArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSLog(#"jSonArrayCount = %i", [jsonArray count]);
for (int i = 0; i<jsonArray.count; i++) {
NSString *address = [[jsonArray objectAtIndex:i] objectForKey:#"adresse"];
NSLog(#"address FROM JSON = %#", address);
NSString *titre = [[jsonArray objectAtIndex:i] objectForKey:#"titre"];
NSString *stringId = [[jsonArray objectAtIndex:i] objectForKey:#"id"];
[geocoder geocodeAddressString:address completionHandler:^(NSArray* placemarks, NSError* error){
// Check for returned placemarks
if (placemarks && placemarks.count > 0) {
NSLog(#"if placemarks && placemarks.count");
CLPlacemark *topResult = [placemarks objectAtIndex:0];
MKPlacemark *placemark = [[MKPlacemark alloc]initWithPlacemark:topResult];
// [self.mapViewOutlet addAnnotation:placemark];
NSLog(#"Placemark posé au longitude : %f et latitude : %f", placemark.location.coordinate.longitude, placemark.location.coordinate.latitude);
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
annotation.coordinate = placemark.location.coordinate;
annotation.title = titre;
annotation.subtitle = stringId;
[mapViewOutlet addAnnotation:annotation];
}
}];
NSLog(#"one placemark well defined via retrieveData:");
}
}
}
With all the NSLogs I did, I understood that the for int loop is called 4 times as it is supposed to, but the entire code in the loop is not called.
This part of the loop is called only once and I don't get why :
[geocoder geocodeAddressString:address completionHandler:^(NSArray* placemarks, NSError* error){
// Check for returned placemarks
if (placemarks && placemarks.count > 0) {
NSLog(#"if placemarks && placemarks.count");
CLPlacemark *topResult = [placemarks objectAtIndex:0];
MKPlacemark *placemark = [[MKPlacemark alloc]initWithPlacemark:topResult];
// [self.mapViewOutlet addAnnotation:placemark];
NSLog(#"Placemark posé au longitude : %f et latitude : %f", placemark.location.coordinate.longitude, placemark.location.coordinate.latitude);
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
annotation.coordinate = placemark.location.coordinate;
annotation.title = titre;
annotation.subtitle = stringId;
[mapViewOutlet addAnnotation:annotation];
}
}];
I would like to create multiple annotation views on the map and not only one. I have multiple entries in databases that are downloaded in order to be shown on the Map in the loop for JsonArray but the code after the geocoding is called only once so it shows only the first entry of my database.
Any idea guys ?
Thanks in advance for your help and reading ;)
I hope it will help someone else having the same problem too !
AFTER ANSWERS
LOG OF THE JSON ARRAY :
2014-09-15 21:24:21.544 xxxx[1416:60b] (
{
adresse = "115 rue de reuilly";
cree = "2014-07-13 21:03:23";
description = "Venez boire!";
icone = "icone_base.png";
id = 1;
"id_annonceur" = 1;
"id_type" = 3;
lat = "";
lon = "";
note = 0;
portee = 25;
titre = "La premiere Leffe gratuite!";
validite = "";
vues = 0;
},
{
adresse = "107 rue de reuilly";
cree = "2014-07-13 22:21:24";
description = "Le Match n'est pas fini, profitez-en !";
icone = "icone_base.png";
id = 2;
"id_annonceur" = 1;
"id_type" = 3;
lat = "";
lon = "";
note = 0;
portee = 25;
titre = "Karhu a -50%";
validite = "";
vues = 0;
},
{
adresse = "Metropole de la Gare";
cree = "2014-07-19 15:57:51";
description = "Premier arrive, premier servi!";
icone = "icone_base.png";
id = 4;
"id_annonceur" = 1;
"id_type" = 1;
lat = "";
lon = "";
note = 0;
portee = 25;
titre = "Le Mojito est gratuit!";
validite = "";
vues = 0;
},
{
adresse = "2 rue de reuilly";
cree = "2014-07-19 15:59:12";
description = "Depechez-vous !";
icone = "icone_base.png";
id = 5;
"id_annonceur" = 1;
"id_type" = 1;
lat = "";
lon = "";
note = 0;
portee = 25;
titre = "La dose du Martini doublee pour 1h!";
validite = "";
vues = 0;
}

"After initiating a forward-geocoding request, do not attempt to initiate another forward- or reverse-geocoding request."
- Quote from Apple Documentation
https://developer.apple.com/Library/ios/documentation/CoreLocation/Reference/CLGeocoder_class/Reference/Reference.html#//apple_ref/occ/instm/CLGeocoder/geocodeAddressString:completionHandler:

Related

show user's location with a custom pin on map and in a table view

i m showing user's location in a map view(apple map) with custom pin and those same pins are shown in a table view in front of the user name.Each user should have a different pin and if the user name occurs twice then it should have the same pin colour as the previous one.
This is the table view screen shot and below this table view there is a map view:
if in the table view "user name" has blue pin then in the map "username's" location shud be shown with blue pin.
if user2 has green pin in table, it should be green in map as well.
the response i m getting is
{
"driver_or_rider" = 1;
email = "ish#gmail.com";
isGuest = 0;
lat = "47.606209";
long = "-122.332071";
name = "ish bids";
"status_trip" = 1;
"user_image_url" = "http://app/image/1458101010.userimage";
},
{
"driver_or_rider" = 0;
email = "arin#gmail.com";
isGuest = 0;
lat = "34.052227";
long = "-118.243660";
name = "arin John";
"status_trip" = 1;
"user_image_url" = "http://app/image/5b3ee2e9fb51c7b20303a95b93bf63b2.";
},
{
"driver_or_rider" = 0;
email = "deepak12#gmail.com";
isGuest = 0;
lat = "31.968599";
long = "-99.901813";
name = "Deepak Chaudhary chaudhary ";
"status_trip" = 1;
"user_image_url" = "http://app/image/2197c75dc6b2bbd0ff26008a987781f3.";
},
{
"driver_or_rider" = 0;
email = "ish#gmail.com";
isGuest = 1;
lat = "31.968599";
long = "-99.901813";
name = "Deepak Chaudhary chaudhary 's Guest";
"status_trip" = 1;
"user_image_url" = "http://app/image/no-image.png";
},
{
"driver_or_rider" = 0;
email = "ish#gmail.com";
isGuest = 1;
lat = "41.878114";
long = "-87.629798";
name = "shiv Shankar 's Guest";
"status_trip" = 1;
"user_image_url" = "http://app/image/no-image.png";
},
{
"driver_or_rider" = 0;
email = "shiv#gmail.com";
isGuest = 0;
lat = "41.878114";
long = "-87.629798";
name = "shiv Shankar ";
"status_trip" = 1;
"user_image_url" = "http://app/image/1458129359.userimage";
},
{
"driver_or_rider" = 0;
email = "andrew.payasi#gmail.com";
isGuest = 0;
lat = "43.65322577127058";
long = "-79.38318371772766";
name = username;
"status_trip" = 1;
"user_image_url" = "http://app/image/1456821877.png";
}
)
this is the code in cell for row at index
int randomNumber = indexPath.row % [imageNameArray count];
NSString* nameStr=[goersInfo valueForKey:#"name"];
NSArray * nameStrArray = [nameStr componentsSeparatedByString: #"'s"];
nameStr=[nameStrArray objectAtIndex:0];
NSNumber *indexNumber = self.pinDictionary[nameStr];
index = indexNumber.unsignedIntegerValue;
cell.PinImageView.image=[UIImage imageNamed:[imageNameArray objectAtIndex:index]];
this is dictionary where name are stored
- (void)setupPinDictionary
{
self.pinDictionary = [NSMutableDictionary dictionary];
self.imageNameArray = [[NSArray alloc] initWithObjects:#"pin2#2x.png", #"pin3#2x.png", #"pin4#2x.png", #"pin5#2x.png", #"pin6#2x.png",#"pin8#2x.png",#"pin9#2x.png", nil];
NSUInteger pinImageCount = self.imageNameArray.count;
for (NSDictionary *goersInfo in tableGoersList) {
NSString* nameStr=[goersInfo valueForKey:#"name"];
NSArray * nameStrArray = [nameStr componentsSeparatedByString: #"'s"];
nameStr=[nameStrArray objectAtIndex:0];
if (self.pinDictionary[nameStr] == nil) {
indexPin = arc4random() % pinImageCount;
self.pinDictionary[nameStr] = [NSNumber numberWithUnsignedInteger: indexPin];
}
}
Initially this method is called
-(void)doJourneyGoersList:(id)responseObject{
NSDictionary *dict=[responseObject[#"Count"] firstObject];
checkLocation=[[NSMutableArray alloc]init];
if (dict==nil) {
return;
}
[_messagesButton.badgeButton setBadgeValue:dict[#"Count_Masssage"]];
[_invitesButton.badgeButton setBadgeValue:dict[#"invite_count"]];
[_matchedButton.badgeButton setBadgeValue:dict[#"Count_Match"]];
goersList= [responseObject objectForKey:#"statement"];
CLLocationCoordinate2D orginCllocation=CLLocationCoordinate2DMake([_tripDetails[#"origin_lat"] doubleValue], [_tripDetails[#"origin_long"] doubleValue]);
MKPointAnnotation *annotation =[[MKPointAnnotation alloc] init];
annotation.coordinate=orginCllocation;
[checkLocation addObject:annotation];
tableGoersList=[NSMutableArray new];
for (NSDictionary *dict in goersList) {
NSMutableDictionary *localdict=[NSMutableDictionary new];
loc=[NSMutableDictionary new];
[localdict setObject:[dict objectForKey:#"name"] forKey:#"name"];
[localdict setObject:[dict objectForKey:#"email"] forKey:#"email"];
if ([dict[#"status_trip"] isEqualToString:#"confirm"]) {
[localdict setObject:#"1" forKey:#"status_trip"];
[loc setObject:[dict objectForKey:#"origin_lat"] forKey:#"lat"];
[loc setObject:[dict objectForKey:#"origin_long"] forKey:#"long"];
CLLocationCoordinate2D location=CLLocationCoordinate2DMake([loc[#"lat"] doubleValue], [loc[#"long"] doubleValue]);
[localdict setObject:[dict objectForKey:#"origin_lat"] forKey:#"lat"];
[localdict setObject:[dict objectForKey:#"origin_long"] forKey:#"long"];
if (location.latitude == orginCllocation.latitude && location.longitude == orginCllocation.longitude) {
//location is origin, skip this since it is already added
} else {
MKPointAnnotation *annotation =[[MKPointAnnotation alloc] init];
annotation.coordinate=location;
[checkLocation addObject: annotation];
}
NSLog(#"check location %#",checkLocation);
}
else
[localdict setObject:#"0" forKey:#"status_trip"];
if ([dict[#"isGuest"] isEqualToString:#"1"]) {
[localdict setObject:#"1" forKey:#"isGuest"];
}
else
[localdict setObject:#"0" forKey:#"isGuest"];
[localdict setObject:[dict objectForKey:#"user_image_url"] forKey:#"user_image_url"];
if ([dict[#"driver_or_rider"] isEqualToString:#"Drive"]) {
[localdict setObject:#"1" forKey:#"driver_or_rider"];
[tableGoersList insertObject:localdict atIndex:0];
}
else
{
[localdict setObject:#"0" forKey:#"driver_or_rider"];
[tableGoersList addObject:localdict];
}
//add the objects to the array
}
CLLocationCoordinate2D parkCllocation=CLLocationCoordinate2DMake([_tripDetails[#"park_lat"] doubleValue], [_tripDetails[#"park_long"] doubleValue]);
MKPointAnnotation *jauntAnnotationPark =[[MKPointAnnotation alloc] init];
jauntAnnotationPark.coordinate=parkCllocation;
[checkLocation addObject:jauntAnnotationPark];
[mapView showAnnotations: checkLocation animated:NO];
[mapView setCenterCoordinate:mapView.region.center animated:NO];
int count = [checkLocation count];
CLLocationCoordinate2D coordinateArray[count];
for (int i = 0; i < count; i++) {
coordinateArray[i] = ((MKPointAnnotation *)checkLocation[i]).coordinate;
}
self.routeLine = [MKPolyline polylineWithCoordinates:coordinateArray count:count];
[mapView addOverlay:self.routeLine];
[self setupPinDictionary];
[self.ridersTableView reloadData];
}
and this is the code for view for annotation
{
imageNameArray = [[NSArray alloc] initWithObjects:#"pin2#2x.png", #"pin3#2x.png", #"pin4#2x.png", #"pin5#2x.png", #"pin6#2x.png",#"pin8#2x.png",#"pin9#2x.png",nil];
[self setupPinDictionary];
myAnnotation.image=[UIImage imageNamed:[imageNameArray objectAtIndex:indexPin]];
}
return myAnnotation;
}

How to fetch elements from NSArray in Objective C

I'm using a bus timetable API and want to display the nearby bus stop according to user current location. I've already got the the JSON response through url and parsed JSON to NSArray. The NSArray looks like this.
{
result = {
distance = "0.00003292029";
lat = "-37.92091";
"location_name" = "Monash Medical Centre/Clayton Rd ";
lon = "145.120682";
"route_type" = 2;
"stop_id" = 16518;
suburb = Clayton;
"transport_type" = bus;
};
type = stop;
},
{
result = {
distance = "0.00003728643";
lat = "-37.92227";
"location_name" = "Monash Surgical Private Hospital/291 Clayton Rd ";
lon = "145.1202";
"route_type" = 2;
"stop_id" = 24348;
suburb = Clayton;
"transport_type" = bus;
};
type = stop;
},
{
result = {
distance = "0.00003804303";
lat = "-37.9230766";
"location_name" = "Clayton Railway Station/Clayton Rd ";
lon = "145.120209";
"route_type" = 2;
"stop_id" = 22809;
suburb = Clayton;
"transport_type" = bus;
};
type = stop;
},
{
result = {
distance = "0.00003976311";
lat = "-37.9186172";
"location_name" = "Monash Specialist Centre/Clayton Rd ";
lon = "145.121033";
"route_type" = 2;
"stop_id" = 22807;
suburb = Clayton;
"transport_type" = bus;
};
type = stop;
},
{
result = {
distance = "0.00004085229";
lat = "-37.9186478";
"location_name" = "Dixon St/Clayton Rd ";
lon = "145.120911";
"route_type" = 2;
"stop_id" = 13889;
suburb = Clayton;
"transport_type" = bus;
};
type = stop;
}
)
My question is how to get the latitude and longitude from this NSArray. I wrote these code but it returns nil.
NSMutableArray *coordinateLatit = [[NSMutableArray alloc]init];
for (int i = 0; i<nearbyStop.count; i++) {
NSString *latit = [[nearbyStop objectAtIndex:1] objectForKey:#"lat"];
if(latit == nil)
{
NSLog(#"there is no data");
}
else
{
[coordinateLatit addObject:latit];
}
}
And also i want to display the stops(use longitude&latitude from NSArray) on MKMapView, how should i manage to implement the MKLocalSearchRequest
Appreciate it if anyone can help me!
Your code overlooked the extra nested result level.
NSMutableArray *coordinateLatit=[[NSMutableArray alloc]init];
for(NSDictionary *d in nearbyStop)
{
NSString *latit=d[#"result"][#"lat"];
if(lat) [coordinateLatit addObject:latit];
}
-(id) doApiCall:(NSString*)apiCall useCache:(BOOL)useCache
{
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#%#", mBaseURL, [MapViewController signApiCall:apiCall]]];
id response = [self httpWrapper:url];
NSLog( #"%#", response );
return response;
}
-(id) httpWrapper:(NSURL*)url
{
__block id response = nil;
void (^doStuff)() = ^void()
{
int retry = 3;
NSError * error;
while( retry > 0) {
NSData * data = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:600] returningResponse:nil error:&error ];
if( data != nil )
{
response = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if( response != nil)
retry = 0;
}
if(data == nil || response == nil)
{
NSLog(#"Bad response %#", url);
NSLog(#"%#", error);
--retry;
}
}
};
doStuff();
return response;
}
-(NSArray*) nearby:(CLLocation*)location
{
return [self doApiCall:[NSString stringWithFormat:#"/v2/nearme/latitude/%f/longitude/%f?limit=5", location.coordinate.latitude, location.coordinate.longitude]];
}
Here is the code i'm using to call the API. I use id for the response from url request. so does nearby method returns NSArray type?
you miss a level of the json response, it should be
for (Stop *stop in nearbyStop) {
NSString *latit = [[stop objectForKey:#"result"] objectForKey:#"lat"];
if(latit == nil)
{
NSLog(#"there is no data");
}
else
{
[coordinateLatit addObject:latit];
}
}

how to find closest locations between 5m to 10m range from array of locations in iOS?

this was my code and i want nearest locations from my current location in the range of 10meters and i want to add all the nearest locations with details of the person in response also add in array.thanks
and this is my response from server
{
born = 0;
completed = 0;
"emergency_id" = "-1";
eyes = "";
feet = 0;
"first_name" = Neil;
glasses = No;
hair = "";
inch = 0;
language = "<null>";
"last_name" = Ferris;
latitude = "30.1456987";
longitude = "76.69916";
marks = "";
"member_id" = 21634;
picture = "";
"profile_id" = 5826;
type = 1;
updated = "2015-09-16 06:32:08";
weight = 0;
}
like the above i am getting 5000 users from server ,after i filtering with 10 meters distance through my current location i need to display list in table view who are in below 10 meters range
- (void)getdata
{
NSString * apiURLStr =[NSString stringWithFormat:#"<MY API URL>"];
NSString *outputStr = [NSString stringWithContentsOfURL:[NSURL URLWithString:apiURLStr] encoding:NSUTF8StringEncoding error:nil];
NSDictionary *response;
if (outputStr == nil)
{
return;
}
NSData* data = [outputStr dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
response = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSMutableArray *array=[[NSMutableArray alloc]init];
CLLocation *closestLocation = nil;
for (NSDictionary *dict in response)
{
NSString *latitude=[dict valueForKey:#"latitude"];
NSString *longitude=[dict valueForKey:#"longitude"];
CLLocation *location = [[CLLocation alloc] initWithLatitude:latitude.doubleValue
longitude:longitude.doubleValue];
[array addObject:location];
}
CLLocationDistance closestLocationDistance = DBL_MIN;
for (CLLocation *location in array)
{
if (!closestLocation) {
closestLocation = location;
closestLocationDistance = [currentUserLocation distanceFromLocation:location];
continue;
}
CLLocationDistance currentDistance = [currentUserLocation distanceFromLocation:location];
if (currentDistance < closestLocationDistance)
{
closestLocation = location;
closestLocationDistance = currentDistance;
}
}
NSLog(#"closestLocation %#",closestLocation.description);
NSLog(#"closestLocationDistance %f", closestLocationDistance);
}
thanks for answer bro,but i want list of closest locations in below 10 meters range.
NSMutableArray *locationsInRange = [NSMutableArray new];
for (CLLocation *location in array)
{
CLLocationDistance currentDistance = [currentUserLocation distanceFromLocation:location];
if (currentDistance < 10)
{
[locationsInRange addObject:location];
}
}
NSLog(#"locations in 10 metters %#",locationsInRange.description);

Parsing Json in Google Maps iOS

I have got the Json response. Here it is:
Directions {
routes = (
{
bounds = {
northeast = {
lat = "39.893397";
lng = "42.2477961";
};
southwest = {
lat = "21.4204199";
lng = "39.2398944";
};
};
copyrights = "Map data \U00a92014 Google, Mapa GISrael, ORION-ME";
legs = (
{
distance = {
text = "2,940 km";
value = 2940341;
};
duration = {
text = "1 day 15 hours";
value = 138793;
};
"end_address" = "Unnamed Road, Erzincan Province, Turkey";
"end_location" = {
lat = "39.893397";
lng = "39.906191";
};
"start_address" = "4289, Al Hajlah, Mecca 24231\U00a06970, Saudi Arabia";
"start_location" = {
lat = "21.4204199";
lng = "39.8258119";
};
steps = (
{
distance = {
text = "0.6 km";
value = 630;
};
duration = {
text = "1 min";
value = 55;
};
"end_location" = {
lat = "21.4235672";
lng = "39.8211613";
};
"html_instructions" = "Head <b>west</b> on <b>Alsouq Alsagheer Tunnel</b>";
polyline = {
points = "stvaCinarFEh#?h#?f#Cd#If#Gb#Yx#Yx#e#bAWb#Y`#CD[b#c#l#ILADIRIVGPKRGJKPILKPWRi#X_Ad#MFSJ]N[N_#P]ROJ";
};
"start_location" = {
lat = "21.4204199";
lng = "39.8258119";
};
"travel_mode" = DRIVING;
and it goes on....
Here is some code from my project:
Direction.h
-(void)retrieveDirectionsFromOrigin:(CLLocationCoordinate2D)origin toDestination:(CLLocationCoordinate2D)destination
{
NSString *directionsURL=[NSString stringWithFormat:#"http://maps.google.com/maps/api/directions/json?origin=%f,%f&destination=%f,%f&sensor=false",origin.latitude,origin.longitude,destination.longitude,destination.longitude];
_directionsURL=[NSURL URLWithString:directionsURL];
[self retrieveDirections:nil withDelegate:self];
}
-(void)retrieveDirections:(SEL)selector withDelegate:(id)delegate{
dispatch_async(dispatch_get_main_queue(), ^{
NSData *data = [NSData dataWithContentsOfURL:_directionsURL];
[self fetchedData:data withDelegate:delegate];
});
}
-(void)fetchedData:(NSData *)data withDelegate:(id)delegate{
NSError* error;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSLog(#"Directions %#",json);
if(!error){
self.steps = json[#"routes"][0][#"legs"][0][#"steps"];
}
//MapViewController.m
marker.position = CLLocationCoordinate2DMake(21.422492, 39.826169);
marker2.position = CLLocationCoordinate2DMake(21.413333, 39.893333);
marker.map = mapView;
marker2.map = mapView;
directions=[[Directions alloc]init];
[directions retrieveDirectionsFromOrigin:marker.position toDestination:marker2.position];
[mapViewView setNeedsDisplay];
[mapView setNeedsDisplay];
[self.view bringSubviewToFront:backButton];
}
I am a beginner. Please let me know what to do next to show directions via polyline. Thanks
Here's a tip on how to create the polyline which should get you started on your way
Gather the polystrings from the steps
NSArray *steps = [valDictionary valueForKey:#"steps"];
for (NSDictionary *stepdic in steps) {
NSString *polyStr = [[stepdic valueForKey:#"polyline"] valueForKey:#"points"];
if (polyStr != nil) [polyStrings addObject:polyStr];
}
Create a single path from the polystrings for a smooth line and create the final polyline
GMSMutablePath *path = [GMSMutablePath path];
for (NSString *polyStr in polyStrings) {
GMSPath *p = [GMSPath pathFromEncodedPath:polyStr];
for (NSUInteger i=0; i < p.count; i++) {
[path addCoordinate:[p coordinateAtIndex:i]];
}
}
GMSPolyline *polyLint = [GMSPolyline polylineWithPath:path];
good luck

Parsing JSON to place annotations on Map

I am trying to parse a JSON from Google to place annotations on Map. Parsing JSON using AFNetworking and parsing process is in Singleton class. I am getting values from two different JSON.
Places Autocomplete JSON of Google
Places Details JSON of Google
Here is my code for Singleton class
-(void)getData:(NSString *)searchString
{
_dataArray = [[NSMutableArray alloc]init];
NSString *requestString = [[NSString alloc]init];
requestString = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/autocomplete/json?input=%#&sensor=true&key=APIKEY",searchString];
requestString = [requestString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *URL = [NSURL URLWithString:requestString];
NSURLRequest *requestURL = [NSURLRequest requestWithURL:URL];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:requestURL success:^(NSURLRequest *requestURL,NSHTTPURLResponse *response, id JSON){
self.dataArray = [JSON objectForKey:#"predictions"];
[[NSNotificationCenter defaultCenter]postNotificationName:#"Doreload" object:nil];
}failure:^(NSURLRequest *requestURL,NSHTTPURLResponse *response,NSError *error, id JSON){
NSLog(#"Request Failed with Error: %#, %#", error, error.userInfo);
}];
[operation start];
}
-(void)detailList:(NSString *)referenceString
{
_detailArray = [[NSMutableArray alloc]init];
NSString *requestString = [[NSString alloc]initWithFormat:#"https://maps.googleapis.com/maps/api/place/details/json?reference=%#&sensor=true&key=APIKEY",referenceString];
NSURL *URL = [NSURL URLWithString:requestString];
NSURLRequest *requestURL = [NSURLRequest requestWithURL:URL];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:requestURL success:^(NSURLRequest *requestURL,NSHTTPURLResponse *response, id JSON){
self.detailArray = [JSON objectForKey:#"result"];
[[NSNotificationCenter defaultCenter]postNotificationName:#"showList" object:nil];
}failure:^(NSURLRequest *requestURL,NSHTTPURLResponse *response,NSError *error, id JSON){
}];
[operation start];
}
In ViewController with the first function I am passing the name of the Place in the tableView :
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
sharedRequest = [RequestHandler sharedRquest];
static NSString *cellID = #"Cell Identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
}
cell.textLabel.text = [[sharedRequest.dataArray objectAtIndex:indexPath.row]objectForKey:#"description"];
[_spinner stopAnimating];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailViewController *details = [[DetailViewController alloc]initWithNibName:#"DetailViewController" bundle:nil];
details.stringReference = [[sharedRequest.dataArray objectAtIndex:indexPath.row]objectForKey:#"reference"];
[self.navigationController pushViewController:details animated:YES];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
And the Details Class is :
- (void)viewDidLoad
{
[super viewDidLoad];
[[RequestHandler sharedRquest]detailList:self.stringReference];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(showOnMap) name:#"showList" object:nil];
self.spinner = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
self.spinner.hidesWhenStopped = YES;
self.spinner.frame = CGRectMake(0, 0, 320, 480);
[self.view addSubview:_spinner];
[_spinner startAnimating];
self.mapView.showsUserLocation = TRUE;
self.mapView.delegate = self;
}
- (void)showOnMap:(NSNotification *)notification
{
NSLog(#"Entered");
sharedRequest = [RequestHandler sharedRquest];
NSString *string = [[NSString alloc]init];
string = [sharedRequest.detailArray valueForKey:#"name"];
self.label.text = string;
}
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
sharedRequest = [RequestHandler sharedRquest];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 30000, 30000);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
double latitude = [[[[sharedRequest.detailArray valueForKey:#"geometry"]objectForKey:#"location"]objectForKey:#"lat"]doubleValue];
double longitude =[[[[sharedRequest.detailArray valueForKey:#"geometry"]objectForKey:#"location"]objectForKey:#"lng"]doubleValue];
CLLocationCoordinate2D coord = { latitude, longitude };
MKPointAnnotation *point = [[MKPointAnnotation alloc]init];
point.coordinate = coord;
point.title = [sharedRequest.detailArray valueForKey:#"name"];
[self.mapView addAnnotation:point];
[_spinner stopAnimating];
}
The problem is in Details Class for the first time when using with break points it shows annotations and second it throughs an error:
-[__NSArrayI objectForKey:]: unrecognized selector sent to instance 0x86332e0
EDIT:
here is what shared.detailArray has:
"address_components" = (
{
"long_name" = Francestown;
"short_name" = Francestown;
types = (
locality,
political
);
},
{
"long_name" = Hillsborough;
"short_name" = Hillsborough;
types = (
"administrative_area_level_2",
political
);
},
{
"long_name" = "New Hampshire";
"short_name" = NH;
types = (
"administrative_area_level_1",
political
);
},
{
"long_name" = "United States";
"short_name" = US;
types = (
country,
political
);
}
);
"adr_address" = "<span class=\"locality\">Francestown</span>, <span class=\"region\">NH</span>, <span class=\"country-name\">USA</span>";
"formatted_address" = "Francestown, NH, USA";
geometry = {
location = {
lat = "42.9875";
lng = "-71.8130599";
};
viewport = {
northeast = {
lat = "43.03844";
lng = "-71.7474139";
};
southwest = {
lat = "42.949703";
lng = "-71.88583609999999";
};
};
};
icon = "http://maps.gstatic.com/mapfiles/place_api/icons/geocode-71.png";
id = ccd239475516163d29405af62fb286bedb4c6377;
name = Francestown;
reference = "CoQBcwAAAPSQxzNrepzPywLZr1PDoPEmQmGR8rIPTPoQ_f2kXpceRGHU_J_FEcrDxZSzebqLRpNYlUC_-xRJVV7Jx_mW1KJ33foU9y0ZCNK_kC1orqZVK5B-EONPD_Ef_e9WXXZdfOZTBQzNYLhoVdP8Ufa1bPe_vuuwe3rqYtf80IyANb8mEhCKi6kISip4ItpBFfgWjuGvGhSj0hURZaTQXX4lnFlxe2v4O5Uo6Q";
types = (
locality,
political
);
url = "https://maps.google.com/maps/place?q=Francestown&ftid=0x89e22c36ba6dc937:0x52cccc5f0f9b8663";
vicinity = Francestown;
}
I tried a lot to understand the error, but all in vain.
Any help would be appreciable.
Thanks
Hope this will help you if you are looking to achieve results using a different way.
I used NSJSONSerialization class to parse the json response from Google.
In this method I parse the NSMutable Data object- _routeData(created by appending data from Google response)
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSMutableArray *polyLinesArray = [[NSMutableArray alloc] init];
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:_routeData options:kNilOptions error:nil];
NSArray *locationArray = [[[[[jsonDict valueForKey:#"routes"]valueForKey:#"legs"]valueForKey:#"steps"]valueForKey:#"polyline"] valueForKey:#"points"];
if(locationArray.count > 0)
{
NSArray *polyLinePointsArray = [[locationArray objectAtIndex:0]objectAtIndex:0];
for (int i = 0; i < [polyLinePointsArray count]; i++)
{
NSString *encodedPoints = [polyLinePointsArray objectAtIndex:i];
MKPolyline *route = [self polylineWithEncodedString:encodedPoints];
[polyLinesArray addObject:route];
}
// remove previous overlays
if(_mapView.overlays.count > 0)
{
[_mapView removeOverlays:_mapView.overlays];
}
[self.mapView addOverlays:polyLinesArray];
}
}
To decode the polyline points response from Google I used a class I found on stackoverflow..
- (MKPolyline *)polylineWithEncodedString:(NSString *)encodedString
{
const char *bytes = [encodedString UTF8String];
NSUInteger length = [encodedString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
NSUInteger idx = 0;
NSUInteger count = length / 4;
CLLocationCoordinate2D *coords = calloc(count, sizeof(CLLocationCoordinate2D));
NSUInteger coordIdx = 0;
float latitude = 0;
float longitude = 0;
while (idx < length) {
char byte = 0;
int res = 0;
char shift = 0;
do {
byte = bytes[idx++] - 63;
res |= (byte & 0x1F) << shift;
shift += 5;
} while (byte >= 0x20);
float deltaLat = ((res & 1) ? ~(res >> 1) : (res >> 1));
latitude += deltaLat;
shift = 0;
res = 0;
do {
byte = bytes[idx++] - 0x3F;
res |= (byte & 0x1F) << shift;
shift += 5;
} while (byte >= 0x20);
float deltaLon = ((res & 1) ? ~(res >> 1) : (res >> 1));
longitude += deltaLon;
float finalLat = latitude * 1E-5;
float finalLon = longitude * 1E-5;
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(finalLat, finalLon);
coords[coordIdx++] = coord;
if (coordIdx == count) {
NSUInteger newCount = count + 10;
coords = realloc(coords, newCount * sizeof(CLLocationCoordinate2D));
count = newCount;
}
}
MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordIdx];
free(coords);
return polyline;
}
Instead of this
double latitude = [[[[sharedRequest.detailArray valueForKey:#"geometry"]objectForKey:#"location"]objectForKey:#"lat"]doubleValue];
double longitude =[[[[sharedRequest.detailArray valueForKey:#"geometry"]objectForKey:#"location"]objectForKey:#"lng"]doubleValue];
try this,
double latitude = [[[[sharedRequest.detailArray valueForKey:#"geometry"]valueForKey:#"location"]valueForKey:#"lat"]doubleValue];
double longitude =[[[[sharedRequest.detailArray valueForKey:#"geometry"]valueForKey:#"location"]valueForKey:#"lng"]doubleValue];
Found the Solution:
- (void)showOnMap:(NSNotification *)notification
{
NSLog(#"Entered");
sharedRequest = [RequestHandler sharedRquest];
NSString *string = [[NSString alloc]init];
string = [sharedRequest.detailArray valueForKey:#"name"];
self.label.text = string;
double latitude = [[[[sharedRequest.detailArray valueForKey:#"geometry"]objectForKey:#"location"]objectForKey:#"lat"]doubleValue];
double longitude =[[[[sharedRequest.detailArray valueForKey:#"geometry"]objectForKey:#"location"]objectForKey:#"lng"]doubleValue];
CLLocationCoordinate2D coord = { latitude, longitude };
MKPointAnnotation *point = [[MKPointAnnotation alloc]init];
point.coordinate = coord;
point.title = [sharedRequest.detailArray valueForKey:#"name"];
[self.mapView addAnnotation:point];
[_spinner stopAnimating];
}
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
sharedRequest = [RequestHandler sharedRquest];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 30000, 30000);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
}

Resources