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 之间共享数据 的相关文章

  • Swift 中的 import 语句是否有相关成本?

    阅读字符串宣言 我看到一个段落 https github com apple swift blob master docs StringManifesto md batteries included关于避免Foundation不需要的时候导
  • UIView晃动动画

    我试图在按下按钮时使 UIView 摇动 我正在调整我找到的代码http www cimgf com 2008 02 27 core animation tutorial window shake effect http www cimgf
  • Apple Mach-O 链接器错误(静态,不是 ld)

    我最近遇到了 Apple Mach O 链接器错误 大多数指南建议将 构建设置 中的位码更改为 否 但它仅适用于 ld 错误 这与我的不同 我会提供截图 请帮忙修复bug pod HandySwift 导致了错误的出现 这是它的 Githu
  • 如何检测用户是否第一次打开应用程序[重复]

    这个问题在这里已经有答案了 是否可以检测用户是否是第一次打开iOS应用程序 使用Objective C 我想在用户第一次打开应用程序时显示欢迎消息 但之后不再向他们显示 我正在寻找类似的东西 BOOL firstTime AppDelega
  • 如何动态获取 UITableViewCell 的高度

    我创建了自定义的tableViewCell 我在UITableViewCell中添加了UIView SubView 所以我在 UIView 中的所有动态文本和图像内容都会根据文本和图像大小而变化 但现在 HeightforRowAtInde
  • 错误消息:您输入的捆绑包 ID 已被使用

    我正在尝试发布一个 iPhone 应用程序 这不是第一个 我过去已经发表过其他的 因此 我在第一个和第二个表单中输入了所需的信息 然后填写了第三个大表单 您还可以在其中上传图标和屏幕截图 好吧 我在上传屏幕截图之前按下了 保存 按钮 因为我
  • 从未调用过交互式委托方法

    我想在 ViewController 1 和 NavigationViewController 2 之间进行交互式转换 NavigationController 通过按钮调用 因此呈现时没有交互转换 它可以通过按钮或 UIPanGestur
  • 在 iOS 应用程序中拨打电话

    我有一些代码尝试在应用程序中进行调用 但它似乎不起作用 UIApplication myApp UIApplication sharedApplication NSString theCall NSString stringWithForm
  • 如何在 iOS 13 中将 UISegmentedControl 的背景颜色设置为白色

    iOS 13 对 UISegmentedControl 进行了一些更改 包括切换所选片段时的非常漂亮的动画 但是我注意到它没有显示backgroundColor属性正确 它似乎总是有一点色彩 我见过回答如何设置的问题selectedSegm
  • jQuery:离线后 POST 出错(iOS 和 Chrome)

    我构建了一个具有离线功能的 HTML5 Web 应用程序 使用 AppCache 程序流程为 Online 在网络上时 应用程序预加载一些基本信息 工作 Offline 用户拿着装有应用程序的平板电脑offline 然后在应用程序上执行他们
  • $0 和 $1 在 Swift 闭包中意味着什么?

    let sortedNumbers numbers sort 0 gt 1 print sortedNumbers 谁能解释一下什么 0 and 1在斯威夫特中意味着什么 另一个样本 array forEach actions append
  • 使用数组中的字符串淡入/淡出标签

    func setOverlayTitle self overlayLogo text Welcome var hello String Bon Jour GUTEN nMORGEN BONJOUR HOLA BUENOS D AS BUON
  • 如何删除 UITableView 中的缩进?

    首先 我对此很陌生 我很可能忘记了一些非常简单的事情 问题 我正在制作一个应用程序 在 a 中显示来自 imgur com 的随机图像tableView 由于某种原因 所有单元格都会缩进少量 如下图所示 我摆弄了许多设置storyboard
  • 无法以编程方式快速设置 NSLayoutConstraint 乘数...“无法分配给此表达式的结果

    我试图以编程方式快速设置乘法器的约束 当我设置该值时 它只会给我错误 无法分配给该表达式的结果 我用 IBOutlet 声明了 NSLayoutConstraint 然后设置乘数 就像我对另一个常量所做的那样 效果很好 但这个不会接受它 I
  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u
  • 如何使用 IOS 12 在 UITableViewCell 中正确添加 UICollectionView

    由于某些原因 在使用 Xcode 10 beta 时 我无法正确显示 tableview 单元格内集合中的某些项目 在过去的四天里我尝试了我所知道的一切 我做了一个小项目样本来看看我的问题是什么 如果有人想在本地运行完整代码 请参见此处 h
  • 从现有坐标地图套件中查找最近的位置

    我正在为拥有多家商店的客户开发 iPhone 应用程序 目标 C 我有数组中所有商店 20 的坐标 纬度 长 目前我正在考虑循环遍历商店坐标数组并获取从用户当前位置到商店位置的距离 然后将它们添加到数组中并按最小距离进行排序 这是正确的方法
  • 使用强光混合模式时突出显示伪影

    我正在 iPhone 应用程序中使用顶部图像的 HardLight 混合模式混合两个图像 它看起来像这样 UIGraphicsBeginImageContext size sourceImage drawInRect rectangle b
  • Unwind segue 的用途是什么以及如何使用它们?

    iOS 6 和 Xcode 4 5 有一个称为 Unwind Segue 的新功能 展开转场可以允许过渡到故事板中场景的现有实例 除了 Xcode 4 5 发行说明中的 这个简短条目之外 UIViewController 现在似乎还有几个新
  • 节拍匹配算法

    我最近开始尝试创建一个移动应用程序 iOS Android 它将自动击败比赛 http en wikipedia org wiki Beatmatching http en wikipedia org wiki Beatmatching 两

随机推荐