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
passedTaskItem
works in both cases, so you can move that initialization out of the if clause: