I work with about the same ViewModels as other models. But on this one I get some error almost al of them are 'self' errors. I can't find where it come from.
And this I my code:
import SwiftUI
import Firebase
import Combine
class RouteViewModel: ObservableObject {
// MARK: Filtered Array
@Published var myRoutes: [Route]?
// MARK: Raw All Notes
@Published var allRoutes: [Route]?
// MARK: Search Text
@Published var searchText: String = ""
// Combine Search
var cancellable: AnyCancellable? = nil
// MARK: New Note
@Published var showAddRoutePopup: Bool = false
@Published var boxNumberIdentificatie: [String]
@Published var dateBringDate: Date
@Published var customerIdentificatie: String = ""
@Published var locationPlaceLogLat: GeoPoint
// MARK: Alert
@Published var showAlert: Bool = false
@Published var alertMsg: String = ""
// MARK: Edit Note
@Published var editRoute: Route?
// MARK: Log Status
@AppStorage("log_status") var log_status: Bool = false
// MARK: Logout Alert
@Published var showLogoutPopup: Bool = false
init(){
fetchRoutes()
// Combine Search
cancellable = $searchText.removeDuplicates()
.debounce(for: 0.5, scheduler: RunLoop.main)
.sink(receiveValue: { string in
if string != ""{
self.filterRoutes(searchText: string)
}
else{
withAnimation{
self.myRoutes = self.allRoutes
}
}
})
}
// MARK: Fetching Notes
func fetchRoutes(){
guard let uid = Auth.auth().currentUser?.uid else{
log_status = false
return
}
let routesRef = Firestore.firestore().collection("Routes")
routesRef.order(by: "lastModified", descending: true).addSnapshotListener { snapshot, err in
guard let docs = snapshot?.documentChanges else{
return
}
DispatchQueue.main.async {[self] in
if allRoutes == nil{allRoutes = []}
docs.forEach { doc in
if let route = try? doc.document.data(as: Route.self){
switch doc.type{
case .added: allRoutes?.append(route)
case .modified: updateRoute(route: route)
case .removed: removeRoute(route: route)
}
}
}
sortRoutes()
}
}
}
func sortRoutes(){
DispatchQueue.global(qos: .userInteractive).async {
let sorted = self.allRoutes?.sorted(by: { first, second in
return second.dateAdd < first.dateAdd
})
DispatchQueue.main.async {[self] in
allRoutes = sorted
withAnimation(myRoutes == nil ? .none : .default){
myRoutes = allRoutes
}
}
}
}
func filterRoutes(searchText: String){
DispatchQueue.global(qos: .userInteractive).async {
let filtered = self.allRoutes?.filter({ route in
return route.customerId.lowercased().contains(searchText.lowercased())
})
DispatchQueue.main.async {
withAnimation{
self.myRoutes = filtered
}
}
}
}
func addRoute(){
withAnimation{
showAddRoutePopup = false
}
if customerIdentificatie == ""{return}
let routesRef = Firestore.firestore().collection("Routes")
if let editRoute = editRoute {
routesRef.document(editRoute.id ?? "").updateData([
"boxId": boxNumberIdentificatie,
"dateBring": dateBringDate,
"customerId": customerIdentificatie,
"locationPlace": locationPlaceLogLat
])
clearData()
return
}
let route = Route(boxId: boxNumberIdentificatie, dateAdd: Date(), dateBring: dateBringDate, customerId: customerIdentificatie, locationPlace: locationPlaceLogLat)
do{
let _ = try routesRef.addDocument(from: route)
clearData()
}
catch{
clearData()
alertMsg = error.localizedDescription
showAlert.toggle()
}
}
func updateRoute(route: Route){
if let index = myRoutes?.firstIndex(where: { currentRoute in
return currentRoute.id == route.id
}){
allRoutes![index] = route
}
}
func removeRoute(route: Route){
if let index = myRoutes?.firstIndex(where: { currentRoute in
return currentRoute.id == route.id
}){
allRoutes?.remove(at: index)
}
}
func deleteRoute(){
guard let editRoute = editRoute else {
return
}
let routesRef = Firestore.firestore().collection("Routes")
routesRef.document(editRoute.id ?? "").delete()
withAnimation{
showAddRoutePopup = false
}
clearData()
}
func clearData(){
boxNumberIdentificatie = [""]
dateBringDate = Date()
customerIdentificatie = ""
editRoute = nil
}
}
I hope somebody is seeing the problem what I didn't see. Thanks a lot.. :)
CodePudding user response:
Some of your properties -- dateBringDate
and locationPlaceLogLat
-- do not have default values and are thus uninitialized by the time you call fetchRoutes
in the init
method. To fix, you should initialize them at the start of init
or provide default values:
@Published var dateBringDate: Date = Date()
Basically, the problem is that Swift requires you to initialize an object's properties before calling any of that object's methods. That rule prevents errors that would occur if, for example, fetchRoutes
tried to access the value of dateBringDate
.