AFNetworking的集中错误处理

时间:2015-12-14 23:10:08

标签: ios objective-c afnetworking block centralized

我正在寻找一种处理“通用”错误的方法,例如请求超时或连接脱机时。

基本上,我有AFHTTPSessionManager的多个(单例)子类,其中每个子类代表一个处理对不同服务器的请求的客户端。根据AFNetworking的作者的建议,通过覆盖initWithBaseURL来设置每个客户端;这是设置请求/响应序列化程序以及通用标头的位置。这是一个示例客户端:

@implementation APIClient

+ (APIClient *)sharedClient {
    static APIClient *sharedClient = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedClient = [[self alloc] initWithBaseURL:[NSURL URLWithString:@"baseurl.goes.here"]];
    });
    return sharedClient;
}

- (instancetype)initWithBaseURL:(NSURL *)url
{
    self = [super initWithBaseURL:url];

    if(self) {
        // Setup goes here
        self.requestSerializer = [AFHTTPRequestSerializer serializer];
        self.requestSerializer.timeoutInterval = 20.0f;

        self.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/plain", @"text/html", nil];

        [AFNetworkActivityIndicatorManager sharedManager].enabled = YES;

        [AFNetworkActivityLogger sharedLogger].level = AFLoggerLevelDebug;
        [[AFNetworkActivityLogger sharedLogger] startLogging];
    }

    return self;
}

- (void)startPostRequestWithPath:(NSString *)path parameters:(NSDictionary *)parameters successBlock:(APISuccessBlock)success failureBlock:(APIFailureBlock)failure
{
    [self POST:path parameters:parameters
       success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
           success(responseObject);
       } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
           if(isGenericError) {
               // Do something generic here
           }
           else {
               failure(error);
           }
       }];
}

在我的模型中(例如Post),我有一个静态方法,视图控制器可以使用它通过将自己的成功/失败块传递给客户端来获取数据。所以它是这样的:

View Controller --> Model --> Client --> Model --> View Controller. 

这是模型的实现

@implementation Post

+ (void)fetchLatestPost:(void (^)(Post *parsedData, NSError *error))completion
{
    [[APIClient sharedClient] startRequestWithPath:kIndexPath
                                            parameters:nil
                                           requestType:RequestTypePost
                                          successBlock:^(id data) {
                                              NSError *parsingError = nil;
                                              Post *post = [[Index alloc] initWithDictionary:data error:&err];
                                              completion(index, nil);
                                          }
                                          failureBlock:^(NSError *error) {
                                              completion(nil, error);
                                          }
     ];
}

当视图控制器尝试获取Post并且请求超时时,我想隐藏屏幕内容并显示刷新按钮;这个逻辑在我的BaseViewController中实现,以便所有视图控制器都可以重用它。问题是,如何在单击该按钮时重新启动SAME请求?请注意,视图控制器可以使用不同的方法签名从不同模型发出多个请求。任何帮助都会非常感激,因为我似乎无法解决这个问题。

我曾经使用委托处理这个问题,其中BaseViewController将实现“通用”委托方法。但是,我一直在尝试切换到块,虽然它确实有它的优点,但它不允许我使用我的BaseViewController,因为它不能“覆盖”视图控制器的故障块。

0 个答案:

没有答案