如何从我的API缓存此响应以防止其他调用?

时间:2019-03-08 07:19:01

标签: ios swift caching

以以下服务为例

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 :(得分:0)

在您的fetchCurrentUser中,您可以检查自己的cachedProfile是否不是nil,然后可以从那里返回。

如果它是nil,则可以继续进行网络呼叫。我认为您不必在这里使用单例。

答案 1 :(得分:0)

您可以将传入的值保存到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)
            }
        }
    }
}

确保Profile对象确认了编码协议。