Objective-C для чайников: как я могу пройти через NSDictionary внутри NSDictionary? - PullRequest
1 голос
/ 08 февраля 2011

Хорошо, ребята, я в замешательстве.Итак, у меня есть NSDictionary, который заполняется строкой JSON, которая выглядит следующим образом:

{"Success":true,"Devices":[{"UDId":"...","User":"...","Latitude":0.0,"Longitude":0.0}]}

Теперь я знаю, как проверить, если Success равно true, но мне нужно пройти через массивDevices (объект JSON) и создайте внутренний массив Devices (внутренний объект приложения), и я понятия не имею, как это сделать.Может кто-нибудь объяснить, как это сделать?

Вот мои Device.m/h:

#import <CoreLocation/CoreLocation.h>
#import <Foundation/Foundation.h>

@interface Device : NSObject {
    NSString *udId;
    NSString *name;
    NSNumber *latitude;
    NSNumber *longitude;
}

@property (nonatomic, retain) NSString *udId;
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSNumber *latitude;
@property (nonatomic, retain) NSNumber *longitude;

#pragma mark -
#pragma mark MKAnnotation Properties
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;

@end

----

#import "Device.h"

@implementation Device

@synthesize udId, name, latitude, longitude;

- (CLLocationCoordinate2D)coordinate {
    CLLocationCoordinate2D internalCoordinate;

    internalCoordinate.latitude = [self.latitude doubleValue];
    internalCoordinate.longitude = [self.longitude doubleValue];

    return internalCoordinate;
}

- (void)dealloc {
    [udId release];
    udId = nil;

    [name release];
    name = nil;

    [latitude release];
    latitude = nil;

    [longitude release];
    longitude = nil;

    [super dealloc];
}

@end

А вот методы, где я должен читать ответ и преобразовывать его в объекты, которые я могу использовать:

- (void)requestFinished:(ASIHTTPRequest *)request {
    if (![request error]) {
        NSError *jsonError = nil;
        NSDictionary *jsonDictionary = [NSDictionary dictionaryWithJSONString:[request responseString] error:&jsonError];

        if (!jsonError || ([[jsonDictionary objectForKey:@"Success"] intValue] == 1)) {
            //  READ "DEVICES" AND CONVERT TO OBJECTS
        } else {
            //  AUTHORIZATION FAILED
        }
    }
}

Буду очень признателен за помощь в этом.Я просто не могу обернуться вокруг него ...

Заранее спасибо!

Ответы [ 4 ]

3 голосов
/ 08 февраля 2011

Вы почти у цели. В вашем коде, где вы говорите:

  //  READ "DEVICES" AND CONVERT TO OBJECTS

сделать это:

  NSArray * devices = [jsonDictionary objectForKey:@"Devices"];
  for(NSDictionary * deviceInfo in devices) {
    Device * d = [[[Device alloc] init] autorelease];
    [d setLatitude:[deviceInfo objectForKey:@"Latitude"]];
    [d setLongitude:[deviceInfo objectForKey:@"Longitude"]];
    [d setName:[deviceInfo objectForKey:@"User"]];
    [d setUdId:[deviceInfo objectForKey:@"UDId"]];
    // do some stuff with d
  }

Что здесь происходит: я не видел, какую библиотеку JSON вы используете для преобразования, но, предположив, что она работает как TouchJSON или SBJSON, массив JSON автоматически превращается в экземпляр NSArray, а внутренние хэши NSArray NSDictionary объекты. В тот момент, когда вы десериализовали эту строку JSON, все, с чем вы имеете дело, будет экземплярами NSString, NSNumber, NSArray и NSDictionary (и в зависимости от библиотеки NSNull представляет нулевые значения).

1 голос
/ 08 февраля 2011

Сначала вам нужно определить инициализатор / конструктор для вашего класса устройств.

Device.h

- (id)initWithUdid:(NSString *)udid name:(NSString *)name latitude:(NSNumber *)lat longitude:(NSNumber *)lon;

Device.m

- (id)initWithUdid:(NSString *)udid name:(NSString *)name latitude:(NSNumber *)lat longitude:(NSNumber *)lon {
    if (self = [super init]) {
        self.udid = udid;
        self.name = name;
        self.latitude = lat;
        self.longitude = lon;
    }
    return self;
}

Затем вы можетеИнициализируйте новый объект, например:

Device *dev = [[Device alloc] initWithUdid:@"a udid" name:@"the name" latitude:latNum longitude:lonNum];

Итак, вы должны иметь возможность выполнять итерацию массива и создавать объекты Device следующим образом:

NSArray *devicesArray = [dict objectForKey:@"Devices"];
for (NSDictionary *d in devicesArray) {
  Device *dev = [[Device alloc] initWithUdid:[d objectForKey:@"UDId"]
                                        name:[d objectForKey:@"User"]
                                    latitude:[NSNumber numberWithDouble:[d objectForKey:@"Latitude"]]
                                   longitude:[NSNumber numberWithDouble:[d objectForKey:@"Latitude"]]];
}
0 голосов
/ 08 февраля 2011

Похоже, вам нужно повторно использовать вашу линию:

[jsonDictionary objectForKey:@"Success"]

попробуйте взглянуть на

[jsonDictionary objectForKey:@"Devices"]

Вам действительно нужно выяснить, какой тип он возвращает. Если вам повезет, он возвращает NSDictionary, или, альтернативно, то, что вы легко можете превратить в NSDictionary.

0 голосов
/ 08 февраля 2011

Вы хотите получить доступ к массиву словарей устройств из словаря верхнего уровня так же, как вы указали значение Success.Затем перебирая словари, вы можете использовать метод -keyEnumerator каждого для перебора его ключей.

- (void)requestFinished:(ASIHTTPRequest *)request {
    if (![request error]) {
        NSError *jsonError = nil;
        NSDictionary *jsonDictionary = [NSDictionary dictionaryWithJSONString:[request responseString] error:&jsonError];

        if (!jsonError || ([[jsonDictionary objectForKey:@"Success"] intValue] == 1)) {
            NSArray* deviceArray = [jsonDictionary objectForKey:@"Devices"];
            for(NSDictionary* dict in deviceArray)
            {
                for(NSString* key in [dict keyEnumerator])
                {
                    NSLog(@"%@ -> %@", key, [dict objectForKey:key]);
                }
            }
            //  READ "DEVICES" AND CONVERT TO OBJECTS
        } else {
            //  AUTHORIZATION FAILED
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...