如何使用 WatchConnectivity 在我的 iOS 和 Watch 应用程序之间共享信息?
How can I share information between my iOS and Watch apps using WatchConnectivity?
[免责声明:此问题旨在成为一个 wiki 问题,用于回答有关 iOS 和 watchkit
和 [= 下的 watch 应用程序之间发送数据的常见问题12=] 标签。]
我正在开发 Apple Watch 应用程序,想在 iOS
应用程序与其 WatchKit extension
之间发送数据。我看过 WatchConnectivity
框架,但并不真正理解其所有方法之间的区别。
如果我想即使我的应用程序在后台也能发送数据,我应该使用哪个功能?
我应该使用哪个函数向手表发送 UI 更新?
发送大数据应该使用哪个函数?
在撰写此答案时(watchOS3
是当前的稳定版本,watchOS4
处于测试阶段),direct 的唯一选择iOS
应用与其 WatchKit extension
之间的通信是 WatchConnectivity 框架。 (我说的是直接的,因为这个问答不涉及使用CloudKit
等云技术从一台设备上传文件到互联网并在另一台设备上下载。)
首先,让我们讨论一下WCSession
的哪个功能应该用于什么目的。有关代码示例,请向下滚动。
在深入了解细节之前,简要介绍每个功能以及何时使用它们:
updateApplicationContext
:app之间同步状态,发送数据显示在UI(只用于发送小块数据)
transferUserInfo
:后台发送数据字典
transferFile
: 后台发送一个文件
sendMessage
:发送即时消息至少手表应用程序是运行在前台
详细说明
updateApplicationContext(_:) 如果你想同步你的应用程序(例如保持 UI 更新或发送状态信息,如用户登录等),应该使用。您可以发送数据字典。对该函数的后续调用会替换之前发送的字典,因此对方应用仅接收使用 updateApplicationContext
发送的最后一项。系统会尝试在适当的时间调用此函数,以便在需要时接收数据,同时最大限度地减少功耗。因此,当两个应用程序都不是 运行 在前台时可以调用该函数,但需要激活 WCSession
才能传输成功。尝试使用 updateApplicationContext
传输大量数据的频繁调用可能会失败,因此对于此用法,请改为调用 transferUserInfo
。
transferUserInfo(:) and transferCurrentComplicationUserInfo(:) 如果你想在后台发送需要被其他应用程序接收的数据,应该使用。对该方法的后续调用将排队,并接收从一个应用程序发送到另一个应用程序的所有信息。 transferCurrentComplicationUserInfo
可用于使用高优先级消息将与并发症相关的数据发送到 WatchKit extension
,并在需要时唤醒 WatchKit app
。但是,请注意此功能有每日限制,一旦超过,将使用 transferUserInfo
功能传输数据。
transferFile(_:metadata:) 在实现和性质上与 transferUserInfo
相似,但它接受 fileURL 而不是字典作为其输入参数,因此它应该用于将设备本地文件发送到它的对应物。后续呼叫排队。收到的文件必须保存到session(_:didReceive:)
方法中的新位置,否则将被删除。
sendMessage(:replyHandler:errorHandler:) and sendMessageData(:replyHandler:errorHandler:) 立即将数据发送到对应的应用程序。在调用此方法之前,必须可以访问对端应用程序。 iOS 应用程序始终被认为是可访问的,并且从您的 Watch 应用程序调用此方法会根据需要在后台唤醒 iOS 应用程序。 Watch 应用程序仅在已安装且 运行 时才被视为可访问。传输必须在前台启动。对该方法的后续调用将排队。
有关详细信息,请参阅 App programming guide for watchOS - Sharing Data。
现在一些代码示例:
在 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
class符合WCSessionDelegate
:
extension InterfaceController: WCSessionDelegate {
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {}
}
使用即时通讯功能,sendMessage
:
在 WatchKit app
中,如果您想立即将信息发送到 iOS
应用程序,请使用此代码。
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)
})
}
}
[免责声明:此问题旨在成为一个 wiki 问题,用于回答有关 iOS 和 watchkit
和 [= 下的 watch 应用程序之间发送数据的常见问题12=] 标签。]
我正在开发 Apple Watch 应用程序,想在 iOS
应用程序与其 WatchKit extension
之间发送数据。我看过 WatchConnectivity
框架,但并不真正理解其所有方法之间的区别。
如果我想即使我的应用程序在后台也能发送数据,我应该使用哪个功能?
我应该使用哪个函数向手表发送 UI 更新?
发送大数据应该使用哪个函数?
在撰写此答案时(watchOS3
是当前的稳定版本,watchOS4
处于测试阶段),direct 的唯一选择iOS
应用与其 WatchKit extension
之间的通信是 WatchConnectivity 框架。 (我说的是直接的,因为这个问答不涉及使用CloudKit
等云技术从一台设备上传文件到互联网并在另一台设备上下载。)
首先,让我们讨论一下WCSession
的哪个功能应该用于什么目的。有关代码示例,请向下滚动。
在深入了解细节之前,简要介绍每个功能以及何时使用它们:
updateApplicationContext
:app之间同步状态,发送数据显示在UI(只用于发送小块数据)transferUserInfo
:后台发送数据字典transferFile
: 后台发送一个文件sendMessage
:发送即时消息至少手表应用程序是运行在前台
详细说明
updateApplicationContext(_:) 如果你想同步你的应用程序(例如保持 UI 更新或发送状态信息,如用户登录等),应该使用。您可以发送数据字典。对该函数的后续调用会替换之前发送的字典,因此对方应用仅接收使用 updateApplicationContext
发送的最后一项。系统会尝试在适当的时间调用此函数,以便在需要时接收数据,同时最大限度地减少功耗。因此,当两个应用程序都不是 运行 在前台时可以调用该函数,但需要激活 WCSession
才能传输成功。尝试使用 updateApplicationContext
传输大量数据的频繁调用可能会失败,因此对于此用法,请改为调用 transferUserInfo
。
transferUserInfo(:) and transferCurrentComplicationUserInfo(:) 如果你想在后台发送需要被其他应用程序接收的数据,应该使用。对该方法的后续调用将排队,并接收从一个应用程序发送到另一个应用程序的所有信息。 transferCurrentComplicationUserInfo
可用于使用高优先级消息将与并发症相关的数据发送到 WatchKit extension
,并在需要时唤醒 WatchKit app
。但是,请注意此功能有每日限制,一旦超过,将使用 transferUserInfo
功能传输数据。
transferFile(_:metadata:) 在实现和性质上与 transferUserInfo
相似,但它接受 fileURL 而不是字典作为其输入参数,因此它应该用于将设备本地文件发送到它的对应物。后续呼叫排队。收到的文件必须保存到session(_:didReceive:)
方法中的新位置,否则将被删除。
sendMessage(:replyHandler:errorHandler:) and sendMessageData(:replyHandler:errorHandler:) 立即将数据发送到对应的应用程序。在调用此方法之前,必须可以访问对端应用程序。 iOS 应用程序始终被认为是可访问的,并且从您的 Watch 应用程序调用此方法会根据需要在后台唤醒 iOS 应用程序。 Watch 应用程序仅在已安装且 运行 时才被视为可访问。传输必须在前台启动。对该方法的后续调用将排队。
有关详细信息,请参阅 App programming guide for watchOS - Sharing Data。
现在一些代码示例:
在 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
class符合WCSessionDelegate
:
extension InterfaceController: WCSessionDelegate {
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {}
}
使用即时通讯功能,sendMessage
:
在 WatchKit app
中,如果您想立即将信息发送到 iOS
应用程序,请使用此代码。
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)
})
}
}