Работа с вложенными ключами NSDictionary

Мне нужно получить набор точек широты и долготы и использовать их для построения маркеров карты, но по какой-то причине я не могу сохранить их как двойное значение и передать их в свой метод. Я попытался вывести значения, используя это:

  // 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, который принимает каждое из этих значений и сохраняет их как двойное значение, чтобы отправить его через метод. Вот это для цикла:

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

Я не уверен, что происходит, но он продолжает отправлять мне ошибку. Любые идеи? Я знаю, что это связано с ключами, которые я пытаюсь вызвать.

ОБНОВЛЕНИЕ. Вот что было возвращено:

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

person Lalalalalala    schedule 10.09.2013    source источник


Ответы (1)


Пара вещей, которые я вижу здесь.

  1. Похоже, что в вашем обработчике завершения вы снова обращаетесь к своему веб-сервису. Я не думаю, что это вызывает вашу проблему, но на это стоит обратить внимание. В частности, эта строка: NSData *jsonData = [NSData dataWithContentsOfURL:url]; Я думаю, что это, вероятно, должно быть: NSData *jsonData = data; Данные уже передаются в ваш блок, и вы уже тестируете их как условие ошибки выше этого.

  2. Я не думаю, что данные формируются так, как вы ожидаете. Если только имена всех продавцов не 36.xxxxx, интересно, не могли бы вы распечатать результаты (при условии отсутствия конфиденциальных данных), чтобы мы могли увидеть, как они структурированы? Может быть, заменить NSLog(@"Longitude: %@",[_result valueForKeyPath:@"merchants.branches.longitude"]); на NSLog(@"Results: %@",_result);?

ОБНОВЛЕНИЕ: Хорошо, это помогает. Похоже, что вы возвращаете не массив, а словарь. Похоже, в этом словаре у вас есть свойство торговцев, представляющее собой массив словарей. Каждый из этих словарей содержит запись о торговце. Более того, внутри каждого из этих торговцев есть еще один словарь для всех филиалов. Поэтому вы, вероятно, захотите либо вложить еще один цикл для обработки всех ветвей, либо просто взять ветвь с индексом 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];
             }
    }
person frankfle    schedule 10.09.2013
comment
Хорошо, замечательно, это сработало! Тем не менее, проблема по-прежнему заключается в том, чтобы захватить эти конкретные значения ключей и сохранить их. я собираюсь попытаться снова передать его через цикл for. - person Lalalalalala; 10.09.2013