使用 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 共享数据的主要内容,如果未能解决你的问题,请参考以下文章