用 Alamofire 拦截每一个响应

Posted

技术标签:

【中文标题】用 Alamofire 拦截每一个响应【英文标题】:Intercepting EVERY response with Alamofire 【发布时间】:2016-06-08 16:19:27 【问题描述】:

我只是在探索使用 Alamofire,它非常棒,但我想做一些我觉得可能的事情,只是不知道怎么做。

我们与服务器的身份验证使用一次性承载令牌。因此,对于发出的每个请求,我都必须存储随该请求发送的新令牌。

我想做的是拦截每个返回的响应并检查Authorisation 标头。保存到磁盘,然后转发到等待实际数据的地方。

Alamofire 可以做到这一点吗?

如果是这样,请您指出正确的方向。

谢谢

【问题讨论】:

【参考方案1】:

好的,经过一番搜索 github 和挠头后,我决定通过扩展 Request 类型来创建一个新的响应序列化器。

我像这样创建了一个新的saveAuth() 块......

extension Request 
    public static func AuthSaver() -> ResponseSerializer<Bool, NSError> 
        return ResponseSerializer  request, response, data, error in
            guard error == nil else  return .Failure(error!) 

            if let auth = response?.allHeaderFields["Authorization"] as? String 
                Router.OAuthToken = auth // this uses a didset on the Router to save to keychain
            

            return .Success(true)
        
    

    public func saveAuth() -> Self 
        return response(responseSerializer: Request.AuthSaver()) _ in
    

我可以这样称呼它……

Alamofire.request(Router.Search(query: query))
    .validate()
    .responseSaveAuth() // this line
    .responseJSON 
        response in
        // ...

它仍然需要在每个我想要去除新发送的身份验证令牌的地方添加,但这意味着我也可以选择何时不这样做,它是一行代码。

这可能不是扩展程序中最优雅的代码(我仍在掌握这一切),但它使每次保存身份验证变得更加容易。

【讨论】:

您可以编写一个工厂方法,每次都为您提供Alamofire.request(...).responseSaveAuth(),并根据需要附加您的附加.responseJSON() 或其他响应处理。这样,您永远不会忘记将.responseSaveAuth() 添加到您的请求中。将来可能会使您免于奇怪的边缘情况。 ;-) @72A12F4E 我在回家的路上正在考虑这个问题。明天可能必须尝试实施它。谢谢:-) 如果你觉得你的工厂方法变得太大,你应该遵循@RichmondWatkins 的建议,编写你自己的 NetworkController 类,它只使用 Alamofire 和你的默认操作,比如 responseSaveAuth()【参考方案2】:

我已经通过在我的应用程序中只有一个地方发送网络请求来解决这个问题。基本上,我有一个“网络管理器”,它构建 NSURLRequests 并将它们传递给一个实际发送请求的函数(在我的例子中,它是一个 NSOperation 子类)。这样我只有一个位置可以读取回复。

【讨论】:

以上是关于用 Alamofire 拦截每一个响应的主要内容,如果未能解决你的问题,请参考以下文章

为啥我无法从 Alamofire 获取请求结果

在 Alamofire 4.0 中初始化 SessionManager

安装库 Alamofire 可能出现错误

强制 Alamofire 在主线程上做所有事情?

用 alamofire 处理 Json 响应

Alamofire 请求大约需要 10 秒