Ответ 1
Это все хорошие рамки для JSON, анализирующие словари или другие примитивы, но если вы хотите избежать много повторяющейся работы, посмотрите http://restkit.org. В частности, проверьте https://github.com/RestKit/RestKit/blob/master/Docs/Object%20Mapping.md Это пример отображения объектов, в котором вы определяете сопоставление для своего класса Учителя, а json автоматически преобразуется в Учителя объект с помощью KVC. Если вы используете сетевые вызовы RestKit, процесс прозрачен и прост, но у меня уже были мои сетевые вызовы, и мне нужно было преобразовать текст ответа json в объект User (учитель в вашем случае), и я, наконец, понял как. Если это вам нужно, отправьте комментарий, и я расскажу, как это сделать с помощью RestKit.
Примечание. Я предполагаю, что json выводится с использованием сопоставленного соглашения {"teacher": { "id" : 45, "name" : "Teacher McTeacher"}}
. Если это не так, но вместо этого, как этот {"id" : 45, "name" : "Teacher McTeacher"}
, тогда не беспокойтесь... object mapping design doc в ссылке показывает вам, как это сделать... несколько дополнительных шагов, но не так уж плохо.
Это мой обратный вызов из ASIHTTPRequest
- (void)requestFinished:(ASIHTTPRequest *)request {
id<RKParser> parser = [[RKParserRegistry sharedRegistry] parserForMIMEType:[request.responseHeaders valueForKey:@"Content-Type"]]; // i'm assuming your response Content-Type is application/json
NSError *error;
NSDictionary *parsedData = [parser objectFromString:apiResponse error:&error];
if (parsedData == nil) {
NSLog(@"ERROR parsing api response with RestKit...%@", error);
return;
}
[RKObjectMapping addDefaultDateFormatterForString:@"yyyy-MM-dd'T'HH:mm:ssZ" inTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]]; // This is handy in case you return dates with different formats that aren't understood by the date parser
RKObjectMappingProvider *provider = [RKObjectMappingProvider new];
// This is the error mapping provider that RestKit understands natively (I copied this verbatim from the RestKit internals ... so just go with it
// This also shows how to map without blocks
RKObjectMapping* errorMapping = [RKObjectMapping mappingForClass:[RKErrorMessage class]];
[errorMapping mapKeyPath:@"" toAttribute:@"errorMessage"];
[provider setMapping:errorMapping forKeyPath:@"error"];
[provider setMapping:errorMapping forKeyPath:@"errors"];
// This shows you how to map with blocks
RKObjectMapping *teacherMapping = [RKObjectMapping mappingForClass:[Teacher class] block:^(RKObjectMapping *mapping) {
[mapping mapKeyPath:@"id" toAttribute:@"objectId"];
[mapping mapKeyPath:@"name" toAttribute:@"name"];
}];
[provider setMapping:teacherMapping forKeyPath:@"teacher"];
RKObjectMapper *mapper = [RKObjectMapper mapperWithObject:parsedData mappingProvider:provider];
Teacher *teacher = nil;
RKObjectMappingResult *mappingResult = [mapper performMapping];
teacher = [mappingResult asObject];
NSLog(@"Teacher is %@ with id %lld and name %@", teacher, teacher.objectId, teacher.name);
}
Вы можете, очевидно, реорганизовать это, чтобы сделать его более чистым, но это теперь решает все мои проблемы.. больше не синтаксический анализ... просто ответ → magic → Object