gpt4 book ai didi

ios - 我应该如何触发 SwiftUI 应用程序中的网络调用以刷新应用程序打开时的数据?

转载 作者:行者123 更新时间:2023-12-01 15:40:31 26 4
gpt4 key购买 nike

我正在编写一个 SwiftUI 应用程序,我希望它定期从服务器刷新数据:

  • 首次打开应用时
  • 如果应用进入前台且数据在过去5分钟内没有更新

下面是我到目前为止的代码。

首次在 SwiftUI 应用程序中打开应用程序时触发此更新代码的最佳方式是什么?在 onAppear 中添加观察者是否是在应用程序进入前台时触发更新的好习惯? (这是应用程序中的唯一 View )

class InfoStore {

var lastValueCheck: Date = .distantPast
}

struct ContentView : View {

var infoStore: InfoStore

private func updateValueFromServer() {

// request updated value from the server

// if the request is successful, store the new value

currentValue = 500
UserDefaults.cachedValue = 500
// hardcoded for this example

infoStore.lastValueCheck = Date()
}

private func updateValueIfOld() {

let fiveMinutesAgo: Date = Date(timeIntervalSinceNow: (-5 * 60))

if infoStore.lastValueCheck < fiveMinutesAgo {
updateValueFromServer()
}
}

@State var currentValue: Int = 100

var body: some View {
Text("\(currentValue)")
.font(.largeTitle)
.onAppear {
NotificationCenter.default.addObserver(forName: UIApplication.willEnterForegroundNotification,
object: nil,
queue: .main) { (notification) in
self.updateValueIfOld()
}
}
}
}

extension UserDefaults {

private struct Keys {
static let cachedValue = "cachedValue"
}

static var cachedValue: Int {
get {
return standard.value(forKey: Keys.cachedValue) as? Int ?? 0
}
set {
standard.set(newValue, forKey: Keys.cachedValue)
}
}
}

最佳答案

1) 关于第一点(应用首次打开):获得所需内容的最佳方法可能是使用 DataBinding 提取 View 外部的逻辑(如 MVVM 所建议的那样) ObservableObject。为了向您展示我的意思,我尽可能少地更改了您的代码:

import SwiftUI

class ViewModel: ObservableObject {
@Published var currentValue = -1
private var lastValueCheck = Date.distantPast

init() {
updateValueFromServer()
}

func updateValueIfOld() {
let fiveMinutesAgo: Date = Date(timeIntervalSinceNow: (-5 * 60))

if lastValueCheck < fiveMinutesAgo {
updateValueFromServer()
}
}

private func updateValueFromServer() {
// request updated value from the server

// if the request is successful, store the new value

currentValue = 500
UserDefaults.cachedValue = 500
// hardcoded for this example

lastValueCheck = Date()
}
}

struct ContentView : View {

@ObservedObject var viewModel: ViewModel

var body: some View {
Text("\(viewModel.currentValue)")
.font(.largeTitle)
.onAppear {
NotificationCenter.default.addObserver(forName: UIApplication.willEnterForegroundNotification,
object: nil,
queue: .main) { (notification) in
self.viewModel.updateValueIfOld()
}
}
}
}

extension UserDefaults {

private struct Keys {
static let cachedValue = "cachedValue"
}

static var cachedValue: Int {
get {
return standard.value(forKey: Keys.cachedValue) as? Int ?? 0
}
set {
standard.set(newValue, forKey: Keys.cachedValue)
}
}
}

#if DEBUG
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(viewModel: ViewModel())
}
}
#endif

这样,一旦创建了 ViewModel,就会更新 currentValue。此外,每次服务器调用更改 currentValue 时,都会自动为您重新创建 UI。请注意,您必须以这种方式修改 sceneDelegate:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: ContentView(viewModel: ViewModel()))
self.window = window
window.makeKeyAndVisible()
}
}

2) 关于第二点(应用程序进入前台):你在这里应该小心,因为你要多次注册观察者(每次 onAppear 被触发)。根据您的需要,您应该决定:

  • 移除观察者onDisappear(这个很频繁)
  • 只需添加一次观察者,检查您是否已经添加了它。

在任何情况下,实现以下内容都是一个很好的做法:

deinit {

}

方法并最终移除观察者。

关于ios - 我应该如何触发 SwiftUI 应用程序中的网络调用以刷新应用程序打开时的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57392717/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com