My app terminates every time a value is entered/edited in the text fields for "notes", "task name" and "task length" values. If data for just one of them is entered/edited, the app crashes. The same line of code is highlighted as the cause of the error each time.
The problem is that the array I'm using is empty when I'm trying to search for a value. It should't be empty, but I don't know how to correct this. Could you please tell me a method to resolve this unsafe unwrapping in the code?
I'm using a split Master-Detail view controller. Attached is all the relevant code, from the 3 different View Controllers I'm using. The function in the Task VC is connected to the function in the Master VC - adds new data for a new task.
I've tried using do/try/catch, using the ! on the optional and using IF statements, but nothing I try seems to work. Please help me
Error + line of code highlighted in debugger:
fatal error: unexpectedly found nil while unwrapping an Optional value
textFields[0].text = detail.valueForKey("moduleName") as? String
Detail View Controller
var tasks = [NSSet]()
var courseWork: CourseWork? {
didSet {
dispatch_async(dispatch_get_main_queue()) {
self.configureView()
}
func configureView() { // Update the user interface for the detail view
if let detail = self.courseWork {
self.title = detail.valueForKey("courseWorkName")!.description
textFields[0].text = detail.valueForKey("moduleName") as? String //Error with this line
textFields[1].text = detail.valueForKey("markAwarded") as? String
func setupUIElements() {
//text fields
for textF in textFields {
textF.delegate = self
}
textView.delegate = self
}
@IBOutlet var textFields: [UITextField]!
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
for (index, tf) in textFields.enumerate() {
if textField == tf {
saveTHeCourseWork(index == 0 ? "moduleName" : "markAwarded", value: textFields[index].text!)
}
}
return true
}
@IBOutlet weak var textView: UITextView!
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
if text == "\n" {
saveTHeCourseWork("notes", value: textView.text)
textView.resignFirstResponder()
}
return true
}
Task VC:
@IBOutlet weak var taskName: UITextField!
@IBOutlet weak var taskLength: UITextField!
@IBOutlet weak var taskNotes: UITextView!
@IBAction func saveTask(sender: UIButton) { // function saves and updates data inputted into Task
if task == nil { // task is blank, create new one
MasterViewController().insertNewTask(taskName.text!, length: taskLength.text, startDate: startDate.date, dueDate: dueDate.date, notes: taskNotes.text, course: courseWork!)
} else {
MasterViewController().updateTaskValues(taskName.text!, length: taskLength.text, startDate: startDate.date, dueDate: dueDate.date, notes: taskNotes.text, task: task!) // sends to Master Detail View Controller
print ("Update task")
}
Master VC:
func insertNewTask(name: String, length: String?, notes: String, course: CourseWork) {
if let context = course.managedObjectContext {
let task = NSEntityDescription.entityForName("Task", inManagedObjectContext: context)
let newTask = NSManagedObject(entity: task!, insertIntoManagedObjectContext: context)
newTask.setValue(name, forKey: "taskName")
newTask.setValue(notes, forKey: "notes")
course.mutableSetValueForKey("tasks").addObject(newTask)
// Save data to Object
do {
try course.managedObjectContext?.save()
} catch {
abort()
}