Как перезагрузить экран просмотра при изменении некоторых значений, которые генерируются методом ForEach?

#swiftui

#swiftui

Вопрос:

В настоящее время я разрабатываю приложение с использованием SwiftUI.

Я пытаюсь создать представление для отображения некоторого значения в виде списка, используя вызовы CRUD API.

В случае моих кодов, когда я добавляю или удаляю несколько массивов (списков), представление перезагружает экран, но когда я редактирую некоторые данные в массиве (списке), представление не перезагружает экран новыми значениями…

как я мог решить эту проблему?


Вот коды:

HomeView.swift

 import SwiftUI

struct HomeView: View {
    @EnvironmentObject var appState: AppState
    
    var body: some View {
        NavigationView{
                VStack{
                    ForEach(appState.arrayInfos ?? []){ info in
                        VStack{
                            InfoRow(
                                id: info.id,
                                name: info.name,
                                memo: info.memo ?? "",
                            )
                        }
                        
                        NavigationLink(destination: DetailView(),
                                       isActive: $appState.isNavigateToDetailView){
                            EmptyView()
                        }
                    }
                }
            }.onAppear(){
                appState.makeGetCallInfos()
            }
           
        }
}
  

InfoRow.swift

 import SwiftUI

struct InfoRow: View {
    
    @EnvironmentObject var appState: AppState

    @State var id: Int
    @State var name: String
    @State var memo: String
    
    var body: some View {
             VStack{
               Text(String(id))
               Text(name)
               Text(memo)
             }
    }
}
  

JSONModel.swift

 import Foundation

struct Infos: Codable,Identifiable {
    var id: Int
    var name: String
    var memo: String?
}
  

AppState.swift

 import SwiftUI
import Foundation
import Combine
import UIKit

class AppState: ObservableObject {

    @Published var isNavigateToDetailView:Bool = false

    @Published var infos:Infos?
    @Published var arrayInfos:[Infos]?

func makeGetCallInfos() {
        let endpoint: String = "https://sample.com/api/info/"
        
        guard let url = URL(string: endpoint) else {
            print("Error: cannot create URL")
            return
        }
        var urlRequest = URLRequest(url: url)
        urlRequest.addValue("token xxxxxxxxxxxx", forHTTPHeaderField: "authorization")
        let config = URLSessionConfiguration.default
        let session = URLSession(configuration: config)
        
        let task = session.dataTask(with: urlRequest) {
            (data, response, error) in
            guard error == nil else {
                print("error calling GET")
                print(error!)
                return
            }
            guard let responseData = data else {
                print("Error: did not receive data")
                return
            }
            DispatchQueue.main.async {
                
                do{ self.arrayInfos = try JSONDecoder().decode([Infos].self,from:responseData)
                }catch{
                    print("Error: did not decode")
                    return
                }
            }
        }
        task.resume()
    }
  

Я попытался изменить код следующим образом, но затем у меня возникла ошибка, подобная приведенной ниже:

HomeView.swift

                 VStack{
                    ForEach(appState.arrayInfos ?? []){ info in
                        VStack{
                            InfoRow(
                                id: appState.infos!.id,
                                name: appState.infos!.name,
                                memo: appState.infos!.memo ?? "",
                            )
                        }
                        
                        NavigationLink(destination: DetailView(),
                                       isActive: $appState.isNavigateToDetailView){
                            EmptyView()
                        }
                    }
                }
           
  

сообщение об ошибке

 Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
  

Xcode: версия 12.0.1

Ответ №1:

Я мог бы решить эту проблему, изменив коды, как показано ниже:

удаление @State

InfoRow.swift

 import SwiftUI

struct InfoRow: View {
    
    @EnvironmentObject var appState: AppState

    var id: Int
    var name: String
    var memo: String
    
    var body: some View {
             VStack{
               Text(String(id))
               Text(name)
               Text(memo)
             }
    }
}