处理嵌套的NSDictionary密钥

时间:2013-09-10 17:32:23

标签: ios objective-c json mapkit

我需要获取一组纬度和经度点并使用它们来绘制地图标记,但出于某种原因,我无法将它们存储为double值并将它们传递给我的方法。我已尝试使用以下方法注销值:

  // 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);

         }


     }];

}

这是发回的数据:

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"
    )
)

现在我正在尝试创建一个for循环,它接受每个值并将它们存储为doublevalue,以便通过方法发送它。这是for循环:

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];

我不确定发生了什么,但它一直向我发回错误。有任何想法吗?我知道这与我试图打电话的钥匙有关。

UPDATE-这是返回的内容:

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";
        },

1 个答案:

答案 0 :(得分:2)

我在这里看到的一些事情。

  1. 似乎在您的完成处理程序中,您再次呼叫您的Web服务。我不认为这会导致你的问题,但这是值得关注的。具体来说,这一行:NSData *jsonData = [NSData dataWithContentsOfURL:url];我认为应该是:NSData *jsonData = data;数据已经传递到您的块中,并且您已经在上面测试它作为错误条件。

  2. 我不认为数据的形成方式与您期望形成的方式相同。除非商家名称都是36.xxxxx我想知道你是否可以打印结果(假设没有敏感数据),那么我们可以看到它的结构如何?也许用NSLog(@"Longitude: %@",[_result valueForKeyPath:@"merchants.branches.longitude"]);替换NSLog(@"Results: %@",_result);

  3. 更新: 好的,这有帮助。看起来你要回的不是数组,而是字典。看起来在那本词典中,你有一个属性商家,这是一系列词典。这些词典中的每一个都包含商家的记录。而且,这些商家中的每一个都在其中具有用于所有分支的另一个字典。所以你可能想要嵌套另一个循环来处理所有分支,或者只是在索引0处取分支。

    所以,而不是你当前的循环结构:

        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];
    

    你想要更像的东西:

        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];
                 }
        }