全局保存和访问收到的数据

时间:2018-04-18 06:25:45

标签: ios xcode swift4

我试图从服务器获取一些数据并在应用程序中全局使用..

我的意思是,例如,我使用以下代码从服务中获取数据:

struct Service : Decodable{
    let id: Int
    let name, description: String
    let createdAt: String?
    let updatedAt: String?
}

func makeGetCall() {
    let todoEndpoint: String = "http://web.src01.view.beta.is.sa/public/api/services"
    guard let url = URL(string: todoEndpoint) else {
        print("Error: cannot create URL")
        return
    }
    let urlRequest = URLRequest(url: url)

    let config = URLSessionConfiguration.default
    let session = URLSession(configuration: config)

    let task = session.dataTask(with: urlRequest) {
        (data, response, error) in
        guard error == nil else {
            print("error calling GET on /public/api/services")
            print(error!)
            return
        }
        guard let responseData = data else {
            print("Error: did not receive data")
            return
        }
        do {

            let decoder = JSONDecoder()
            decoder.keyDecodingStrategy = .convertFromSnakeCase
            let todos = try decoder.decode([Service].self, from: responseData)
            for todo in todos{
                print(todo.name)
            }

        } catch  {
            print("error trying to convert data to JSON")
            return
        }
    }
    task.resume()
}

此代码在HomeViewController中找到并调用,我可以获取我想要的数据。

但我想在另一个viewcontroller和整个app中访问和使用这些数据......

我怎么做?如何使从函数接收的数据全局保存,以及如何在另一个viewcontroller中使用它?

有人可以告诉我我该怎么做吗?

1 个答案:

答案 0 :(得分:1)

对于这种情况,我们通常使用static数据。它们可以作为单身人士或仅作为静态财产。在您的情况下,缓存数据的静态属性可能很好。我们可以将static属性放在扩展名中,因此添加以下内容可能很不错:

// MARK: - Fetching Data
extension Service {

    private static var cachedServices: [Service]?

    static func fetchServices(_ completion: (_ services: [Service]) -> Void?) {
        if let cachedServices = cachedServices {
            completion(cachedServices)
        } else {
            makeGetCall { services in
                let newServices = services ?? []
                self.cachedServices = newServices
                completion(newServices)
            }
        }
    }

}

现在,来自世界各地的用法正在调用

Service.fetchServices { services in
}

并且此调用可能是异步的,具体取决于数据是否已加载。

如果您需要同步访问它们,并且您确定已加载数据,则只需在扩展中添加另一个方法:

static func getCachedData() -> [Service] {
    return cachedServices ?? []
}

此方法将立即返回,但如果尚未收到数据,则数组将为空。但是你可以在任何地方拨打Service.getCachedData()

此缓存现在仅在您的应用终止之前保留。如果您想要更长时间地保留它们,那么您需要做的就是添加逻辑以将数据保存并加载到文件或用户默认值中。这个逻辑就像是:

private static var cachedServices: [Service]? {
    didSet {
        self.saveServicesToFile(cachedServices)
    }
}

static func fetchServices(_ completion: (_ services: [Service]) -> Void?) 
{
    if let cachedServices = cachedServices {
        completion(cachedServices)
    } else if let saved = self.loadFromFile() {
        self.cachedServices = saved
        completion(saved)
    }else {
        makeGetCall { services in
            let newServices = services ?? []
            self.cachedServices = newServices
            completion(newServices)
        }
    }
}