I am engaged on a SwiftUI venture the place I’ve a ShoppingListView that masses and shows purchasing lists from Firestore. The info appears to load appropriately primarily based on print statements within the console, however the lists will not be displaying up within the UI.
Right here’s a breakdown of what’s taking place:
Knowledge Loading (loadLists Perform):
func loadLists() {
isLoading = true
print("🔄 loadLists: Inicio de la carga de listas.")
guard let uid = Auth.auth().currentUser?.uid else {
print("❌ loadLists: No se encontró UID del usuario.")
return
}
let manualRef = Firestore.firestore().assortment("iFoodList").doc(uid)
let premiumRef = Firestore.firestore().assortment("PaidShoppingLists").doc(uid)
let group = DispatchGroup()
var combinedLists: [String: [(item: Any, creationDate: Date?)]] = [:]
group.enter()
manualRef.getDocument { doc, error in
defer { group.go away() }
if let doc = doc, doc.exists, let knowledge = doc.knowledge() {
combinedLists.merge(self.parseListData(knowledge, listType: .handbook)) { present, _ in present }
} else {
print("⚠️ loadLists: La lista 'Nueva 1' no tiene elementos para cargar.")
}
}
group.enter()
premiumRef.getDocument { doc, error in
defer { group.go away() }
if let doc = doc, doc.exists, let knowledge = doc.knowledge() {
combinedLists.merge(self.parseListData(knowledge, listType: .premium)) { present, _ in present }
} else {
print("⚠️ loadLists: La lista 'Nueva 1' no tiene elementos para cargar.")
}
}
group.notify(queue: .primary) {
self.lists = combinedLists
self.isLoading = false
print("🔄 loadLists: Listas cargadas exitosamente.")
}
}
Knowledge Parsing (parseListData Perform):
func parseListData(_ knowledge: [String: Any], listType: ListType) -> [String: [(item: Any, creationDate: Date?)]] {
var parsedLists: [String: [(item: Any, creationDate: Date?)]] = [:]
for (listName, listItems) in knowledge {
if let listData = listItems as? [String: Any], let creationDate = listData["creationDate"] as? Timestamp {
let itemsArray = (listData["items"] as? [[String: Any]]) ?? []
let listing = itemsArray.compactMap { itemData -> (Any, Date?)? in
if listType == .handbook {
if let title = itemData["title"] as? String {
return (ListTextField(id: itemData["id"] as? String ?? UUID().uuidString,
title: title,
subtitle: itemData["subtitle"] as? String ?? "",
isChecked: itemData["isChecked"] as? Bool ?? false),
creationDate.dateValue())
}
} else if let name_es = itemData["name_es"] as? String, let name_en = itemData["name_en"] as? String {
return (Product(id: itemData["id"] as? String ?? UUID().uuidString,
knowledge: itemData),
creationDate.dateValue())
}
return nil
}
if !listing.isEmpty {
parsedLists[listName] = listing
}
}
}
return parsedLists
}
UI Code (ShoppingListView):
var physique: some View {
NavigationView {
ZStack {
if isLoading {
ProgressView()
} else {
if lists.isEmpty {
Textual content("No lists obtainable.")
} else {
Checklist {
ForEach(Array(lists.keys.sorted()), id: .self) { listName in
NavigationLink(vacation spot: destinationView(for: listName)) {
Textual content(listName)
}
}
}
}
}
}
.onAppear(carry out: loadLists)
}
}
ViewModel:
import SwiftUI
import Mix
import FirebaseFirestore
class ListViewModel: ObservableObject {
@Revealed var lists: [String: [(item: Any, creationDate: Date?)]] = [:]
@Revealed var isLoading: Bool = false
@Revealed var errorMessage: String? = nil
non-public var cancellables = Set()
func loadLists() {
isLoading = true
print("🔄 loadLists: Inicio de la carga de listas.")
guard let uid = Auth.auth().currentUser?.uid else {
print("❌ loadLists: No se encontró UID del usuario.")
self.isLoading = false
self.errorMessage = "No consumer ID discovered."
return
}
let manualRef = Firestore.firestore().assortment("iFoodList").doc(uid)
let premiumRef = Firestore.firestore().assortment("PaidShoppingLists").doc(uid)
let group = DispatchGroup()
var combinedLists: [String: [(item: Any, creationDate: Date?)]] = [:]
group.enter()
manualRef.getDocument { doc, error in
defer { group.go away() }
if let doc = doc, doc.exists, let knowledge = doc.knowledge() {
combinedLists.merge(self.parseListData(knowledge, listType: .handbook)) { present, _ in present }
} else {
print("⚠️ loadLists: La lista 'Nueva 1' no tiene elementos para cargar.")
}
}
group.enter()
premiumRef.getDocument { doc, error in
defer { group.go away() }
if let doc = doc, doc.exists, let knowledge = doc.knowledge() {
combinedLists.merge(self.parseListData(knowledge, listType: .premium)) { present, _ in present }
} else {
print("⚠️ loadLists: La lista 'Nueva 1' no tiene elementos para cargar.")
}
}
group.notify(queue: .primary) {
self.lists = combinedLists
self.isLoading = false
print("🔄 loadLists: Listas cargadas exitosamente.")
}
}
non-public func parseListData(_ knowledge: [String: Any], listType: ListType) -> [String: [(item: Any, creationDate: Date?)]] {
var parsedLists: [String: [(item: Any, creationDate: Date?)]] = [:]
for (listName, listItems) in knowledge {
if let listData = listItems as? [String: Any], let creationDate = listData["creationDate"] as? Timestamp {
let itemsArray = (listData["items"] as? [[String: Any]]) ?? []
let listing = itemsArray.compactMap { itemData -> (Any, Date?)? in
if listType == .handbook {
if let title = itemData["title"] as? String {
return (ListTextField(id: itemData["id"] as? String ?? UUID().uuidString,
title: title,
subtitle: itemData["subtitle"] as? String ?? "",
isChecked: itemData["isChecked"] as? Bool ?? false),
creationDate.dateValue())
}
} else if let name_es = itemData["name_es"] as? String, let name_en = itemData["name_en"] as? String {
return (Product(id: itemData["id"] as? String ?? UUID().uuidString,
knowledge: itemData),
creationDate.dateValue())
}
return nil
}
if !listing.isEmpty {
parsedLists[listName] = listing
}
}
}
return parsedLists
}
}
Concern:
Knowledge masses efficiently, as confirmed by print statements (e.g., “🔄 loadLists: Listas cargadas exitosamente”), however the UI doesn’t show the lists.
I think a problem with how SwiftUI updates the UI or handles state.
Questions:
Is there one thing incorrect with how lists is getting used within the UI?
May the issue be associated to the lifecycle of ShoppingListView?