我有一个功能性应用程序,用于在iPhone和Watch之间共享数据(共享文本),我希望即使手表设置在后台也可以使用(当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.updateApplicationContext()更改方法session.sendMessage()后,它只能运行一次。有什么建议吗?
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")
}
}
}
Code fore Watch:
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()
}
}
答案 0 :(得分:1)
简而言之,即使Watch应用程序处于后台,您也应该使用updateApplicationContext
方法而不是sendMessage
来从iPhone应用程序发送数据。有关详细信息,请继续。
如果您查看,则表示如果session.sendMessage
应用仅在后台运行,则调用Watch
不会唤醒它。
在WatchKit扩展名处于活动状态时调用此方法 并运行在后台唤醒相应的iOS应用程序 使它可以访问。从您的iOS应用程序调用此方法不会 唤醒相应的WatchKit扩展。如果你调用这个方法 并且对方无法访问(或者之前无法访问) 消息传递),errorHandler块用。执行 适当的错误。
它还声明此功能仅在isReachable
为true
时才有效。
使用sendMessage(:replyHandler:errorHandler :)或sendMessageData(:replyHandler:errorHandler :)方法传输数据 到可达的对手。这些方法旨在立即实现 iOS应用和WatchKit扩展之间的通信。该 对于这些方法,isReachable属性当前必须为true 成功。
要发送用于更新用户界面的数据,您应该使用updateApplicationContext(_:)
方法,documentation
当机会出现时,系统会发送上下文数据 目标是在对方醒来时准备好使用数据 起来。
要使此方法有效,只需要激活session
,不需要它是可以访问的。