如何使用WatchConnectivity在iOS和Watch应用之间共享信息? [英] How can I share information between my iOS and Watch apps using WatchConnectivity?

查看:129
本文介绍了如何使用WatchConnectivity在iOS和Watch应用之间共享信息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

[免责声明:该问题旨在作为Wiki问题,回答有关在iOS和手表应用之间在watchkitwatch-os标签下发送数据的常见问题.]

我正在开发Apple Watch应用程序,并希望在iOS应用程序及其WatchKit extension之间发送数据.我已经看过WatchConnectivity框架,但是并没有真正理解其所有方法之间的区别.

即使我的应用程序在后台也要发送数据,我应该使用哪个功能?

我应该使用哪个功能将UI更新发送到Watch?

我应该使用哪个功能发送大数据?

解决方案

在撰写此答案时(watchOS3是当前的稳定版本,watchOS4处于beta阶段),的唯一选择iOS应用与其WatchKit extension之间的直接通信是 WatchConnectivity 框架. (我直接说,因为该问答不涉及使用CloudKit之类的云技术从一台设备将文件上传到互联网并在另一台设备上下载它们.)

首先,让我们讨论WCSession的哪个功能应用于什么目的.有关代码示例,请向下滚动.

快速深入了解每种功能以及何时使用它们,然后再深入研究细节:

  • updateApplicationContext:在应用程序之间同步状态,发送要在UI上显示的数据(仅用于发送少量数据)
  • transferUserInfo:在后台发送数据字典
  • transferFile:在后台发送文件
  • sendMessage:至少在watch应用程序在前台运行之间发送即时消息

详细说明

如果您要使用

updateApplicationContext(_ :) 同步您的应用程序(例如保持UI更新或发送状态信息,例如用户登录状态等).您可以发送数据字典.随后对该函数的调用将替换先前发送的字典,因此对应的应用程序仅接收使用updateApplicationContext发送的最后一项.系统尝试在适当的时间调用此函数,以使其在需要的时间接收数据,同时最大程度地减少功耗.因此,当两个应用都未在前台运行时可以调用该函数,但是需要激活WCSession才能成功进行传输.尝试使用updateApplicationContext传输大量数据的频繁调用可能会失败,因此对于此用法,请调用transferUserInfo.

transferUserInfo( :) transferCurrentComplicationUserInfo( :) 其他应用程序需要接收的背景.对该方法的后续调用排队,并且接收从一个应用程序发送到另一个应用程序的所有信息. transferCurrentComplicationUserInfo可以用于通过高优先级消息将与并发症相关的数据发送到WatchKit extension,并在需要时唤醒WatchKit app.但是,请注意,此功能有每日限制,一旦超过该限制,便会使用transferUserInfo函数来传输数据.

transferFile(_:metadata :) 的实现方式相似, transferUserInfo的属性,但它接受fileURL而不是字典作为其输入参数,因此应使用它来将设备本地的文件发送给它的对应对象.后续呼叫排队.收到的文件必须使用session(_:didReceive:)方法保存到新位置,否则将被删除.

sendMessage(:replyHandler:errorHandler :) sendMessageData(:replyHandler:errorHandler :) 立即发送数据到对应的应用程序.调用此方法之前,对应的应用程序必须可访问.始终将iOS应用视为可访问的,并且从Watch应用中调用此方法会在需要时在后台唤醒iOS应用.只有在安装并运行Watch应用程序后,该应用程序才可访问.传输必须在前台启动.随后对该方法的调用排队.

有关更多信息,请参见 watchOS的应用程序编程指南-共享数据.

现在有一些代码示例:

iOS应用程序的AppDelegate中设置WatchConnectivity:

import UIKit
import WatchConnectivity

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        if WCSession.isSupported() {
            let session = WCSession.default()
            session.delegate = self
            session.activate()
        }
        return true
    }
}

extension AppDelegate: WCSessionDelegate {

    func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
        print("Message received: ",message)
    }

    //below 3 functions are needed to be able to connect to several Watches
    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {}

    func sessionDidDeactivate(_ session: WCSession) {}

    func sessionDidBecomeInactive(_ session: WCSession) {}
}

使您的WatchKit类符合WCSessionDelegate:

extension InterfaceController: WCSessionDelegate {
    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {}
}

使用即时消息传递功能sendMessage:

如果要立即将信息发送到iOS应用,请在WatchKit app中使用此代码.

