我正在用AFNetworking做一个简单的GET请求
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:@"http://someapi.com/hello.json" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
发出请求后,我希望能够responseObject
从类中的任何其他方法访问。
我希望能够保存responseObject,以便可以执行类似在表视图中显示输出的操作。
创建将由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;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句