使用AFNetworking GET请求并保存响应

时间:2014-02-23 20:50:49

标签: ios objective-c afnetworking

我正在使用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中显示输出。

3 个答案:

答案 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