1

AFNetworking用作一个很好的库来使用网络。通常我有一些API类来处理对服务器的所有请求。API类是一个单例,包括一些基本 url 配置,几个块(闭包)成功和失败通常将数据传递回请求的控制器(对象)并更新 UI/呈现新的视图控制器等。

我的问题是可以直接在 API 类中处理警报错误。例如,如果我们收到一些错误表单服务器,我是否需要直接在 API 类中处理这些错误,或者我需要将它们传递回控制器,并且控制器基于带有错误类型的回调将显示所需的带有硬编码信息的警报。比如“您输入了错误的电子邮件或密码”等。

这个最佳实践也是在成功块或失败块中处理来自后端的错误,AFNetworking例如当我们GET/POST/PUT/DELET做某事时。

据我所知,我们有很多可以自动处理的 http 代码错误(状态代码 400 错误请求等)。但是,如果这是自定义错误,哪种状态代码更适合这种情况呢?我猜答案是——我们应该使用failure回调来处理来自服务器的错误。但是如果这个自定义错误要澄清的话。

总结

  1. 第一个问题是关于根据错误向用户显示警报的实现。我们应该为此使用哪个类(或视情况而定)。
  2. 第二个问题是关于成功/失败块应该处理自定义错误,或者我们需要switch每次在失败块中出错AFNeteworking
4

2 回答 2

0

第一个问题是关于根据错误向用户显示警报的实现。我们应该为此使用哪个类(或视情况而定)。

在这一点上,应该考虑到相当多的选择。但我会分享我的经验。为了解决此类问题,我使用自己的类来显示应用程序中的警报。这是由于在一个类中对警报的高度定制。

例子 :

CustomAlertController.alert("Test title", message: "message", acceptMessage: "OK") { () -> () in

}

根据您使用的模式,您可以定义应该在哪里显示警报。在我的应用程序中,我使用的是 MVC。所以我的 ViewController 类应该显示基于 MVC 规则的警报对话框。

例子

 MainViewController -> (Ask for data) NetworkController -> (Response with completion block) -> MainViewController -> (Show alert with response)

第二个问题是关于应该处理自定义错误的成功/失败块,或者我们需要每次在 AFNeteworking 的失败块中切换错误

我喜欢研究在Github上展示的新框架(Moya),所以我找到了一个让我了解易于使用和管理框架的愿景,它提供了处理网络请求的机会。因此,基于它们,您可以回答您的问题。

Moya的小例子:

provider.request(.Zen) { result in
    switch result {
    case let .Success(moyaResponse):
        // do something with the response data or statusCode
    case .Failure(error):
        // this means there was a network failure - either the request
        // wasn't sent (connectivity), or no response was received (server
        // timed out).  If the server responds with a 4xx or 5xx error, that
        // will be sent as a ".Success"-ful response.
    }
}

由于可以得出使用 switch case 处理请求结果的结论,由于代码的高可读性和简单性,这是一个非常好的方法。

于 2016-04-28T10:29:10.153 回答
0

总结第 1 点:在处理对服务器的所有请求的 API 类(AFHTTPSessionManager 子类)中,添加以下方法代码。API 调用 ---

- (void)getMyRecordsFromServer:(NSString *)url withLastModified:(NSTimeInterval)lastModified callbackHandler:(void (^)(id, NSError *))handler {

  self.requestSerializer = [AFHTTPRequestSerializer serializer];
  self.responseSerializer = [AFHTTPResponseSerializer serializer];


  [self GET:url parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
    handler(responseObject, nil);

} failure:^(NSURLSessionDataTask *task, NSError *error) {

    /**********************************************************************/
    NSHTTPURLResponse *response = error.userInfo[AFNetworkingOperationFailingURLResponseErrorKey];
    NSInteger statusCode = response.statusCode;
    NSLog(@"Error Code=%ld",(long)statusCode);
    NSLog(@"Desc=%@",response.description);
    /**********************************************************************/
    [self baseFailureWithError:error onFailure:handler];

}];

}

呼叫成功----

 - (void)myGetRequestWithSuccess:(void (^)(id))success
              onFailure:(void (^)(NSError *))failure
 {
     [self GET:@"api/object"
           parameters:nil
           success:^(NSURLSessionDataTask *task, id responseObject)
           {
                 // success code here.
           } failure:^(NSURLSessionDataTask *task, NSError *error)
           {
            [[self class] baseFailureWithError:error onFailure:failure];
           }];
 }

之后在 baseFailureWithError:: 类方法中实现通用逻辑,然后回调您的视图控制器以实现用户特定的错误验证。失败调用----

 - (void)baseFailureWithError:(NSError *)error
               onFailure:(void(^)(id responseObject,NSError *error))failure
 {
if (failure){
    NSHTTPURLResponse *response = error.userInfo[@"AFNetworkingOperationFailingURLResponseErrorKey"];

    if ([response isKindOfClass:[NSHTTPURLResponse class]] && response.statusCode == 401){
        NSLog(@"Handle all 401's!");
        // decide show alert or not for point 2
    } else {
        failure(nil, error);
    }
  }
}
于 2016-04-28T18:25:42.223 回答