swift 如何在 Watch 和后台 iPhone 之间共享数据
swift how to share data between Watch and iPhone on background
我有一个功能性应用程序可以在 iPhone 和 Watch 之间共享数据(共享文本),我想让它即使在手表设置为后台时也能正常工作(从 iPhone 发送数据在 Watch 处于后台时观看)。我阅读了很多有关如何制作此内容的文章,但似乎对我的应用程序没有任何好处。请添加代码以使应用程序像我之前所说的那样工作。或者给我一些适合这个应用程序的资源。谢谢!
iPhone的代码:
import UIKit
import WatchConnectivity
class ViewController: UIViewController, WCSessionDelegate {
@IBOutlet weak var iPhoneLabel: UILabel!
var session : WCSession!;
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
}
func sessionDidBecomeInactive(_ session: WCSession) {
}
func sessionDidDeactivate(_ session: WCSession) {
}
func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
let msg = message["b"] as? String;
self.iPhoneLabel.text = msg;
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
if(WCSession.isSupported()){
self.session = WCSession.default;
self.session.delegate = self;
self.session.activate();
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func sendMessage(_ sender: Any) {
session.sendMessage(["a" : "Hello"], replyHandler: nil, errorHandler: nil);
}
}
手表代码:
import WatchKit
import Foundation
import WatchConnectivity
import UIKit
class InterfaceController: WKInterfaceController, WCSessionDelegate {
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
}
@IBOutlet var WatchLabel: WKInterfaceLabel!
var session: WCSession!;
func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
//self.label.setText(message["a"]! as? String)
let msg = message["a"] as? String;
WatchLabel.setText(msg);
sendMessage();
}
func sendMessage(){
session.sendMessage(["b":"goodbye"], replyHandler: nil, errorHandler: nil);
}
override func awake(withContext context: Any?) {
super.awake(withContext: context)
// Configure interface objects here.
}
override func willActivate() {
// This method is called when watch view controller is about to be visible to user
super.willActivate()
if(WCSession.isSupported()){
self.session = WCSession.default;
self.session.delegate = self;
self.session.activate();
}
}
override func didDeactivate() {
// This method is called when watch view controller is no longer visible
super.didDeactivate()
}
}
在我将方法 session.sendMessage() 更改为 session.updateApplicationContext() 之后,它只有效一次。有什么建议吗?
iPhone的代码:
import UIKit
import WatchConnectivity
class ViewController: UIViewController, WCSessionDelegate {
@IBOutlet weak var iPhoneLabel: UILabel!
var session : WCSession!;
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
}
func sessionDidBecomeInactive(_ session: WCSession) {
}
func sessionDidDeactivate(_ session: WCSession) {
}
func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
let msg = applicationContext["b"] as? String
//Use this to update the UI instantaneously (otherwise, takes a little while)
DispatchQueue.main.async() {
self.iPhoneLabel.text = msg;
}
}
override func viewDidLoad() {
super.viewDidLoad()
if(WCSession.isSupported()){
self.session = WCSession.default;
self.session.delegate = self;
self.session.activate();
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
@IBAction func sendMessage(_ sender: Any) {
let applicationDict = ["a":"Hello"];
do {
try session.updateApplicationContext(applicationDict)
} catch {
print("error")
}
}
}
观看代码:
import WatchKit
import Foundation
import WatchConnectivity
import UIKit
class InterfaceController: WKInterfaceController, WCSessionDelegate {
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
}
@IBOutlet var WatchLabel: WKInterfaceLabel!
var session: WCSession!;
func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
print("Watch message received")
let msg = applicationContext["a"] as? String
DispatchQueue.main.async() {
self.WatchLabel.setText(msg);
}
sendMessage();
}
func sendMessage(){
print("Watch send message");
let applicationDict = ["b":"goodbye"];
do {
try session.updateApplicationContext(applicationDict)
} catch {
print("error")
}
}
override func awake(withContext context: Any?) {
super.awake(withContext: context)
// Configure interface objects here.
}
override func willActivate() {
// This method is called when watch view controller is about to be visible to user
super.willActivate()
if(WCSession.isSupported()){
self.session = WCSession.default;
self.session.delegate = self;
self.session.activate();
}
}
override func didDeactivate() {
// This method is called when watch view controller is no longer visible
super.didDeactivate()
}
}
简而言之,您应该使用 updateApplicationContext
方法而不是 sendMessage
方法,以便能够从 iPhone 应用程序发送数据,即使 Watch 应用程序在后台也是如此。更多信息,请继续。
如果您查看 documentation,它表明调用 session.sendMessage
不会唤醒 Watch
应用程序,如果它 运行 仅在后台运行。
Calling this method from your WatchKit extension while it is active
and running wakes up the corresponding iOS app in the background and
makes it reachable. Calling this method from your iOS app does not
wake up the corresponding WatchKit extension. If you call this method
and the counterpart is unreachable (or becomes unreachable before the
message is delivered), the errorHandler block is executed with an
appropriate error.
它还声明此功能仅在 isReachable
为 true
时有效。
Use the sendMessage(:replyHandler:errorHandler:) or sendMessageData(:replyHandler:errorHandler:) method to transfer data
to a reachable counterpart. These methods are intended for immediate
communication between your iOS app and WatchKit extension. The
isReachable property must currently be true for these methods to
succeed.
要发送用于更新 UI 的数据,您应该使用 updateApplicationContext(_:)
方法,using which
The system sends context data when the opportunity arises, with the
goal of having the data ready to use by the time the counterpart wakes
up.
要使此方法起作用,session
只需激活,不需要可达。
我有一个功能性应用程序可以在 iPhone 和 Watch 之间共享数据(共享文本),我想让它即使在手表设置为后台时也能正常工作(从 iPhone 发送数据在 Watch 处于后台时观看)。我阅读了很多有关如何制作此内容的文章,但似乎对我的应用程序没有任何好处。请添加代码以使应用程序像我之前所说的那样工作。或者给我一些适合这个应用程序的资源。谢谢!
iPhone的代码:
import UIKit
import WatchConnectivity
class ViewController: UIViewController, WCSessionDelegate {
@IBOutlet weak var iPhoneLabel: UILabel!
var session : WCSession!;
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
}
func sessionDidBecomeInactive(_ session: WCSession) {
}
func sessionDidDeactivate(_ session: WCSession) {
}
func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
let msg = message["b"] as? String;
self.iPhoneLabel.text = msg;
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
if(WCSession.isSupported()){
self.session = WCSession.default;
self.session.delegate = self;
self.session.activate();
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func sendMessage(_ sender: Any) {
session.sendMessage(["a" : "Hello"], replyHandler: nil, errorHandler: nil);
}
}
手表代码:
import WatchKit
import Foundation
import WatchConnectivity
import UIKit
class InterfaceController: WKInterfaceController, WCSessionDelegate {
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
}
@IBOutlet var WatchLabel: WKInterfaceLabel!
var session: WCSession!;
func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
//self.label.setText(message["a"]! as? String)
let msg = message["a"] as? String;
WatchLabel.setText(msg);
sendMessage();
}
func sendMessage(){
session.sendMessage(["b":"goodbye"], replyHandler: nil, errorHandler: nil);
}
override func awake(withContext context: Any?) {
super.awake(withContext: context)
// Configure interface objects here.
}
override func willActivate() {
// This method is called when watch view controller is about to be visible to user
super.willActivate()
if(WCSession.isSupported()){
self.session = WCSession.default;
self.session.delegate = self;
self.session.activate();
}
}
override func didDeactivate() {
// This method is called when watch view controller is no longer visible
super.didDeactivate()
}
}
在我将方法 session.sendMessage() 更改为 session.updateApplicationContext() 之后,它只有效一次。有什么建议吗?
iPhone的代码:
import UIKit
import WatchConnectivity
class ViewController: UIViewController, WCSessionDelegate {
@IBOutlet weak var iPhoneLabel: UILabel!
var session : WCSession!;
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
}
func sessionDidBecomeInactive(_ session: WCSession) {
}
func sessionDidDeactivate(_ session: WCSession) {
}
func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
let msg = applicationContext["b"] as? String
//Use this to update the UI instantaneously (otherwise, takes a little while)
DispatchQueue.main.async() {
self.iPhoneLabel.text = msg;
}
}
override func viewDidLoad() {
super.viewDidLoad()
if(WCSession.isSupported()){
self.session = WCSession.default;
self.session.delegate = self;
self.session.activate();
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
@IBAction func sendMessage(_ sender: Any) {
let applicationDict = ["a":"Hello"];
do {
try session.updateApplicationContext(applicationDict)
} catch {
print("error")
}
}
}
观看代码:
import WatchKit
import Foundation
import WatchConnectivity
import UIKit
class InterfaceController: WKInterfaceController, WCSessionDelegate {
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
}
@IBOutlet var WatchLabel: WKInterfaceLabel!
var session: WCSession!;
func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
print("Watch message received")
let msg = applicationContext["a"] as? String
DispatchQueue.main.async() {
self.WatchLabel.setText(msg);
}
sendMessage();
}
func sendMessage(){
print("Watch send message");
let applicationDict = ["b":"goodbye"];
do {
try session.updateApplicationContext(applicationDict)
} catch {
print("error")
}
}
override func awake(withContext context: Any?) {
super.awake(withContext: context)
// Configure interface objects here.
}
override func willActivate() {
// This method is called when watch view controller is about to be visible to user
super.willActivate()
if(WCSession.isSupported()){
self.session = WCSession.default;
self.session.delegate = self;
self.session.activate();
}
}
override func didDeactivate() {
// This method is called when watch view controller is no longer visible
super.didDeactivate()
}
}
简而言之,您应该使用 updateApplicationContext
方法而不是 sendMessage
方法,以便能够从 iPhone 应用程序发送数据,即使 Watch 应用程序在后台也是如此。更多信息,请继续。
如果您查看 documentation,它表明调用 session.sendMessage
不会唤醒 Watch
应用程序,如果它 运行 仅在后台运行。
Calling this method from your WatchKit extension while it is active and running wakes up the corresponding iOS app in the background and makes it reachable. Calling this method from your iOS app does not wake up the corresponding WatchKit extension. If you call this method and the counterpart is unreachable (or becomes unreachable before the message is delivered), the errorHandler block is executed with an appropriate error.
它还声明此功能仅在 isReachable
为 true
时有效。
Use the sendMessage(:replyHandler:errorHandler:) or sendMessageData(:replyHandler:errorHandler:) method to transfer data to a reachable counterpart. These methods are intended for immediate communication between your iOS app and WatchKit extension. The isReachable property must currently be true for these methods to succeed.
要发送用于更新 UI 的数据,您应该使用 updateApplicationContext(_:)
方法,using which
The system sends context data when the opportunity arises, with the goal of having the data ready to use by the time the counterpart wakes up.
要使此方法起作用,session
只需激活,不需要可达。