2

Just updated to Xcode 7.0 from Xcode 6.4. In my project I am getting an error now which I try to solve the whole night and did not get it.

The error message is: Initializer for conditional binding must have optional type not 'nsmanagedobjectcontext'

The error is coming twice in lines if let managedObjectContext = self.managedObjectContext { in following code

func preloadData () {
    // Retrieve data from the source file
    if let contentsOfURL = NSBundle.mainBundle().URLForResource("listofdata", withExtension: "csv") {

        // Remove all the items before preloading
        removeData()

        var error:NSError?
        if let items = parseCSV(contentsOfURL, encoding: NSUTF8StringEncoding, error: &error) {
            // Preload the items
            if let managedObjectContext = self.managedObjectContext {
                for item in items {
                    let listOfItem = NSEntityDescription.insertNewObjectForEntityForName("ListOfItem", inManagedObjectContext: managedObjectContext) as! ListOfItem
                    listOfItem.name = item.name
                    listOfItem.address = item.address
                    listOfItem.phone = item.phone

                    if managedObjectContext.save(&error) != true {
                        print("insert error: \(error!.localizedDescription)")
                    }
                }
            }
        }
    }
}

func removeData () {
    // Remove the existing items
    if let managedObjectContext = self.managedObjectContext {
        let fetchRequest = NSFetchRequest(entityName: "ListOfItem")
        var e: NSError?
        let listOfItems = managedObjectContext.executeFetchRequest(fetchRequest, error: &e) as! [ListOfItem]

        if e != nil {
            print("Failed to retrieve record: \(e!.localizedDescription)")

        } else {

            for listOfItem in listOfItems {
                managedObjectContext.deleteObject(listOfItem)
            }
        }
    }
}

Appreciate all help! Thanks!

Update:

The updated code looks like this, but still have these two errors in the first function preloadData:

  1. Missing argument for parameter 'error' in call
  2. Initializer for conditional binding must have Optional type, not 'NSManagedObjectContext'

    func preloadData () {
    // Retrieve data from the source file
    if let contentsOfURL = NSBundle.mainBundle().URLForResource("listofdata", withExtension: "csv") {
    
        // Remove all the menu items before preloading
        removeData()
    
        do {
            let items = try parseCSV(contentsOfURL, encoding: NSUTF8StringEncoding)
            // Preload the items
            if let managedObjectContext = self.managedObjectContext {
                for item in items {
                    let listOfItem = NSEntityDescription.insertNewObjectForEntityForName("ListOfItem", inManagedObjectContext: managedObjectContext) as! ListOfItem
                    listOfItem.name = item.name
                    listOfItem.address = item.address
                    listOfItem.phone = item.phone
    
                    if managedObjectContext.save() != true {
                        print("insert error: \(error.localizedDescription)")
                    }
                }
            }
        } catch let error as NSError {
            print("insert error: \(error.localizedDescription)")
        }
    }
    

This function shows no errors

func removeData () {
    // Remove the existing items
    let fetchRequest = NSFetchRequest(entityName: "ListOfItem")

    do {
        let listOfItems = try self.managedObjectContext.executeFetchRequest(fetchRequest) as! [ListOfItem]
        for listOfItem in listOfItems {
            self.managedObjectContext.deleteObject(listOfItem)
        }
    }
    catch let error as NSError {
        print("Failed to retrieve record: \(error.localizedDescription)")
    }

Can some help? Thanks!

Olli D.
  • 59
  • 6

2 Answers2

3

In Swift 2 the Core Data template implements the property managedObjectContext in AppDelegate as non-optional. Probably the updater changed the implementation accordingly.

The benefit is that the optional bindings are not necessary any more, but you have to consider the new error handling for example

func removeData () {
  let fetchRequest = NSFetchRequest(entityName: "ListOfItem")

  do {
    let listOfItems = try self.managedObjectContext.executeFetchRequest(fetchRequest) as! [ListOfItem]
    for listOfItem in listOfItems {
       self.managedObjectContext.deleteObject(listOfItem)
     }
   }
   catch let error as NSError {
     print("Failed to retrieve record: \(error.localizedDescription)")
   }
}
vadian
  • 274,689
  • 30
  • 353
  • 361
  • Your first sentence is misleading, `NSManagedObjectContext` does not have a `managedObjectContext` variable. Perhaps you meant the `managedObjectContext` property of the application delegate? – Then, strictly speaking, this is not a change in the Swift language, but a change in the template code generated by Xcode 7. – Martin R Sep 18 '15 at 09:23
  • vielen dank vadian! it looks like that the second function (func removeData) is working as you described it. I just had to add a "try" in the "do" statement: let listOfDgItem = try NSEntityDescription.insertNew....I want to correct the first function (fun preloadData) in same way but its not working. Now I am a light bit confused. Any idea how it could look? – Olli D. Sep 18 '15 at 10:32
1

try below code

removeData()

 func removeData () {

    let fetchRequest = NSFetchRequest(entityName: "MenuItem")

    do {
        let listOfItems = try self.managedObjectContext.executeFetchRequest(fetchRequest) as! [MenuItem]
        for listOfItem in listOfItems {
            self.managedObjectContext.deleteObject(listOfItem)
        }
    }
    catch let error as NSError {
        print("Failed to retrieve record: \(error.localizedDescription)")
    }


}

preloadData ()

 func preloadData () {
    // Retrieve data from the source file
    if let contentsOfURL = NSBundle.mainBundle().URLForResource("menudata", withExtension: "csv") {

        // Remove all the menu items before preloading
        removeData()

        var error:NSError?
        if let items = parseCSV(contentsOfURL, encoding: NSUTF8StringEncoding, error: &error) {
            // Preload the menu items

                for item in items {

                    let menuItem =  NSEntityDescription.insertNewObjectForEntityForName("MenuItem", inManagedObjectContext:self.managedObjectContext) as! MenuItem
                    menuItem.name = item.name
                    menuItem.detail = item.detail
                    menuItem.price = (item.price as NSString).doubleValue

            }

        }
    }
}
Khadija Daruwala
  • 1,185
  • 3
  • 25
  • 54
Chandramani
  • 871
  • 1
  • 12
  • 11