WatchKit和CoreData的奇怪问题

时间:2015-04-20 18:30:20

标签: ios iphone swift core-data watchkit

我正在使用WatchKit和CoreData,我编写的演示应用程序正在运行,但有时会产生意想不到的结果。基本上,它是一个toDo应用程序。您在iPhone上输入toDo项目,并使用CoreData将它们存储在名为ToDoItem的实体中,该实体具有2个属性:name(字符串)和completed(boolean)。在iPhone上输入的项目名称在CoreData实体中分配item.completed = false

在Apple Watch上,它在iPhone上查询CoreData,并在WatchKit表视图中列出未完成的项目的名称(item.completed == 0)。选择手表上的项目时,字体将变为红色,该行将从表中删除,并将CoreData中的已完成值更改为true(item.completed = true)。下次启动Watch应用程序时,表中不再列出已完成的项目。

这在大多数情况下都可以正常工作,但有时当在手表上选择某个项目时,它不会将项目更新为Core item.completed = true。一旦发生这种情况,它在选择时不再更新CoreData中的项目。没有错误。如果我重置模拟器,它会再次开始工作,但过了一会儿会做同样的事情。

我的代码如下:

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)")
    }



}

1 个答案:

答案 0 :(得分:1)

您如何在主机应用和手表扩展程序之间协调数据?我在应用程序组容器中使用了Core Data存储,我发现手表,今天的小部件和主机应用程序没有获得对托管对象的更新,直到保存强制合并发生。 (托管对象上下文不会注意到商店中的对象已更改。)因此,可能是手表的上下文具有已完成的项目,但主机应用程序在上下文中仍有未完成的项目。

对我来说,修复是使用MMWormhole,因此所有三个二进制文件在触及NSManagedObject子类时都可以相互更新。我在消息中传递object ID,当二进制文件收到消息时调用 context.refreshObject(managedObject, mergeChanges: true)让所有人重新同步。