Как переопределить Alamofire SessionManager, чтобы изменить ответ, чтобы добавить заголовки?

Итак, я использую Alamofire для выполнения некоторых HTTP-запросов и пытаюсь использовать политику кэширования, но сервер не имеет флага «Cache-Control» в своих заголовках. Поэтому я хочу добавить этот флаг с помощью диспетчера сеансов делегат метод dataTaskWillCacheResponse на основе этого ответа здесь.

Для этого я хотел создать класс со статическим общим экземпляром (я не хочу создавать глобальную переменную в AppDelegate. Я думаю, что это не очень хорошая практика) SessionManager и в этом класс переопределяет метод делегата, но я не могу этого сделать.

Вот мой код:

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

На self.manager.delegate = self я получаю сообщение об ошибке: Невозможно назначить свойство: «делегат» - это константа «let»

Я относительно новичок в Swift и Alamofire. Что я делаю не так? И как я могу добиться того, что я пытаюсь сделать?

Изменить: я увидел, что не смог создать синглтон, но смог использовать общий экземпляр и переопределить методы. Проверьте ответ ниже


person Nathan Barreto    schedule 09.07.2018    source источник
comment
Любая конкретная причина для синглтона? Вам это не нужно. SessionManager создает и назначает своего делегата во время своего init()   -  person SirCJ    schedule 09.07.2018
comment
Никто. Я подумал, что это будет хорошим решением, и я смогу переопределить методы делегата в классе singleton.   -  person Nathan Barreto    schedule 09.07.2018
comment
Вы уже можете переопределить dataTaskWillCacheResponse, это открытая переменная. См. Переопределение замыканий в Alamofire Docs.   -  person SirCJ    schedule 09.07.2018
comment
Да, это то, с чем я играю. Я думаю, что мог бы это сделать, но я не могу редактировать cachedResponse.   -  person Nathan Barreto    schedule 09.07.2018


Ответы (1)


После дополнительных исследований я обнаружил следующее:
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)
        }
    }
}
person Nathan Barreto    schedule 10.07.2018
comment
Да, это так. Просто вызовите тот же URL-адрес, и если ответ кэшируется, он вернет его. - person Nathan Barreto; 03.08.2018
comment
Он вернет кешированный ответ, если максимальный возраст не истек - person Nathan Barreto; 03.08.2018