SwiftUI — попытка повторного запуска класса из другого представления для принудительной перезагрузки данных

#swiftui

#swiftui

Вопрос:

Я новичок в SwiftUI и иногда сталкиваюсь со всей «декларативной» концепцией, но обычно добиваюсь этого в конце…В любом случае я создал простое приложение, которое загружает данные из удаленного файла JSON в режиме онлайн. Эта часть работает нормально. Затем я хочу сделать, чтобы в другом представлении я вызывал класс fetchData — пытаясь заставить его пересмотреть источник данных и обновить переменные. Похоже, что класс работает нормально, так как операторы печати снова появляются при вызове, но переменные не обновляются новыми значениями.

Вот код для класса для загрузки данных.

     import SwiftUI


struct GetData: Hashable, Codable, Identifiable {
    var id: Int
    var CODE: String
    var RATE: Double
    var TIME: String
    var FLAG: String
    var COUNTRY: String
    var NAME: String
    
   
}



public class FetchData: ObservableObject {
 
  
  // 1.
   @Published var rates = [Rates]()
    @State var showingAlert = true
    
    init() {

        let url = URL(string: "https://www.exampledata.co.uk/example.php")!
        // 2.
        URLSession.shared.dataTask(with: url) { [self](data, response, error) in
            do {
                if let processData = data {
                    // 3.
                    let decodedData = try JSONDecoder().decode([Rates].self, from: processData)
                    DispatchQueue.main.async {
                       
                        self.rates = decodedData
                        print("Data Loaded from Internet")
                        self._showingAlert = State(initialValue: false)
                        
                    }
                } else {
                    print("No data")
                    self.rates=exchange
                    // use diferent method to load data from hardcopy if no internet avail
                    print("Data Loaded from Hardcopy")
                    self._showingAlert = State(initialValue: true)
                }
            } catch {
                print("Error")
                self.rates=exchange
                print("Data Loaded from Hardcopy")
                // use diferent method to load data from hardcopy if server down or general error
                self._showingAlert = State(initialValue: false)
            }
        }.resume()
    }
}
  

Затем в другом представлении, откуда я хочу его вызвать, у меня есть…

         Text("Data last updated:"   RowData.TIME)
            .font(.footnote)
            .foregroundColor(Color.gray)
                Button(action: {
                    FetchData.init()

                }) {
                    HStack{
                    Image(systemName: "arrow.clockwise").resizable()
                        .frame(width: 15.0, height: 15.0)
                        Text("Reload rates")
                            .font(.footnote)
                    }}
        
    }
  

Ответ №1:

2 вещи

Во-первых, @State следует использовать только в View не в ObservableObject соответствии с документацией. Переключитесь @State на @Published .

Во-вторых, и, вероятно, ваша проблема заключается в вашем view . Как вы инициализируете ObservableObject (код недоступен)? это должно быть @ObservedObject , @EnvironmentObject , или @StateObject . Кроме того, убедитесь, что вы не создаете два разных экземпляра, в этом может помочь одноэлементный шаблон @EnvironemntObject или an.