gpt4 book ai didi

ios - 重用 API 管理器类和存储数据以使其可重用的最佳方法是什么

转载 作者:行者123 更新时间:2023-11-30 11:07:15 25 4
gpt4 key购买 nike

我有一个 PageViewController,它创建 DataViewController 的实例,并且这个 dataViewController 需要执行一些调用的 API(从管理器类),然后使用该数据来填充其 UI。 IE。添加页面后,dataViewController 获取其数据源并使用该数据源告诉 API 要获取什么。

问题是,因为我可以添加多个页面,并且我需要例如数据来为每个页面形成图表,所以每次 View Controller 加载时都必须执行 API 调用,我觉得这是不值得的,并且必须有是在检索数据后在 session 生命周期内存储数据的更好方法。由于 dataViewController 的每个实例都使用相同的 API 管理器,我刷新它们,清除它们拥有的所有数据,然后再次为加载的页面启动 API 调用,这有时会导致数据混合,显示来自两个页面的混合信息或显示错误的数据出现在错误的页面上。下面是我的一个 API 管理器的示例,它使用 dataViewController 的 dataObject 来获取图表数据:

import Foundation

struct Root: Codable {
let prices: [Price]
}
struct Price: Codable {
let date: Date
let price: Double
}

class CGCharts {

var priceData = [Price]()
var graphPrices: [Double] = []
var graphTimes: [String] = []

static let shared = CGCharts()

var defaultCurrency = UserDefaults.standard.string(forKey: "DefaultCurrency")!

var coin = ""
var currency = ""
var days = ""

enum GraphStatus {
case day, week, month
}

var graphSetup = GraphStatus.day

func getData(arr: Bool, completion: @escaping (Bool) -> ()) {

switch graphSetup {

case .day:
days = "1"
case .week:
days = "14"
case .month:
days = "30"

}

let urlJSON = "https://api.coingecko.com/api/v3/coins/\(coin)/market_chart?vs_currency=\(defaultCurrency)&days=\(days)"

guard let url = URL(string: urlJSON) else { return }

URLSession.shared.dataTask(with: url) { (data, response, err) in

guard let data = data else { return }

do {
let prices = try JSONDecoder().decode(Root.self, from: data).prices
print(prices.first!.date.description(with:.current)) // "Saturday, September 1, 2018 at 6:25:38 PM Brasilia Standard Time\n"
print(prices[0].price)
self.priceData = prices

for element in prices {
self.graphPrices.append(element.price)
}
for element in prices {
self.graphTimes.append(element.date.description(with: nil))

}

completion(arr)

} catch {
print(error)
}

}.resume()

}

func refresh(arr: Bool, completion: @escaping (Bool) -> ()) {

defaultCurrency = UserDefaults.standard.string(forKey: "DefaultCurrency")!
graphPrices = []
graphTimes = []


completion(arr)
}

}
正如你所看到的,我正在获取数据,使用可编码来解析,在这种情况下,我能找到的分离数据的最佳方法是使用两个数组,我基本上希望将 2 个数组存储在内存中对于该特定的数据对象,这样当在 pageView 中加载具有相同数据对象的页面时,它会首先检查该数据是否已经存在,并使用它,而不是每次都获取新信息,而我必须清除该类。希望我说得有道理,谢谢。

最佳答案

在研究了有关 NSCache 的更多信息后,我了解到您可以将数据保存到磁盘或缓存并轻松地再次访问它。我发现 Saoud M. Rizwan here 制作的这个出色的存储类

这使得存储结构变得非常容易:

var messages = [Message]()

for i in 1...4 {
let newMessage = Message(title: "Message \(i)", body: "...")
messages.append(newMessage)
}

Storage.store(messages, to: .documents, as: "messages.json")

并检索它们:

let messagesFromDisk = Storage.retrieve("messages.json", from: .documents, as: [Message].self)

非常适合存储来自 API 的数据,这样您就不必进行如此多的 API 调用,如果您的请求有限,这尤其有用。就我而言,我使用该方法来检查存储是否存在,如果存在,我使用它来加载数据,如果不存在,则我执行 api 调用,使用此类存储数据,然后再次运行检查以看到数据在那里并使用它,它可能不是最有效的,但它有效。

我的例子:

var prices: [Double] = []
var days: [String] = []
var priceData = [Price]()

var graphDataExists = false
func checkGraphStorage() {
if Storage.fileExists("\(dataObject)GraphPrices", in:
Storage.Directory.caches) {
print("UsingSavedData")
self.priceData = Storage.retrieve("\(dataObject)GraphPrices", from:
Storage.Directory.caches, as: [Price].self)

if self.prices.isEmpty {
for element in self.priceData {
self.prices.append(element.price)
}
for element in self.priceData {
self.days.append(element.date.description(with: nil))
graphDataExists = true

}
} else {

}
DispatchQueue.main.async {
self.chartView.animate(xAxisDuration: 4.0)
self.lineChartUpdate(dataPoints: self.days, values: self.prices)
}


} else {
self.prepareGraph(arr: true) { (success) in

}

}
}

关于ios - 重用 API 管理器类和存储数据以使其可重用的最佳方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52571718/

25 4 0
文章推荐: javascript - 为什么