swift 如何在后台在 Watch 和 iPhone 之间共享数据

2024-03-22

我有一个用于在 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")
}
}

}

手表代码:

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即使 Watch 应用程序处于后台,也能够从 iPhone 应用程序发送数据。欲了解更多信息,请继续。

如果你看一下文档 https://developer.apple.com/documentation/watchconnectivity/wcsession,它指出调用session.sendMessage不唤醒Watch应用程序(如果它仅在后台运行)。

在 WatchKit 扩展处于活动状态时调用此方法 并且运行会在后台唤醒相应的iOS应用程序 使其可达。从您的 iOS 应用程序调用此方法不会 唤醒相应的WatchKit扩展。如果你调用这个方法 并且对方无法到达(或者在 消息已传递),errorHandler 块使用 适当的错误。

它还指出,此功能仅在以下情况下才有效isReachable is true.

使用发送消息(:replyHandler:errorHandler:) 或 sendMessageData(:replyHandler:errorHandler:)方法传输数据 到可到达的对方。这些方法旨在立即 iOS 应用程序和 WatchKit 扩展之间的通信。这 isReachable 属性当前必须为 true,这些方法才能 成功。

要发送用于更新 UI 的数据,您应该使用updateApplicationContext(_:)方法,使用哪个 https://developer.apple.com/documentation/watchconnectivity/wcsession/1615621-updateapplicationcontext

当机会出现时,系统会发送上下文数据,其中 目标是在对方醒来时准备好使用数据 向上。

为了使该方法发挥作用,session只需要激活,不需要可达。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

swift 如何在后台在 Watch 和 iPhone 之间共享数据 的相关文章

随机推荐