Как я могу кэшировать этот ответ от моего API, чтобы предотвратить дополнительные вызовы? - PullRequest
0 голосов
/ 08 марта 2019

Возьмите следующий сервис в качестве примера

import Foundation
import PromiseKit

protocol ProfileServiceType {
    func fetchCurrentUser() -> Promise<Profile>
}

struct ProfileService: ProfileServiceType {

    private let httpClient: HTTPClientProtocol

    init(httpClient: HTTPClientProtocol) {
        self.httpClient = httpClient
    }

    func fetchCurrentUser() -> Promise<Profile> {
        return httpClient.call(endpoint: ProfilesEndpoint.byUserId, method: .get, urlParams: nil, queryParams: nil, bodyParams: nil)
    }
}

Когда я выбираю для текущего пользователя, я возвращаю его профиль, например, у меня есть несколько сцен в моем приложении, которые могут нуждаться в некотором аспекте пользователяпрофиль, например их userId.Каждый раз, когда я обращаюсь к этому методу, он отправляет сетевой запрос.Поскольку этот вызов выполняется при первом запуске моего приложения, я могу с некоторой гарантией сказать, что я получу эти данные уже до того, как это понадобится любым другим сценам или службам.

Я думал что-то подобное, но потом ямне нужно было бы реализовать одноэлементный шаблон, который, я считаю,

   var cachedProfile: Profile?

    func fetchCurrentUser() -> Promise<Profile> {
        return Promise<Profile> { [weak self] seal in
            return httpClient.call(endpoint: ProfilesEndpoint.byUserId, method: .get, urlParams: nil, queryParams: nil, bodyParams: nil)
                .done { (value: Profile) in
                    self?.cachedProfile = value
                    seal.fulfill(value)
                }.catch { err in
                    seal.reject(err)
            }
        }
    }

Недавно пришедший из F / E-разработки и активно использующий Redux, это для меня новость, и я не совсем уверен, когда имею дело с разработкой для iOS.

Ответы [ 2 ]

0 голосов
/ 08 марта 2019

Вы можете сохранить входящее значение в UserDefaults, а затем вернуть его, если оно существует, в противном случае перейдите к сетевому запросу и сохраните объект.

func fetchCurrentUser() -> Promise<Profile> {
    return Promise<Profile> { [weak self] seal in
        if let data = UserDefaults.standard.object(forKey: "SavedProfile"),
            let savedProfile = try! NSKeyedUnarchiver.unarchivedObject(ofClass: Profile.self, from: data) as? Profile {
            seal.fulfill(savedProfile)
        } else {
            return httpClient.call(endpoint: ProfilesEndpoint.byUserId, method: .get, urlParams: nil, queryParams: nil, bodyParams: nil)
                .done { (value: Profile) in
                    let data = try! NSKeyedArchiver.archivedData(withRootObject: value, requiringSecureCoding: true)
                    UserDefaults.standard.set(value, forKey: "SavedProfile")
                    seal.fulfill(value)
                }.catch { err in
                    seal.reject(err)
            }
        }
    }
}

Убедитесь, что объект профиля соответствует протоколу кодирования.

0 голосов
/ 08 марта 2019

В вашем fetchCurrentUser вы можете проверить, не является ли ваш cachedProfile не nil, а затем вы можете просто вернуться оттуда.

Если это nil, вы можете продолжить выполнение сетевого вызова.Я не думаю, что вы действительно должны использовать синглтон здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...