加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 04:49:25 所属栏目:百科 来源:网络整理
导读:如要查看完整代码,请移步仿煎蛋github 1、几个要点 单例 + (AFHTTPRequestOperationManager *)sharedHTTPOperationManager { static AFHTTPRequestOperationManager *manager = nil ; static dispatch_once_t pred; dispatch_once (pred,^{ manager = [AFHT

如要查看完整代码,请移步仿煎蛋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、封装的目的

  • 统一处理,减少重复代码

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读