我正在使用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)")
}
}
答案 0 :(得分:1)
您如何在主机应用和手表扩展程序之间协调数据?我在应用程序组容器中使用了Core Data存储,我发现手表,今天的小部件和主机应用程序没有获得对托管对象的更新,直到保存强制合并发生。 (托管对象上下文不会注意到商店中的对象已更改。)因此,可能是手表的上下文具有已完成的项目,但主机应用程序在上下文中仍有未完成的项目。
对我来说,修复是使用MMWormhole,因此所有三个二进制文件在触及NSManagedObject
子类时都可以相互更新。我在消息中传递object ID
,当二进制文件收到消息时调用
context.refreshObject(managedObject, mergeChanges: true)
让所有人重新同步。