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

Posted

技术标签:

【中文标题】使用 Core Data 时如何使用 Watch Connectivity 共享数据【英文标题】:How to share data using Watch Connectivity when working with Core Data 【发布时间】:2015-12-18 22:51:55 【问题描述】:

在我的 ios 应用程序中,我使用 Core Data 来存储数据并使用获取请求来创建 NSManagedObjects 的数组以显示在 UITableView 中。

在 Watch OS 上,我检查是否支持 WCSession 并激活会话,然后从 watchOS 扩展向 iOS 应用程序发送消息。

当 iOS 应用程序收到来自 watchOS 的消息时,它应该将 Objects 的数组发送到 watchOS 扩展以显示 WKInterfaceTable 中的数据,但我不确定如何执行此操作。最终我想要实现的是;

如何与 watchOS 扩展共享Objects 的数组?

如果用户在Watch上添加/编辑/删除数组中的对象,我们如何更新iPhone上的数据?

另外,iOS 应用程序嵌入在UITabBarController 中,所以我与哪个视图控制器通信是否重要?

观看 OS FavouritesInterfaceController

var session : WCSession!

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()
    


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

    //Send Message
    sendmessagetoiphone()   


func sendMessageToIphone() 
    if(WCSession.isSupported())
        session.sendMessage(["b":"goodBye"], replyHandler: nil, errorHandler: nil)
    

IOS 应用程序:FavouritesViewController

var objects = [Objects]()

func loadData()  

    let moc = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
    let request = NSFetchRequest(entityName: "Objects")
    request.sortDescriptors = [NSSortDescriptor(key: "date", ascending: true)]
    do 
        try
            self.objects = moc.executeFetchRequest(request) as! [Objects]
        // success ...
     catch 
        // failure
        print("Fetch failed")
    
 

   func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) 
    //handle received message   
    let value = message["Value"] as? String
    dispatch_async(dispatch_get_main_queue()) 
        self.messageLabel.text = value
    
    //send a reply
    replyHandler(["Value":"Hello Watch"])
   

【问题讨论】:

【参考方案1】:

如何与 Watch OS 扩展共享对象数组? 由于您使用的是WatchConnectivity 框架,请使用sendMessage 方法从iPhone 发送对象数组,并在您的FavoritesInterfaceController 中实现func session(session: WCSession, didReceiveMessage 方法以获得响应,或者您可以在replyhandler 中获取数组 到。

如果用户在 Watch OS 上的数组中添加/编辑/删除对象 我们如何更新 iPhone 上的数据?

将 objectId 以及 sendMessage 方法中的新更改从手表发送到手机,在手机上接收时,将数据库中的更改保存并在 replyHandler 中发送更新的值,所以您的手表内容将相应更新。

iOS 应用程序也嵌入在 UITabBarController 中,因此 我与哪个视图控制器通信有关系吗?

您希望与之通信的 viewController 或者负责进行更改的 viewController 应该是活动的。如果多个 ViewController 正在监听 WCSessionDelegates,那么当您从 watch 发送任何消息时,所有实时控制器都会收到该消息。您应该在您的sendMessage 字典中包含某种identifier,这样您就可以知道要执行哪个操作。就像如果你想delete 一个对象,那么当watch 发送消息时,identifier 将包含delete,这样在接收时你可以检查identifier 的值并执行delete 操作。

【讨论】:

看来我必须同时打开 iOS 应用程序和 Watch 应用程序才能使用此方法。这违背了在不拔出手机的情况下快速访问手表上的数据的意义。我说的对吗? 如果您在 WCSession.h 中看到有关此方法的 cmets,它会显示 如果对应应用程序未运行,则对应应用程序将在收到消息后启动(仅限 iOS 对应应用程序)。消息字典只能接受属性列表类型。 因此,即使您的计数器 iOS 应用程序已关闭并且您从手表向 iPhone 发送一条消息,它也会启动该应用程序并接收消息,但反过来是不可能的。 【参考方案2】:

您可以使用 sendMessage 中的 replyHandler 来执行此操作。确保您在 Watch 和 iOS 应用程序上都实现了回复处理程序以获取此信息。

基本上,如果您做对了,您的回复处理程序可以确保您的 iOS 应用对手表应用的消息做出响应。

另外,谈到您的响应(发送对象数组) - 您应该将其作为字典发送并在手表上获取。

【讨论】:

【参考方案3】:

首先,这是一个非常好的问题。对于初学者,我建议您观看 WWDC 2015 中的本次会议:第 713 次会议 - 介绍 Watch Connectivity。这个可以找到here.

现在回答您的实际问题。有一个很棒的教程和 Github repo 向您展示了如何使用 App Groups 在 Apple Watch 应用和容器应用之间传递 Core Data,因为这使您能够访问所有共享内容,例如 Core Data 甚至 NSUSerdefaults。

然后您可以在以下link 下找到有关如何执行此操作的完整教程。

希望对您有所帮助,朱利安。

【讨论】:

我很确定 github 示例不适用于 Xcode 7,或者更好的说法是 WatchSDK 2。

以上是关于使用 Core Data 时如何使用 Watch Connectivity 共享数据的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Visual Studio ASP.NET Core 监视文件更改“dotnet watch”

使用 Core Data 时如何重新排列部分

vue data中的对象的属性如何使用watch监听

使用 CoreDataViewModel 时如何在 Canvas 中预览 Core Data 对象

使用 NSDocument 时如何将情节提要视图绑定到 Core Data 实体?

如何使用 Core Data 更新数据?