How to override Alamofire SessionManager to modify response in order to add headers?

3.2k Views Asked by At

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

1

There are 1 best solutions below

2
Nathan Barreto On

After researching more, I found some things:
1 - Advanced usage override closures
2 - Found this answer that creates a Session Manager
3 - Found this solution that adds headers on my response in the dataTaskWillCacheResponse delegate method.

This is my solution:

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)
        }
    }
}