Reputation: 19
I am getting the error that i wrote in the title and after looking at all the other stack overflow threads but none of them really explain where the problem comes from.
When I launch the application it instantly crashes and highlights this line in red:
let modelURL = NSBundle.mainBundle().URLForResource("HitList", withExtension: "momd")!
My main View controller that the app launches to has this code:
import UIKit
import CoreData
class ViewController: UIViewController, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
var subjects = [NSManagedObject]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.registerClass(UITableViewCell.self,
forCellReuseIdentifier: "Cell")
}
func tableView(tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return subjects.count
}
func tableView(tableView: UITableView,
cellForRowAtIndexPath
indexPath: NSIndexPath) -> UITableViewCell {
let cell =
tableView.dequeueReusableCellWithIdentifier("Cell")
let check = subjects[indexPath.row]
cell!.textLabel!.text =
check.valueForKey("name") as? String
return cell!
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
@IBAction func addName(sender: AnyObject) {
let alert = UIAlertController(title: "New Subject", message: "Add a new Subject", preferredStyle: .Alert)
let saveAction = UIAlertAction(title: "Save",
style: .Default,
handler: { (action:UIAlertAction) -> Void in
let textField = alert.textFields!.first
self.saveName(textField!.text!)
self.tableView.reloadData()
})
let cancelAction = UIAlertAction(title: "Cancel",
style: .Default) { (action: UIAlertAction) -> Void in
}
alert.addTextFieldWithConfigurationHandler {
(textField: UITextField) -> Void in
}
alert.addAction(saveAction)
alert.addAction(cancelAction)
presentViewController(alert,
animated: true,
completion: nil)
}
func saveName(name: String) {
let appDelegate =
UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let entity = NSEntityDescription.entityForName("Subjects",
inManagedObjectContext:managedContext)
let check = NSManagedObject(entity: entity!,
insertIntoManagedObjectContext: managedContext)
check.setValue(name, forKey: "name")
do {
try managedContext.save()
subjects.append(check)
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
}
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
let appDelegate =
UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let fetchRequest = NSFetchRequest(entityName: "Subjects")
do {
let results =
try managedContext.executeFetchRequest(fetchRequest)
subjects = results as! [NSManagedObject]
} catch let error as NSError {
print("Could not fetch \(error), \(error.userInfo)")
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle,forRowAtIndexPath indexPath: NSIndexPath) {
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "ShowAssesment") {
let indexPath = tableView.indexPathForCell((sender as? UITableViewCell)!)
let listVC = segue.destinationViewController as? AssesmentViewController
let subject = subjects[indexPath!.row]
listVC?.assesments = ["Death"]
}
}
}
Upvotes: 1
Views: 827
Reputation: 19
Thank you, that has worked. John Doe's didn't work as it still gave the error message but changing the URLForResource in this case to the name of the xcdatamodeld name.
Upvotes: 0
Reputation: 1609
You're trying to unwrap a value that doesn't exist on the line..
let modelURL = NSBundle.mainBundle().URLForResource("HitList", withExtension: "momd")!
Locate the file you're trying to obtain and make sure it exists and that it's called HitList.momd. And do this instead...
var modelURL = NSBundle.mainBundle().URLForResource("HitList", withExtension: "momd")
So just in case the file doesn't exist your app doesn't crash.
Upvotes: 0
Reputation: 23459
The URLForResource
method according to Apple:
Returns the file URL for the resource file identified by the specified name and extension and residing in a given bundle directory.
And returns :
The file URL for the resource file or
nil
if the file could not be located. This method also returnsnil
if the bundle specified by thebundlePath
parameter does not exist or is not a readable directory.
You need to check before unwraps it, remember every time you use the !
operator to unwrap an optional you say to the compiler that the variable always have a value, you can fix it using optional binding like in the following way:
if let modelURL = NSBundle.mainBundle().URLForResource("HitList", withExtension: "momd") {
// do whatever you what with the value
}
else {
// the value is nil
}
Or instead use the new guard
statement in Swift 2.0 like in the following way;
guard let let modelURL = NSBundle.mainBundle().URLForResource("HitList", withExtension: "momd") else {
// the value is nil
return
}
I hope this help you.
Upvotes: 0
Reputation: 261
When let modelURL = NSBundle.mainBundle().URLForResource("HitList", withExtension: "mom")!
is executed, the file HitList is not found and the result is nil. You cannot unwrap nil.
Upvotes: 3