我正在寻找一种处理“通用”错误的方法,例如请求超时或连接脱机时。
基本上,我有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,因为它不能“覆盖”视图控制器的故障块。