Обычно создаются объектные модели, которые будут представлены в формате JSON. Когда вы получите ответ, вы затем разберете данные в модели. Подход, который мы используем, заключается в том, чтобы вернуть ответ запрашивающей стороне через блок завершения. Вам не нужно разбирать JSON на строго типизированные объекты, но это действительно полезно в долгосрочной перспективе. Вероятно, было бы неплохо также выделить операции сетевых запросов в отдельный класс (называемый службой). Таким образом, вы можете создать экземпляр новой службы и получить уведомление через блок завершения о том, что она завершена. Например, подпись запроса вашего сервиса может выглядеть так:
typedef void(^HelloWorldCompletionHandler)(NSString *helloWorld, NSError *error);
- (void)requestHelloWorldData:(HelloWorldCompletionHandler)completionHandler;
// implementation
- (void)requestHelloWorldData:(HelloWorldCompletionHandler)completionHandler {
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:@"http://someapi.com/hello.json" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
id JSONResponse = [operation responseObject];
if (operation.error) {
completionHandler(nil, error);
} else {
// parse the response to something
id parserResult = [self parseJSONResponse:JSONResponse];
completionHandler(parserResult, nil);
}
}];
Таким образом, вы будете знать, когда сетевой запрос будет завершен, и вы сможете установить нужные данные для свойства в вашем классе. Затем вы можете вызвать tableView.reloadData, чтобы использовать данные в своей таблице.
Весь этот код попадет в класс типа службы. Мне нравится организовывать свои услуги по принципу ответственности. Я не знаю, сколько различных вызовов данных вы делаете, но у нас есть несколько для нашего проекта. Если, например, вы делаете приложение о погоде, вы потенциально можете организовать его по Текущим условиям, Ежедневным прогнозам и Почасовым прогнозам. Я бы сделал услугу для каждого из этих запросов. Скажем, я создал CurrentConditionsService. Заголовок будет выглядеть примерно так:
typedef void(^CurrentConditionsCompletionHandler)(CurrentConditions *currentConditions, NSError *error);
@interface CurrentConditionsService : NSObject
// locationKey is some unique identifier for a city
+ (instancetype)serviceWithLocationKey:(NSString *)locationKey;
- (void)retrieveCurrentConditionsWithCompletionHandler:(CurrentConditionsCompletionHandler)completionHandler;
@end
Затем в моем файле реализации я бы сделал запрос и вызвал данный обработчик завершения, как показано выше. За этим шаблоном может следовать множество различных сервисов до такой степени, что все ваши сервисы могут наследоваться от базового класса, который обрабатывает части запроса/ответа. Затем ваши подклассы могут переопределять определенные методы и соответствующим образом обрабатывать/анализировать данные в зависимости от типа.
Если вы пойдете по пути разбора ответов JSON в объекты модели, все ваши парсеры должны будут соответствовать протоколу. Таким образом, в вашем суперклассе не имеет значения, какова конкретная реализация вашего парсера. Вы предоставляете суперклассу конкретную реализацию, и все, что он умеет делать, — это вызывать синтаксический анализатор и возвращать ответ.
Пример протокола парсера JSON будет выглядеть так:
@protocol AWDataParser <NSObject>
@required
- (id)parseFromDictionary:(NSDictionary *)dictionary;
- (NSArray *)parseFromArray:(NSArray *)array;
@end
И вызывая его в суперклассе ваших услуг:
- (id)parseJSONResponse:(id)JSONResponse error:(NSError **)error {
NSAssert(self.expectedJSONResponseClass != nil, @"parseResponse: expectedJSONResponseClass cannot be nil");
NSAssert(self.parser != nil, @"parseResponse: parser cannot be nil");
id parserResult = nil;
if (![JSONResponse isKindOfClass:self.expectedJSONResponseClass]) {
//handle invalid JSON reponse object
if (error) {
*error = [NSError errorWithDomain:NetworkServiceErrorDomain code:kNetworkServiceErrorParsingFailure userInfo:@{@"Invalid JSON type": [NSString stringWithFormat:@"expected: %@, is: %@",self.expectedJSONResponseClass, [JSONResponse class]]}];
}
} else {
if (self.expectedJSONResponseClass == [NSArray class]) {
parserResult = [self.parser parseFromArray:JSONResponse];
}else {
parserResult = [self.parser parseFromDictionary:JSONResponse];
}
if (!parserResult) {
if (error) {
*error = [NSError errorWithDomain:NetworkServiceErrorDomain code:kNetworkServiceErrorParsingFailure userInfo:nil];
}
}
}
return parserResult;
}
person
jervine10
schedule
23.02.2014