我正在使用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,这样我就可以在tableview中显示输出。
答案 0 :(得分:2)
创建将由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;
}
答案 1 :(得分:0)
使用这种方法:
NSURL *COMBINAT = [[NSURL alloc] initWithString:@"http://someapi.com/hello.json"];
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL:
COMBINAT];
[self performSelectorOnMainThread:@selector(savedata:) withObject:data waitUntilDone:YES];
});
然后简单地致电:
- (void)savedata:(NSData *)responseData {
NSError* error;
NSLog(@"Answer from server %@", responseData);
// ... your code to use responseData
}
答案 2 :(得分:0)
只需创建一个属性:
@property(nonatomic, strong) id savedResponseObject;
并将其设置在请求的成功处理程序中:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:@"http://someapi.com/hello.json"
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
self.savedResponseObject = responseObject;
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(@"Error: %@", error);
}];
然后,您可以通过引用来访问班级中的其他地方:
self.savedResponseObject