AFNetworking将逻辑与视图控制器和职责分开以显示数据的最佳实践

时间:2016-04-27 09:52:48

标签: ios afnetworking afnetworking-2 afnetworking-3

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

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

此最佳实践也是处理成功块后端或AFNetworking失败块中的错误,例如我们GET/POST/PUT/DELET时的错误。

据我所知,我们有很多http代码错误,我们可以自动处理,如(状态代码400错误请求等)。但是如果这是自定义错误,那么状态代码对于这种情况更好,我想答案是 - 我们应该使用failure回调来处理来自服务器的错误。但是要澄清这个自定义错误的内容。

总结

  1. 第一个问题是关于根据错误向用户显示警报的实现。我们应该使用哪个类(或者它取决于)。
  2. 第二个问题是关于应该处理自定义错误的成功/失败块,或者每次switch
  3. 的失败块时我们都需要AFNeteworking错误

2 个答案:

答案 0 :(得分: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.
    }
}

由于可以结束使用交换机案例来处理请求结果,因此代码的高可读性和简单性是非常好的方法。

答案 1 :(得分: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 :: class方法中实现泛型逻辑,然后回调给您的视图控制器以实现用户特定的错误验证。 失败电话----

 - (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);
    }
  }
}