使用 CoreData 时如何与 Watch OS 2 共享数据以显示在 WKInterfaceTable 中

Posted

技术标签:

【中文标题】使用 CoreData 时如何与 Watch OS 2 共享数据以显示在 WKInterfaceTable 中【英文标题】:How To Share Data with Watch OS 2 to display in WKInterfaceTable when working with CoreData 【发布时间】:2016-03-10 23:26:04 【问题描述】:

我正在使用WatchConnectivity 尝试将类型为NSManagedObject 的数据称为arrayOfOjects 发送到Watch。每个object 都有一个名为title 的字符串属性。

Watch 上的InterfaceController 加载并显示并清空表 - 因为数组为空,所以当用户请求数据时,它会在手机上使用didReceiveMessage 方法发送。

我不确定如何将字典数组添加到 objectsArray 以显示在 WKInterfaceTable 中。

有谁知道我如何将数据发送到手表以显示在表格中以进行更改并将它们与手机同步?

Apple Watch:

class ObjectsInterfaceController: WKInterfaceController, WCSessionDelegate 

var session : WCSession!
var objectsArray = [[AnyObject]]()

@IBOutlet var table: WKInterfaceTable!
@IBOutlet var titleLabel: WKInterfaceLabel!

func loadTableData() 

    table.setNumberOfRows(self.objectsArray.count, withRowType: "CellRow")
    if self.objectsArray.count > 0 
        for (index, name) in self.objectsArray.enumerate() 
            let row = self.table.rowControllerAtIndex(index) as! CellRowController
            row.objectCellLabel.setText(name.title)
        
    


override init() 
    super.init()
    loadTableData()


override func awakeWithContext(context: AnyObject?) 
    super.awakeWithContext(context)
    // Interface Objects


override func willActivate() 
    // This method is called when watch view controller is about to be visible to user
    super.willActivate()
    //Check if session is supported and Activate
    if (WCSession.isSupported()) 
        session = WCSession.defaultSession()
        session.delegate = self
        session.activateSession()
    


//Swift
func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) 

    let value = message["Value"]

    dispatch_async(dispatch_get_main_queue()) 
        self.objectsArray.removeAll()
        self.objectsArray.append(value! as! Array)
        self.loadTableData()
    

    //send a reply
    replyHandler(["Value":"Yes"])



iPhone

我已经获取了所有对象并存储在数组中。

var objectsArray = [Objects]()

func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) 

    //send a reply
    replyHandler(["Value": [objectsArray]])


我需要能够修改对象的属性并将更改保存在 iPhone 上,但 atm 我什至无法发送数据并在表中显示:( 我已经能够在字典中发送简单的字符串值设备,但不是数组或实际数据。

【问题讨论】:

您不能在(上下文、线程或)设备之间共享NSManagedObject 您能否发布将姓名发送到手表的 ios 应用程序的代码? 【参考方案1】:

TL/DR:

您只能将基本类型(如字符串、整数、双精度数)发送到手表。 This question has more details about sending custom objects.

另一个问题:

即使您归档或序列化了托管对象,仍然无法将特定数据从手机发送到手表。

NSManagedObject 仅在其自己的上下文中有效。在这种情况下,托管对象在您的 iOS 应用程序上注册到特定的NSMangedObjectContext。托管对象除了它的上下文没有用处,而且它的托管对象上下文不存在于手机以外的任何地方。

NSManagedObject 实例不打算在队列之间传递。这样做可能会导致数据损坏和应用程序终止。当需要将托管对象引用从一个队列传递到另一个队列时,必须通过 NSManagedObjectID 实例来完成。

由于不可能将托管对象从一个上下文(或线程或队列)传递到 same 平台上的另一个上下文,因此您绝对不能在手机与其配对的手表之间传递托管对象.

你能做什么?

如果您有办法在手机和手表之间共享您的核心数据存储,您可以将托管对象 ID 转换为字符串(使用 URIRepresentation),然后将这些字符串传递给手表,然后将这些字符串转换回来对象 ID 并获取相应的对象。 This is explained in detail in this question.

但是,watchOS 2 不再支持应用组,而且要让两个不同的商店在不同设备之间保持同步会非常复杂。

一个更轻松的解决方案是传递有关标题的详细信息,跟踪您在手表上所做的任何更改,然后发回一个包含插入、删除或以其他方式更改的标题的字典。

然后手机会更新与这些更改的标题相对应的托管对象。

这类似于NSFetchedResultsControllerDelegate 响应更改以保持其结果同步的方式。

有谁知道我如何将数据发送到手表以显示在表格中以进行更改并将它们与手机同步?

我给了你一个总体概述。任何更详细的内容都过于广泛,无法在此答案中涵盖。我只能建议开发人员要么使用第三方框架,要么编写自己的实现。

一些注意事项:

请记住,您不希望通过来回传输大量数据来降低用户的观看体验。保持您的手表应用轻巧且响应迅速,因为它的理想设计是只使用几秒钟。

如果您可以简化手表应用程序设计(例如,仅将待办事项列表项标记为已完成),则可以消除大部分“同步”开销,并将更复杂的任务委托给 iOS 应用程序。

【讨论】:

使用WatchConnectivity框架向手表发送Dictionary是没有问题的。我在手机上做获取请求的问题(只发送一些数据)。也许你对此有提示? ***.com/questions/47734060/…

以上是关于使用 CoreData 时如何与 Watch OS 2 共享数据以显示在 WKInterfaceTable 中的主要内容,如果未能解决你的问题,请参考以下文章

使用 Core Data 时如何使用 Watch Connectivity 共享数据

如何使用 Apple Watch 的 os_log 访问过去一天的日志?

如何从watch os swift获取设备ID

在 Watch Extension 和 iPhone 上使用相同的启用了 iCloud 的 CoreData 存储

如何从 Apple Watch 检索 os_log 条目?

如何在swift ui watch os中的同一屏幕中添加键盘和文本字段[关闭]