Я использую комбинацию для подключения к REST API, который извлекает некоторые данные в ObservableObject. Вся установка на самом деле просто MVVM. Затем ObservableObject наблюдается в представлении. Теперь я застрял с ошибкой, которую не могу решить. Кажется, что View отрисовывается дважды. В первый раз он обновляется значениями из ObservedObject. Затем он немедленно перерисовывается, но теперь извлеченные данные внезапно исчезают. Я подтвердил, что код, извлекающий данные, не выполняется во второй раз. Кроме того, средство просмотра иерархии представлений, похоже, предлагает, чтобы текстовые представления, которые должны отображать данные в представлении, каким-то образом удаляются при втором прогоне визуализации.
Вот как выглядит модель (код аутентификации взят из Firebase):
class ItemViewModel: ObservableObject {
@Published var items = [ScheduleItem]()
private var publisher: AnyCancellable?
func fetchData() {
let currentUser = Auth.auth().currentUser
currentUser?.getIDTokenForcingRefresh(false, completion: { idToken, error in
let url = URL(string: "abc")!
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("Bearer "+String(idToken!), forHTTPHeaderField: "Authorization")
self.publisher = URLSession.shared
.dataTaskPublisher(for: url)
.map(\.data)
.decode(
type: [ScheduleItem].self,
decoder: JSONDecoder()
)
.receive(on: DispatchQueue.main)
.sink(
receiveCompletion: { completion in
switch completion {
case .failure(let error):
print("SINKERROR")
print(error)
case .finished:
print("SINKSUCCESS")
}
},
receiveValue: { repo in
print("DONE")
self.items.append(contentsOf: repo)
}
)
})
}
}
Операторы печати выводят DONE SINKSUCCESS Оба они могут быть найдены только один раз в выводе отладки.
Это мнение:
struct TreatmentCardView: View {
let startDate: String
let uid: Int
@ObservedObject var data = ItemViewModel()
@State private var lastTime: String = "2"
var body: some View {
ZStack {
GeometryReader { geometry in
VStack{
Text("Headline")
.font(.title)
.foregroundColor(Color.white)
.padding([.top, .leading, .bottom])
Print("ISARRAYEMPTY")
Print(String(data.items.isEmpty))
Text(String(data.items.isEmpty))
.font(.headline)
.fontWeight(.light)
.foregroundColor(Color.white)
.frame(width: 300, height: 25, alignment: .leading)
.multilineTextAlignment(.leading)
.padding(.top)
}
}
}
.background(Color("ColorPrimary"))
.cornerRadius(15)
.onAppear{
self.data.fetchData()
}
}
}
Print (String (data.items.isEmpty)) сначала имеет значение false, затем true, что указывает на повторную визуализацию представления.
Что для меня немного странно, так это то, что я ожидал, что представление отобразится хотя бы один раз, прежде чем данные будут извлечены, но я не вижу никаких признаков того, что это происходит.
Я уже два дня пытаюсь сказать это слово. Любая помощь и совет приветствуются!