I am playing around with WatchKit and CoreData and the demo app I wrote is working but sometimes gives unexpected results. Basically, it's a toDo app. You enter the toDo items on the iPhone and it stores them using CoreData in an entity called ToDoItem with 2 attributes: name (string) and completed (boolean). The name of items entered on the iPhone are assigned item.completed = false in the CoreData entity.
On the Apple Watch it queries CoreData on the iPhone and lists the names of the items that are not completed (item.completed == 0) in a WatchKit table view. When an item on the watch is selected the font changes to red, the row is deleted from the table, and it changes the completed value in CoreData to true (item.completed = true). The next time the Watch app is launched, the completed items no longer are listed in the table.
This works fine most of the time, but sometimes when an item is selected on the watch, it does not update CoreData with the item as item.completed = true. And once this happens, it no longer updates the items in CoreData when selected. No errors are given. If I reset the simulator, it starts working again but after a while does the same thing.
My code is below:
class InterfaceController: WKInterfaceController { @IBOutlet var table: WKInterfaceTable! override func awakeWithContext(context: AnyObject?) { super.awakeWithContext(context) // Configure interface objects here. var context = CoreDataStack.sharedInstance.managedObjectContext! let request = NSFetchRequest(entityName: "ToDoItem") //CoreData entity ToDoItem contains two attributes - name (string) and completed (boolean) let fetchItems: Array = context.executeFetchRequest(request, error: nil) as! [ToDoItem] //fetches the items in the entity var counter = 0 for element in fetchItems{ counter++ println("The item name is \(element.name) and completed is \(element.completed)") //prints the items to the console } self.table.setNumberOfRows(fetchItems.count, withRowType: "ToDoRow") var theCount = 0 for element in fetchItems { if element.completed == 0 { let row = self.table.rowControllerAtIndex(theCount) as? ToDoTableRowController row?.nameLabel.setText(element.name) //populates the table with names of items that are not completed theCount++ } } } override func table(table: WKInterfaceTable, didSelectRowAtIndex rowIndex: Int) { //self.pushControllerWithName("ToDoDetail", context: nil) let row = table.rowControllerAtIndex(rowIndex) as! ToDoTableRowController row.nameLabel.setTextColor(UIColor.redColor()) //change the color of font to red when row is selected var myIndex = NSIndexSet(index: rowIndex) self.table.removeRowsAtIndexes(myIndex) //removes selected row from table var context = CoreDataStack.sharedInstance.managedObjectContext! let request = NSFetchRequest(entityName: "ToDoItem") let items = context.executeFetchRequest(request, error: nil) as! [ToDoItem] let item = items[rowIndex] item.setValue(true, forKey: "completed") //changes the selected item to completed and saves it in coredata //item.completed = true var error: NSError? if !context.save(&error) { println("Cannot save due to \(error) \(error?.localizedDescription)") } }