I have an ObservableObject declared like this in my DateView:
import SwiftUI
class SelectedDate: ObservableObject {
@Published var selectedMonth: Date = Date()
var startDateOfMonth: Date {
let components = Calendar.current.dateComponents([.year, .month], from: self.selectedMonth)
let startOfMonth = Calendar.current.date(from: components)!
return startOfMonth
}
var endDateOfMonth: Date {
var components = Calendar.current.dateComponents([.year, .month], from: self.selectedMonth)
components.month = (components.month ?? 0) + 1
let endOfMonth = Calendar.current.date(from: components)!
return endOfMonth
}
}
struct DateView: View {
// other code
}
I can access startDateOfMonth and endDateOfMonth in other views like this:
Text("\(self.selectedDate.startDateOfMonth)")
But I have a problem when I try to use those variables from ObservableObject inside a fetchRequest initializer in my TransactionsListView:
import SwiftUI
struct TransactionsListView: View {
@Environment(\.managedObjectContext) var managedObjectContext
var fetchRequest: FetchRequest<NPTransaction>
var transactions: FetchedResults<NPTransaction> { fetchRequest.wrappedValue }
@EnvironmentObject var selectedDate: SelectedDate
// other code
init() {
fetchRequest = FetchRequest<NPTransaction>(entity: NPTransaction.entity(), sortDescriptors: [
NSSortDescriptor(keyPath: \NPTransaction.date, ascending: false)
], predicate: NSPredicate(format: "date >= %@ AND date < %@", self.selectedDate.startDateOfMonth as NSDate, self.selectedDate.endDateOfMonth as NSDate))
}
var body: some View {
// other code
}
}
I am getting an error:
Variable 'self.fetchRequest' used before being initialized
What ma I doing wrong? I have tried to use those variables inside init without self. Same error. The only way it worked was if those startDateOfMonth and endDateOfMonth were not in ObservableObject, but as a vars in ancestor view which I was passing as parameters to my view with fetchRequest init. But I have few views like this and wanted to use ObservableObject, not to pass the same parameters to subviews all the time.
The problem is that you can not use @EnvironmentObject
in the init()
. The possible option here is to pass the EnvironmentObject
as parameter to the View. Then use that parameter inside the init. Here is the constructor for the view, then you can access start and endTime with local variable selectedDate
.
init(selectedDate : SelectedDate)
{
//now you can access selectedDate here and use it in FetchRequest
fetchRequest = FetchRequest<NPTransaction>(entity: NPTransaction.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \NPTransaction.date, ascending: false)], predicate: NSPredicate(format: "date >= %@ AND date < %@", selectedDate.startDateOfMonth as NSDate, selectedDate.endDateOfMonth as NSDate))
}
Where you call that view, pass the EnvironmentObject
as parameter.
//Declared as Environment Object
TransactionsListView(selectedDate : self.selectedDate)