2015-09-03 24 views
2

我正在创建Alamofire请求,并将startRequestsImmediately设置为false。然后我将一个块排入一个NSOperationQueue,该请求调用resume()。如果我需要中止外发请求,我只需暂停队列并让它们缓冲起来。一旦我取消暂停队列,就会分派任何请求。在恢复之前修改Alamofire请求上的标题()d

有时,当队列被暂停时,我需要在那里的任何现有请求(例如授权令牌)上更改标头。我还没有找到办法做到这一点(我尝试的任何东西都没有生效)。 NSURLSessionTask有可能吗?是否有可能换出NSURLSessionTask给定的请求(带有更新的头文件)?

+0

你设法找到对的方法吗? – Yaman

+0

是的,没有。请参阅下面的答案。 – iraxef

回答

2

一旦创建Alamofire.Request,它就会创建一个NSURLSessionTask,并且一旦创建,它就是有效的只读。所以我发现的唯一选择是推迟创建Request,直到我的请求即将运行。

但是,Request对象是您设置响应处理程序的对象。例如,客户想要调用类似于:request().response(...).response(...)。 Alamofire的request()返回Request对象,您可以多次调用response(),以便设置一旦请求完成就会运行的响应处理程序。但是,如果您需要推迟创建Request,直到您知道它即将运行为止,以便您可以在当时使用最新的标头,那么您如何将其返回给客户端,以便他们可以拨打.response()

我所做的是创建一个myRequest()包装(而不是能够覆盖实际request()功能/名)在我的Alamofire.Manager派生类,这需要1个附加参数的方式 - 一个“请求准备”块(它本身需要Alamofire.Request)而不是返回RequestmyRequest(),myRequest(),不会返回任何内容,而是在请求即将分派时调用该块(将其传递给Request)。

因此,像

manager.request(.GET, "endpoint").responseJSON(…)

,而不是成为

manager.myRequest(.GET, "endpoint") { request in 
    request.responseJSON(...) 
} 

这样我可以推迟Alamofire.Request的创建(这立即产生,因为它们是潜在的头NSURLSessionTask和锁在那个时候),直到后来,而不是在他们指定响应处理程序的方式上过多地给客户造成不便。

myRequest()看起来像这样(不包括应用程序特定的东西):

func myRequest(
    method: Alamofire.Method, 
    _ URLString: URLStringConvertible, 
    parameters: [String: AnyObject]? = nil, 
    encoding: ParameterEncoding = .URL, 
    headers: [String: String]? = nil, 
    requestReady: ((Request) -> Void)?) { 

    pendingRequestsQueue.addOperationWithBlock { [weak self] in 
     if let strongSelf = self { 
      let request = strongSelf.request(method, URLString, parameters: parameters, encoding: encoding, headers: headers) 

      if let requestReady = requestReady { 
       requestReady(request) 
      } 

      request.resume() 
     } 
    } 
}