Reputation: 167
I need to grab a set of latitude and longitude points and use them to plot map markers, but for some reason I cannot store them as a double value and pass them into my method. I have tried logging out the the values using this:
// Make the URL connection
NSString *urlAsString = @"...........";
NSURL *url = [NSURL URLWithString:urlAsString];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// Error and success message handling.
[NSURLConnection
sendAsynchronousRequest:urlRequest
queue:queue
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if([data length] > 0 &&
error == nil){
NSData *jsonData = [NSData dataWithContentsOfURL:url];
if (jsonData != nil){
NSError *error = nil;
self.result = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
if(error == nil)
NSLog(@"Longitude: %@",[_result valueForKeyPath:@"merchants.branches.longitude"]);
NSLog(@"Name: %@", [_result valueForKeyPath:@"merchants.branches.name"]);
}
}
else if ([data length] == 0 &&
error == nil){
NSLog(@"Nothing was downloaded");
}
else if (error != nil){
NSLog(@"Error happened = %@", error);
}
}];
}
and this is the data that is sent back:
2013-09-10 10:14:35.775 Longitude: (
(
"-115.118958"
),
(
"-114.985397"
),
(
"-115.285782"
),
(
"-115.114960"
),
(
"-115.108841"
),
(
"-115.280380"
),
(
"-115.120628"
),
(
"-115.166840"
),
(
"-115.224167",
"-115.172226"
)
)
2013-09-10 10:14:35.776 Name: (
(
"36.110806"
),
(
"36.033428"
),
(
"36.158482"
),
(
"36.029102"
),
(
"36.076591"
),
(
"36.143978"
),
(
"35.997353"
),
(
"36.106091"
),
(
"36.238758",
"36.067402"
)
)
Now I'm trying to create a for loop that takes each of these values and stores them as a doublevalue in order to send it through a method. Here's that for loop:
for(NSDictionary *location in _result) {
CLLocationCoordinate2D annotationCoordinate =
CLLocationCoordinate2DMake([location valueForKey:@"merchants.branches.latitude"] doubleValue]]),
([location valueForKey:@"merchants.branches.longitude"] doubleValue]]);
Annotation *annotation = [[Annotation alloc] init];
annotation.coordinate = annotationCoordinate;
annotation.title = location[@"name"];
annotation.subtitle = nil;
[self.mapView addAnnotation:annotation];
I'm not sure what's going on, but it keeps sending me back an error. Any ideas? I know it has to do with the keys I'm trying to call.
UPDATE- This is what was returned:
categories = (
{
id = 69;
label = Medical;
parentId = 1;
},
{
id = 25;
label = Apparel;
},
{
id = 70;
label = "Exercise & Weight Loss";
parentId = 1;
},
{
id = 16;
label = "Sports & Fitness";
},
{
id = 1;
label = Health;
},
{
id = 48;
label = Women;
parentId = 25;
},
{
id = 2;
label = Travel;
},
{
id = 89;
label = Spas;
parentId = 23;
},
{
id = 78;
label = Outdoors;
parentId = 16;
},
{
id = 23;
label = Beauty;
},
{
id = 85;
label = Services;
}
);
currentCount = 10;
deals = (
{
categories = (
{
id = 1;
},
{
id = 16;
},
{
id = 70;
}
);
merchant = {
branches = (
{
id = 8718069;
}
);
id = 200014;
};
owner = {
id = 1;
};
price = "60.00";
sold = 1;
startDate = "2012-03-25 18:21";
startDateEpoch = 1332699660000;
terms = "";
tippedAtDate = "<null>";
tippedAtDateEpoch = "<null>";
tippingPoint = "<null>";
title = "$60 for Color/Cut/Style from Pin Ups Day Spa & Salon ";
url = "http://mediaengine.onebigplanet.com/d/public/redirectToMerchant.do?webService=true&offerId=520053";
value = "120.00";
},
{
categories = (
{
id = 1;
},
{
id = 23;
},
{
id = 89;
}
);
categories = (
{
id = 16;
},
{
id = 1;
}
);
description = "<p>Teeth whitening can help remove stains left by coffee, tea, hot chocolate, or\U00e2\U20ac\U201c\U00e2\U20ac\U201cthe most popular hot beverage of all\U00e2\U20ac\U201c\U00e2\U20ac\U201call of the above mixed together in a shoebox lined with wax paper (you drink it by punching a hole in the bottom). Smile brighter with this Groupon.</p>\n\n<h4>$99.99 for an In-Office Teeth-Whitening Treatment (Up to $217 Value)</h4>\n\n<p>In-office <a href=\"http://gr.pn/11LSlWo\">teeth whitening</a> treatments last for 60 minutes.<p></p>";
discountMoney = "117.01";
discountPercent = "53.92";
distanceInKms = "19.65";
distanceInMiles = "12.21";
endDate = "2016-01-28 06:59";
endDateEpoch = 1453964340000;
feedSource = 5;
id = 872004;
imageUrl = "https://img.grouponcdn.com/deal/pwZjaNwsgB74teJtHre2/Zc-440x267/v1/t440x300.jpg";
merchant = {
branches = (
{
id = 6462898;
}
);
id = 132923;
};
owner = {
id = 1;
};
price = "99.99";
sold = 30;
startDate = "2013-04-28 07:00";
startDateEpoch = 1367132400000;
terms = "<ul><li>Limit 1 per person, may buy 5 additional as gifts. Limit 1 per visit. Appointment required. 24hr cancellation notice required. Must be 14 or older.</li></ul>";
tippedAtDate = "2013-04-27 20:51";
tippedAtDateEpoch = 1367095860000;
tippingPoint = "<null>";
title = "$99 for a 60-Minute In-Office Teeth-Whitening Treatment at Teeth Whitening by T & G (Up to $217 Value)";
url = "http://mediaengine.onebigplanet.com/d/public/redirectToMerchant.do?webService=true&offerId=872004";
value = "217.00";
}
);
errorCode = "";
errorMessage = "";
feedSources = (
{
code = zozi;
id = 11;
logoUrl = "http://d2bvnbhf12ry1m.cloudfront.net/media/44611.png";
name = Zozi;
},
{
code = "amazon_local";
id = 163;
logoUrl = "http://d2bvnbhf12ry1m.cloudfront.net/media/87293.png";
name = AmazonLocal;
},
{
code = groupon;
id = 5;
logoUrl = "http://d2bvnbhf12ry1m.cloudfront.net/media/31513.jpg";
name = Groupon;
},
{
code = livingsocial;
id = 7;
logoUrl = "http://d2bvnbhf12ry1m.cloudfront.net/media/32636.png";
name = LivingSocial;
},
{
code = signpost;
id = 20;
logoUrl = "http://d2bvnbhf12ry1m.cloudfront.net/media/73440.png";
name = Signpost;
}
);
merchants = (
{
branches = (
{
city = "Las Vegas";
country = "United States";
countryIsoCode = USA;
distanceInKms = "10.51";
distanceInMiles = "6.53";
id = 9913587;
latitude = "36.110806";
longitude = "-115.118958";
name = "Las Vegas - 89119";
state = Nevada;
stateIsoCode = NV;
street = "4318 South Eastern Avenue";
telephone = "(702) 736-6119";
}
);
id = 229950;
logoUrl = "http://d2bvnbhf12ry1m.cloudfront.net";
name = Prodentista;
},
{
branches = (
{
city = Henderson;
country = "United States";
countryIsoCode = USA;
distanceInKms = "14.91";
distanceInMiles = "9.27";
id = 8718069;
latitude = "36.033428";
longitude = "-114.985397";
name = "Henderson - 89012";
state = Nevada;
stateIsoCode = NV;
street = "12 W. Pacific Ave.";
telephone = 7025381248;
}
);
id = 200014;
logoUrl = "http://d2bvnbhf12ry1m.cloudfront.net";
name = "Pin Ups Day Spa & Salon";
},
{
branches = (
{
city = "Las Vegas";
country = "United States";
countryIsoCode = USA;
distanceInKms = "19.65";
distanceInMiles = "12.21";
id = 6462898;
latitude = "36.158482";
longitude = "-115.285782";
name = "The Body Spa";
state = Nevada;
stateIsoCode = NV;
street = "8751 W Charleston Blvd.";
telephone = "";
}
);
id = 132923;
logoUrl = "http://d2bvnbhf12ry1m.cloudfront.net/31513.jpg";
name = "Teeth Whitening by T & G";
},
{
branches = (
{
city = "Las Vegas";
country = "United States";
countryIsoCode = USA;
distanceInKms = "3.35";
distanceInMiles = "2.08";
id = 15739653;
latitude = "36.029102";
longitude = "-115.114960";
name = "Las Vegas - 89123";
state = Nevada;
stateIsoCode = NV;
street = "8876 Eastern Avenue";
telephone = "";
}
);
id = 355896;
logoUrl = "http://d2bvnbhf12ry1m.cloudfront.net";
name = "Body Heat";
},
{
branches = (
{
city = "Las Vegas";
country = "United States";
countryIsoCode = USA;
distanceInKms = "7.34";
distanceInMiles = "4.56";
id = 17028009;
latitude = "36.076591";
longitude = "-115.108841";
name = "Las Vegas - 89120";
state = Nevada;
stateIsoCode = NV;
street = "6230 Mcleod Drive, Suite 140";
telephone = "702-435-9478";
}
);
id = 430327;
logoUrl = "http://d2bvnbhf12ry1m.cloudfront.net";
name = "Mcleod Wellness Center";
},
{
branches = (
{
city = "Las Vegas";
country = "United States";
countryIsoCode = USA;
distanceInKms = "18.09";
distanceInMiles = "11.24";
id = 6043133;
latitude = "36.143978";
longitude = "-115.280380";
name = "Las Vegas - 8645 W Sahara Ave.";
state = Nevada;
stateIsoCode = NV;
street = "8645 W Sahara Ave.";
telephone = "";
}
);
id = 121022;
logoUrl = "http://d2bvnbhf12ry1m.cloudfront.net/31513.jpg";
name = "Just Face It Medspa";
},
{
branches = (
{
city = Henderson;
country = "United States";
countryIsoCode = USA;
distanceInKms = "3.66";
distanceInMiles = "2.27";
id = 4563174;
latitude = "35.997353";
longitude = "-115.120628";
name = Henderson;
state = Nevada;
stateIsoCode = NV;
street = "3035 W Horizon Ridge Pkwy., Suite 100";
telephone = "";
}
);
id = 57146;
logoUrl = "http://d2bvnbhf12ry1m.cloudfront.net/31513.jpg";
name = "Signature Institute of Aesthetic Sculpting";
},
{
branches = (
{
city = "Las Vegas";
country = "United States";
countryIsoCode = USA;
distanceInKms = "9.71";
distanceInMiles = "6.03";
id = 13769564;
latitude = "36.106091";
longitude = "-115.166840";
name = "Las Vegas - 89109";
state = Nevada;
stateIsoCode = NV;
street = "145 East Harmon Avenue";
telephone = "";
}
);
id = 272131;
logoUrl = "http://d2bvnbhf12ry1m.cloudfront.net";
name = "Luxury Suites International";
},
Upvotes: 0
Views: 1072
Reputation: 111
A couple things I'm seeing here.
Seems like in your completion handler, you're calling out to your web service again. I don't think that's causing your issue, but it's something to look at. Specifically, this line: NSData *jsonData = [NSData dataWithContentsOfURL:url];
I think it should probably be: NSData *jsonData = data;
The data is already being passed into your block, and you're already testing against it as an error condition above this.
I don't think the data is formed the way you're expecting it to be formed. Unless the merchants names are all 36.xxxxx
I wonder if you could print out the results (assuming no sensitive data is there) so we could see how it's structured? Maybe replace NSLog(@"Longitude: %@",[_result valueForKeyPath:@"merchants.branches.longitude"]);
with NSLog(@"Results: %@",_result);
?
UPDATE: Ok, that helps. Looks like what you're getting back is not an array, but a dictionary. Looks like in that dictionary, you have an property merchants, which is an array of dictionaries. Each of these dictionaries contains a record for a merchant. Moreover, each of these merchants has another dictionary inside of it for all the branches. So you're probably going to want to either nest another loop to handle all the branches, or just take the branch at index 0.
So, instead of your current looping construct:
for(NSDictionary *location in _result) {
CLLocationCoordinate2D annotationCoordinate =
CLLocationCoordinate2DMake([location valueForKey:@"merchants.branches.latitude"] doubleValue]]),
([location valueForKey:@"merchants.branches.longitude"] doubleValue]]);
Annotation *annotation = [[Annotation alloc] init];
annotation.coordinate = annotationCoordinate;
annotation.title = location[@"name"];
annotation.subtitle = nil;
[self.mapView addAnnotation:annotation];
You'd want something more like:
NSArray *merchantsArray = [_result objectForKey:@"merchants"];
for(NSDictionary *location in merchantsArray) {
NSArray *branches = [location objectForKey:@"branches"];
for (NSDictionary *aBranch in branches) {
CLLocationCoordinate2D annotationCoordinate =
CLLocationCoordinate2DMake([[aBranch objectForKey:@"latitude"] doubleValue],
[[aBranch objectForKey:@"longitude"] doubleValue]);
Annotation *annotation = [[Annotation alloc] init];
annotation.coordinate = annotationCoordinate;
annotation.title = location[@"name"];
annotation.subtitle = nil;
[self.mapView addAnnotation:annotation];
}
}
Upvotes: 2