使用AFNetWorking和ReactiveCocoa对网络请求进行封装(仿煎蛋iOS)(3)

前端之家收集整理的这篇文章主要介绍了使用AFNetWorking和ReactiveCocoa对网络请求进行封装(仿煎蛋iOS)(3)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

如要查看完整代码,请移步仿煎蛋github

1、几个要点

  • 单例
+ (AFHTTPRequestOperationManager *)sharedHTTPOperationManager {
  static AFHTTPRequestOperationManager *manager = nil;
  static dispatch_once_t pred;
    dispatch_once(&pred,^{
        manager = [AFHTTPRequestOperationManager manager];
        manager.requestSerializer = [AFJSONRequestSerializer new];
        manager.requestSerializer.timeoutInterval = 30.f;//超时时间为30s
    });
    return manager;
}
  • block形式的结果转换成信号(参考AFNetworking-RACExtensions)
/** * 转换成响应式请求 可重用 * *  @param url 请求地址 *  @param params 请求参数 * *  @return 带请求结果(字典)的信号 */
+ (RACSignal *)post2racWthURL:(NSString *)url params:(NSDictionary *)params {
  return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    AFHTTPRequestOperationManager *manager = [self sharedHTTPOperationManager];
    AFHTTPRequestOperation *operation= [manager POST:url parameters:params success:^(AFHTTPRequestOperation * _Nonnull operation,id   _Nonnull responSEObject) {
      //将不通用的地方抽取了出来处理
      [self handleResultWithSubscriber:(id<RACSubscriber>)subscriber operation:operation responSEObject:responSEObject];
    } failure:^(AFHTTPRequestOperation * _Nonnull operation,NSError * _Nonnull error) {
      NSMutableDictionary *userInfo = [error.userInfo mutableCopy] ?: [NSMutableDictionary dictionary];
      userInfo[RAFNetworkingOperationErrorKey] = operation;
      userInfo[RAFNetworkingErrorInfoKey] = [self handleErrorMessage:error];
      [subscriber sendError:[NSError errorWithDomain:error.domain code:error.code userInfo:userInfo]];
    }];
    return [RACDisposable disposableWithBlock:^{
      [operation cancel];
    }];
  }];
}
  • 字典转模型(使用了MJ老师的MJExtension框架)
/** * 响应式post请求 返回处理后的结果 对象类型 可重用 * * @param url 请求地址 * @param params 请求参数 * @param clazz 字典对应的对象 * * @return 带请求结果(对象)的信号 */
+ (RACSignal *)racPOSTWithURL:(NSString *)url params:(NSDictionary *)params class:(Class)clazz {
    return [[[self post2racWthURL:url params:params] map:^id(id responSEObject) {
        return [clazz objectWithKeyValues:responSEObject];
    }] replayLazily];
}
  • 错误处理(1,没有正确返回结果 2,返回结果中带有错误
//第一种情况
+ (NSString *)handleErrorMessage:(NSError *)error {
  NSString *result = nil;
  switch (error.code) {
    case kcfURLErrorTimedOut://-1001
      result = @"服务器连接超时";
      break;
    case kcfURLErrorNotConnectedToInternet: //-1009 @"似乎已断开与互联网的连接。"
    case kcfURLErrorCannotDecodeContentData://-1016 cmcc 解析数据失败
      result = @"您连接的网络不正常,请检查您的网络连接";
      break;
    case kcfURLErrorCannotFindHost: //-1003 @"未能找到使用指定主机名的服务器。"
      result = @"服务器内部错误";
      break;
    default:
      LogBlue(@"其他错误 error:%@",error);
      break;
  }

  return result;
}

//第二种情况
/* { "status": "ok","id": 2774402,} { "status": "error","error": "Post ID '61355' not found." } status:ok error pending 仅适用于本项目 */
+ (void)handleResultWithSubscriber:(id<RACSubscriber>)subscriber operation:(AFHTTPRequestOperation * _Nonnull)operation responSEObject:(NSDictionary * _Nonnull)responSEObject{
  NSString *status=[responSEObject objectForKey:@"status"];
  if ([status isEqualToString:@"ok"]) {
    // [subscriber sendNext:RACTuplePack(operation,responSEObject)];
    [subscriber sendNext:responSEObject];
    [subscriber sendCompleted];
  }else {//正确返回,带有错误信息
    NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
    BOOL isError=[status isEqualToString:@"error"];
    userInfo[RAFNetworkingErrorInfoKey] =isError?[responSEObject objectForKey:@"error"]:@"请求没有得到处理";
    userInfo[RAFNetworkingOperationErrorKey] = operation;
    NSError *error= error=[NSError errorWithDomain:customDomain code:isError?AFNetWorkUtilsResponseError
                                                  :AFNetWorkUtilsResponsePending userInfo:userInfo];
    [subscriber sendError:error];
  }
}

2、封装的目的

  • 统一处理,减少重复代码
原文链接:https://www.f2er.com/react/307796.html

猜你在找的React相关文章