将 EnvironmentObject 传递给 ObservableObject 类

xp3*_*3dx 3 ios swift swiftui

我制作了一个 SwiftUI 应用程序,可以重复获取遥测数据以更新自定义视图。这些视图使用存储在环境对象中的变量。

struct updateEO{
    @EnvironmentObject var settings:UserSettings
    func pushSettingUpdate(telemetry: TelemetryData) {
        settings.info = telemetry
        print(settings.info)
    }
}

class DownloadTimer : ObservableObject {
    var timer : Timer!
    let didChange = PassthroughSubject<DownloadTimer,Never>()
    @Published var telemetry = TelemetryData()
    func start() {
        connectToClient()
        self.timer?.invalidate()
        self.timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) {
            _ in
            guard let url = URL(string: "http://127.0.0.1:25555/api/telemetry") else {
                print("Invalid URL")
                return
            }

            let request = URLRequest(url: url)

            URLSession.shared.dataTask(with: request) { data, response, error in
                if let data = data {
                    if let decodedResponse = try? JSONDecoder().decode(TelemetryData.self, from: data) {
                        DispatchQueue.main.async {
                            updateEO().pushSettingUpdate(telemetry: decodedResponse)
                        }
                        return
                    }
                }
            }.resume()
        }
    }
}

Run Code Online (Sandbox Code Playgroud)

在运行时,当遥测数据传递到 时pushSettingUpdate(telemetry: decodedResponse),应用程序崩溃并出现“致命错误:找不到 UserSettings 类型的 ObservableObject”错误。我知道我可能需要传递环境对象的结构,但我不确定如何做到这一点。任何帮助将非常感激。谢谢!:)

Nic*_*ica 7

您应该@EnvironmentObject在您的视图中使用并根据需要将其传递给您的模型。

这里,struct updateEO不是景色。

我创建了一个更简单的示例来向您展示如何执行此操作:

用户设置

class UserSettings: ObservableObject {
    @Published var info: String = ""
}
Run Code Online (Sandbox Code Playgroud)

下载定时器

class DownloadTimer: ObservableObject {
    var timer : Timer?
    
    func start(settings: UserSettings) {
        self.timer?.invalidate()
        self.timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { t in
            settings.info = t.fireDate.description
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当 出现时,您可以调用start(作为UserSettings参数)Text

我的看法

struct MyView: View {
    @StateObject private let downloadTimer = DownloadTimer()
    @EnvironmentObject var settings: UserSettings
    
    var body: some View {
        Text(settings.info)
            .onAppear {
                self.downloadTimer.start(settings: self.settings)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并且不要忘记调用.environmentObject函数来注入您的UserSettingsin SceneDelegate

场景委托

let contentView = MyView().environmentObject(UserSettings())
Run Code Online (Sandbox Code Playgroud)

您应该看到文本随着时间的推移而更新。