if WCSession.isSupported() {
    print("WCSession supported")
    let session = WCSession.default()
    session.delegate = self
    session.activate()
    if session.isReachable {
        session.sendMessage(["Instant":"Message"], replyHandler: nil, errorHandler: { error in
            print("Error sending message",error)
        })
    }
}

[Disclaimer: this question is intended to be a wiki question to answer the frequent questions about sending data between the iOS and watch apps under the watchkit and watch-os tags.]

I am developing an Apple Watch app and would like to send data between the iOS app and its WatchKit extension. I have looked at the WatchConnectivity framework, but don't really understand the difference between all of its methods.

Which function should I use if I want to be able to send data even when my apps are in the background?

Which function should I use to send UI updates to the Watch?

Which function should I use to send large data?

解决方案

At the time of writing this answer (watchOS3 is the current stable release and watchOS4 is in beta stage), the only option for direct communication between an iOS app and its WatchKit extension is the WatchConnectivity framework. (I said direct, because this Q&A is not concerned with using cloud technologies such as CloudKit to upload files to the internet from one device and download them on the other one.)

First, let's discuss which function of WCSession should be used for what purpose. For the code examples, please scroll down.

A quick, one-liner about each function and when to use them before diving deep into details:

  • updateApplicationContext: synchronise states between the apps, send data to be displayed on the UI (only use it to send small pieces of data)
  • transferUserInfo: send a dictionary of data in the background
  • transferFile: send a file in the background
  • sendMessage: send an instant message between at least the watch app is running in foreground

Detailed description

updateApplicationContext(_:) should be used if you want to synchronise your apps (such as keep the UI updated or send state information, like user logged in, etc.). You can send a dictionary of data. Subsequent calls to this function replace the previously sent dictionary, so the counterpart app only receives the last item sent using updateApplicationContext. The system tries to call this function at an appropriate time for it to receive data by the time it is needed and meanwhile minimising power usage. For this reason, the function can be called when neither app is running in the foreground, but WCSession needs to be activated for the transfer to succeed. Frequent calls trying to transfer large amount of data using updateApplicationContext might fail, so for this usage call transferUserInfo instead.

transferUserInfo(:) and transferCurrentComplicationUserInfo(:) should be used if you want to send data in the background that needs to be received by the other application. Subsequent calls to this method are queued and all information sent from one app to the other is received. transferCurrentComplicationUserInfo might be used to send complication-related data to the WatchKit extension using a high-priority message and waking up the WatchKit app if needed. However, be aware that this function has a daily limit and once it's exceeded, data is transferred using the transferUserInfo function.

transferFile(_:metadata:) is similar in implementation and nature to transferUserInfo, but it accepts a fileURL instead of a dictionary as its input parameter and hence it should be used to send files local to the device to its counterpart. Subsequent calls are queued. Received files must be saved to a new location in the session(_:didReceive:) method, otherwise they are deleted.

sendMessage(:replyHandler:errorHandler:) and sendMessageData(:replyHandler:errorHandler:) send data immediately to a counterpart app. The counterpart app must be reachable before calling this method. The iOS app is always considered reachable, and calling this method from your Watch app wakes up the iOS app in the background as needed. The Watch app is considered reachable only while it is installed and running. The transfer must be initiated in the foreground. Subsequent calls to this method are queued.

For more information please see App programming guide for watchOS - Sharing Data.

Now some code examples:

Set up WatchConnectivity in the iOS app's AppDelegate:

import UIKit
import WatchConnectivity

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        if WCSession.isSupported() {
            let session = WCSession.default()
            session.delegate = self
            session.activate()
        }
        return true
    }
}

extension AppDelegate: WCSessionDelegate {

    func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
        print("Message received: ",message)
    }

    //below 3 functions are needed to be able to connect to several Watches
    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {}

    func sessionDidDeactivate(_ session: WCSession) {}

    func sessionDidBecomeInactive(_ session: WCSession) {}
}

Make your WatchKit class conform to WCSessionDelegate:

extension InterfaceController: WCSessionDelegate {
    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {}
}

Using the instant messaging function, sendMessage:

In the WatchKit app use this code when you want to send information immediately to the iOS app.

if WCSession.isSupported() {
    print("WCSession supported")
    let session = WCSession.default()
    session.delegate = self
    session.activate()
    if session.isReachable {
        session.sendMessage(["Instant":"Message"], replyHandler: nil, errorHandler: { error in
            print("Error sending message",error)
        })
    }
}

这篇关于如何使用WatchConnectivity在iOS和Watch应用之间共享信息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