首页 > 解决方案 > How to override Alamofire SessionManager to modify response in order to add headers?

问题描述

So, I'm using Alamofire to make some HTTP requests and I'm trying to use the caching policy but the server doesn't have the "Cache-Control" flag in its headers. So I want to add this flag using the session manager delegate method dataTaskWillCacheResponse based on this answer here.

In order to do that I wanted to create a class with a static shared instance (I don't want to create a global variable on AppDelegate. I think it's not a good practice) of SessionManager and in this class override the delegate method but I can't do.

Here is my code:

public class Manager: SessionDelegate {
    var manager: SessionManager?
    weak var sessionDelegate: SessionDelegate?
    override init() {
        super.init()
        let configuration = URLSessionConfiguration.default
        configuration.urlCache = URLCache(memoryCapacity: 20 * 1024 * 1024, diskCapacity: 100 * 1024 * 1024, diskPath: nil)
        configuration.requestCachePolicy = .returnCacheDataElseLoad
        configuration.timeoutIntervalForRequest = 35
        self.manager = SessionManager(configuration: configuration)
        self.manager = Alamofire.SessionManager(configuration: configuration)
        self.manager?.delegate = self
    }
}

On self.manager.delegate = self I get the error: Cannot assign to property: 'delegate' is a 'let' constant

I'm relatively new in Swift and Alamofire. What am I doing wrong? And how could I achieve what I'm trying to do?

Edit: I saw that I wasn't able to create a singleton but I was able to use a shared instance and override the methods. Check the answer below

标签: iosswiftalamofirensurlcache

解决方案


在研究了更多之后,我发现了一些东西:
1 -高级用法覆盖闭包
2 -找到了创建会话管理器的这个答案
3 -找到了这个解决方案dataTaskWillCacheResponse,它在委托方法 中的我的响应中添加了标题。

这是我的解决方案:

class MyService {
    static let shared = MyService()

    //The manager with the cache policy
    private let manager: Alamofire.SessionManager = {
        let configuration = URLSessionConfiguration.default
        configuration.requestCachePolicy = .useProtocolCachePolicy
        configuration.timeoutIntervalForRequest = 35
        return Alamofire.SessionManager(configuration: configuration)
    }()

    init() {
        let delegate: Alamofire.SessionDelegate = manager.delegate
        //Overriding delegate to add headers
        delegate.dataTaskWillCacheResponseWithCompletion = { session, datatask, cachedResponse, completion in
            let response = cachedResponse.response  as! HTTPURLResponse
            var headers = response.allHeaderFields as! [String: String]
            print(headers.keys.contains("Cache-Control"))
            headers["Cache-Control"] = "max-age=30"
            let modifiedResponse = HTTPURLResponse(
                url: response.url!,
                statusCode: response.statusCode,
                httpVersion: "HTTP/1.1",
                headerFields: headers)

            let modifiedCachedResponse = CachedURLResponse(
                response: modifiedResponse!,
                data: cachedResponse.data,
                userInfo: cachedResponse.userInfo,
                storagePolicy: cachedResponse.storagePolicy)
            completion(modifiedCachedResponse)
        }
    }
}

推荐阅读