快速使用 AFHTTPSessionManager

Posted

技术标签:

【中文标题】快速使用 AFHTTPSessionManager【英文标题】:Using AFHTTPSessionManager in swift 【发布时间】:2015-10-19 15:47:07 【问题描述】:

虽然我确实计划将来切换到 Alamofire,但与此同时,我希望将我的 AFHTTPSessionManager 子类从 objc 转换为 swift。我在转换我的自定义 dataTaskWithHTTPMethod 方法时遇到了一些问题。该函数覆盖了AFHTTPSessionManager.dataTaskWithHTTPMethod,因此我可以在请求中添加一些额外的标头并将响应主体传递给失败完成闭包。

@interface WebAPIClient : AFHTTPSessionManager

及实现功能:

- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
                                   URLString:(NSString *)URLString
                                   csrfToken:(NSString *)csrfToken
                                  parameters:(id)parameters
                                     success:(void (^)(NSURLSessionDataTask *, id))success
                                     failure:(void (^)(NSURLSessionDataTask *, NSError *, id))failure

  NSError *serializationError = nil;
  NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[NSURL URLWithString:URLString relativeToURL:self.baseURL].absoluteString parameters:parameters error:&serializationError];
  if (serializationError) 
    if (failure) 
      dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^
        failure(nil, serializationError, nil);
      );
    

  return nil;
  

  if (csrfToken!=nil) 
    [request setValue:@"XMLHttpRequest" forHTTPHeaderField:@"X-Requested-With"];
    [request setValue:csrfToken forHTTPHeaderField:@"X-CSRFToken"];
  


  __block NSURLSessionDataTask *dataTask = nil;
  dataTask = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) 
  if (error) 
    if (failure) 
      failure(dataTask, error, responseObject);
    
   else 
    if (success) 
      success(dataTask, responseObject);
    
  
  ];

  return dataTask;

我很难弄清楚如何重写函数的第一部分。快速处理 NSError 并将其传递给函数的行为不同,我无法使用 NSErrorPointer 替换。

【问题讨论】:

【参考方案1】:

这就是你的方法在 Swift 中的样子:

typealias DataTaskSuccessHandler = (dataTask: NSURLSessionDataTask?, responseObject: AnyObject?) -> ()
typealias DataTaskErrorHandler = (dataTask: NSURLSessionDataTask?, error: NSError?, responseObject: AnyObject?) -> ()

func dataTask(withHTTPMethod httpMethod: String, urlString: String, csfrToken: String?, parameters: AnyObject?, success: DataTaskSuccessHandler?, failure: DataTaskErrorHandler?) -> NSURLSessionDataTask? 
    var dataTask: NSURLSessionDataTask?
    var serializationError: NSError?
    guard let absoluteURLString = NSURL(string: urlString, relativeToURL: baseURL)?.absoluteString else  return nil 
    let request = requestSerializer.requestWithMethod(httpMethod, URLString: absoluteURLString, parameters: parameters, error: &serializationError)
    if serializationError != nil 
        if let failure = failure 
            dispatch_async(completionQueue ?? dispatch_get_main_queue(),  () -> Void in
                failure(dataTask: nil, error: serializationError, responseObject: nil)
            )
        
        return nil
    

    if let csfrToken = csfrToken 
        request.setValue("XMLHttpRequest", forHTTPHeaderField: "X-Requested-With")
        request.setValue(csfrToken, forHTTPHeaderField: "X-CSRFToken")
    

    dataTask = dataTaskWithRequest(request, completionHandler:  (_, responseObject, error) -> Void in
        if let error = error, let failure = failure 
            failure(dataTask: dataTask, error: error, responseObject: responseObject)
         else if let success = success 
            success(dataTask: dataTask, responseObject: responseObject)
        
    )

    return dataTask

我不确定在调用函数时是否需要 successfailure 闭包,因此我将它们定义为可选项。如果您在没有成功和失败处理程序的情况下从不调用该方法,则可以在执行这些闭包时删除这些 Optional 并摆脱 if let

【讨论】:

以上是关于快速使用 AFHTTPSessionManager的主要内容,如果未能解决你的问题,请参考以下文章

使用 AFHTTPSessionManager 时的内存泄漏

AFNetworking 2.0 AFHTTPSessionManager

使用两个不同的 baseUrl - AFHTTPSessionManager

如何使用 AFHTTPSessionManager 访问 422 上的响应正文?

使用 AFNetworking 快速传递参数

如何使用 AFHTTPSessionOperation 或 AFHTTPSessionManager 设置票证?