Ios WatchKit和CoreData存在奇怪的问题
我正在玩WatchKit和CoreData,我编写的演示应用程序正在运行,但有时会产生意想不到的结果。基本上,这是一个待办事项应用程序。在iPhone上输入toDo项,它使用CoreData将它们存储在名为ToDoItem的实体中,该实体具有两个属性:名称(字符串)和完成(布尔值)。在iPhone上输入的项目名称在CoreData实体中分配为Ios WatchKit和CoreData存在奇怪的问题,ios,iphone,swift,core-data,watchkit,Ios,Iphone,Swift,Core Data,Watchkit,我正在玩WatchKit和CoreData,我编写的演示应用程序正在运行,但有时会产生意想不到的结果。基本上,这是一个待办事项应用程序。在iPhone上输入toDo项,它使用CoreData将它们存储在名为ToDoItem的实体中,该实体具有两个属性:名称(字符串)和完成(布尔值)。在iPhone上输入的项目名称在CoreData实体中分配为item.completed=false 在Apple Watch上,它查询iPhone上的CoreData,并在WatchKit表视图中列出未完成项目的名
item.completed=false
在Apple Watch上,它查询iPhone上的CoreData,并在WatchKit表视图中列出未完成项目的名称(item.completed==0
)。选择手表上的项目时,字体变为红色,行从表中删除,并将CoreData中的已完成值更改为true(item.completed=true
)。下次启动Watch应用程序时,表中不再列出已完成的项目
这在大多数情况下都可以正常工作,但有时当在手表上选择某个项目时,它不会将该项目更新为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)")
}
}
您如何协调主机应用程序和手表分机之间的数据?我正在应用程序组容器中使用一个核心数据存储,我发现watch、today小部件和主机应用程序在保存强制合并之前没有更新托管对象。(托管对象上下文没有注意到存储中的对象已更改。)因此,可能是手表的上下文中有已完成的项目,但主机应用程序的上下文中仍有未完成的项目 对我来说,修复方法是使用这三个二进制文件,当它们接触到
NSManagedObject
子类时,它们可以互相更新。我在消息中传递对象ID
,当二进制文件收到消息时,调用
context.refreshObject(managedObject,mergeChanges:true)
让所有人恢复同步。您检查过“保存”返回的错误吗?我在关键点item.setvalue和context.save创建了断点,但都显示良好。我不知道这是否是watchKit模拟器中的一个bug,也不能用Apple Watch设备进行测试,因为我还没有。我看了一篇可能有用的文章。如果我找到了这个问题的答案,我会更新这篇文章。