Самый простой способ передать @Published data в Textfield ()? - PullRequest
0 голосов
/ 15 января 2020

Сценарий: Я использую Observable Class для получения данных из сети. В этом случае некоторые элементарные данные о погоде.

Проблема: Я не знаю, как отобразить эти данные в вызывающем представлении.

В настоящее время я просто пытаюсь заполнить текстовое поле (и позже буду беспокоиться о макете с большим количеством элементов).

Я получаю следующее:

... / StandardWeatherView.swift: 22: 13: Невозможно вызвать инициализатор для типа 'TextField <_>' со списком аргументов типа '(Text, text: Sample?) '

Вот мой вызывающий вид, который является получателем данных @ObservedObject:

import SwiftUI

struct StandardWeatherView: View {
    @EnvironmentObject var settings: Settings
    @ObservedObject var standardWeatherReportLoader = StandardWeatherReportLoader()

    init() {
        self.standardWeatherReportLoader.doStandard()
    }

    var body: some View {
        ZStack {
            Color("FernGreen").edgesIgnoringSafeArea(.all)
            TextField(Text("Weather Data"), text: standardWeatherReportLoader.weatherReport)
        }
    }
}

struct StandardWeatherView_Previews: PreviewProvider {
    static var previews: some View {
        StandardWeatherView()
    }
}

Вот издатель, собирающий данные :

import Foundation

class StandardWeatherReportLoader: ObservableObject {
    @Published var networkMessage: String?
    @Published var hasAlert = false
    @Published var weatherReport: Sample?
    @Published var hasReport = false

    func doStandard() {
        let url = EndPoint.weather.path()
        var request = URLRequest(url: EndPoint.weather.path()!)
        request.httpMethod = "GET"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")

        let task = URLSession.shared.dataTask(with: url!) { (data: Data?, _: URLResponse?, error: Error?) -> Void in
            DispatchQueue.main.async {
                guard error == nil else {
                    self.networkMessage = error?.localizedDescription
                    self.hasAlert = true
                    return
                }

                do {
                    let decoder = JSONDecoder()
                    decoder.keyDecodingStrategy = .convertFromSnakeCase
                    let result = try decoder.decode(Sample.self, from: data!)
                    self.weatherReport = result
                    self.hasReport = true
                    print("\n Standard Weather ----------------")
                    print(#function, "line: ", #line, "Result: ",result)
                    print("\n")
                } catch let error as NSError {
                    print(error)
                }
            }
        }
        task.resume()
    }
}

Какой самый простой способ передачи строки данных в представление через @Published var?

Журнал:

Стандартная погода ---------------- doStandard () строка: 38 Результат: Образец (координировать: DataTaskPubTab.Coord (длительность: -0,13, широта: 51,51), погода: [DataTaskPubTab.Weather (id: 300, основной: «Морось»), описание: «моросящий дождь»), база: «станции», основная: DataTaskPubTab.Main ( температура: 280,32, давление: 1012, влажность: 81, температура: 279,15, температура: 281,15), видимость: 10000, ветер: DataTaskPubTab.Wind (скорость: 4,1, град: 80), облака: DataTaskPubTab.Clouds (все: 90). , dt: 1485789600.0, id: 2643743, имя: "Лондон")

Но я получаю ноль в TextField:

(lldb) po standardWeatherReportLoader.weatherReport nil

1 Ответ

1 голос
/ 15 января 2020

Один из вариантов - установить привязку внутри вашего тела, чтобы отслеживать, когда обновляется TextField. Из этой привязки вы можете затем отредактировать вашу переменную «Публикация» при помощи sh:

@ObservedObject var reportLoader = StandardWeatherReportLoader()

var body: some View {

        // Binding to detect when TextField changes
        let textBinding = Binding<String>(get: {
            self.reportLoader.networkMessage
        }, set: {
            self.reportLoader.networkMessage = $0
        })

        // Return view containing the text field
        return VStack {

                TextField("Enter the Network Message", text: textBinding)
        }
}

Редактировать: также в исходном сообщении вы передавали объект необязательного типа Sample в TextField, который был ожидание связующего типа String, который может вызвать некоторые проблемы.

...