Having trouble resolving this error "Return from initializer without initializing all stored properties"
Here is the code that prompted the error,
import SwiftUI
struct TaskEditView: View
{
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
@Environment(\.managedObjectContext) private var viewContext
@EnvironmentObject var dateHolder: DateHolder
@ObservedObject var notificationManager: NotificationManager
@State var selectedTaskItem: TaskItem?
@State var name: String
@State var desc: String
@State var dueDate: Date
@State var scheduleTime: Bool
init(passedTaskItem: TaskItem?, initialDate: Date)
{
if let taskItem = passedTaskItem
{
_selectedTaskItem = State(initialValue: taskItem)
_name = State(initialValue: taskItem.name ?? "")
_desc = State(initialValue: taskItem.desc ?? "")
_dueDate = State(initialValue: taskItem.dueDate ?? initialDate)
_scheduleTime = State(initialValue: taskItem.scheduleTime)
}
else
{
_name = State(initialValue: "")
_desc = State(initialValue: "")
_dueDate = State(initialValue: initialDate)
_scheduleTime = State(initialValue: false)
}
} //error appears right here
var body: some View
{
NavigationView{
Form
{
Section(header: Text("ToDo"))
{
TextField("Name", text: $name)
TextField("Description", text: $desc)
}
Section(header: Text("Deadline"))
{
Toggle("Schedule Time", isOn: $scheduleTime)
DatePicker("Date", selection: $dueDate, displayedComponents: displayedComps())
}
if selectedTaskItem?.isCompleted() ?? false
{
Section(header: Text("Completed"))
{
Text(selectedTaskItem?.completedDate?.formatted(date: .abbreviated, time: .shortened) ?? "")
}
}
Section()
{
Button("Save", action: saveAction)
.font(.headline)
.foregroundColor(.green)
.padding(.horizontal)
}
.navigationTitle("Create New ToDo ")
}
}
}
func displayedComps() -> DatePickerComponents
{
return scheduleTime ? [.hourAndMinute, .date] : [.date]
}
func saveAction()
{
withAnimation
{
if selectedTaskItem == nil
{
selectedTaskItem = TaskItem(context: viewContext)
}
selectedTaskItem?.created = Date()
selectedTaskItem?.name = name
selectedTaskItem?.desc = desc
selectedTaskItem?.dueDate = dueDate
selectedTaskItem?.scheduleTime = scheduleTime
dateHolder.saveContext(viewContext)
self.presentationMode.wrappedValue.dismiss()
}
let dateComponents = Calendar.current.dateComponents([.hour, .minute], from: dueDate)
guard let hour = dateComponents.hour, let minute = dateComponents.minute else { return }
notificationManager.createLocalNotification(title: name, hour: hour, min: minute) { error in
if error == nil {}
}
}
}
struct TaskEditView_Previews: PreviewProvider {
static var previews: some View {
TaskEditView(passedTaskItem: TaskItem(), initialDate: Date())
}
}
I looked online and it said that I have to initialize all my proporties but im unsure how to do that for the
_selectedTaskItem
in the else statement.
Im very new to coding and much help would be appreciated Thanks
Yes, you still need to initialize
selectedTaskItem, even if its initial value isnil.The good news is that
passedTaskItemworks in both cases, so you can move that initialization out of the if clause: