gpt4 book ai didi

ios - WatchConnectivity:WCSession.transferUserInfo 在 watch 上成功,但数据从未到达 iPhone

转载 作者:行者123 更新时间:2023-12-04 13:30:13 32 4
gpt4 key购买 nike

语境
我正在使用 Xcode 12.3 为 iOS 应用程序构建 watchOS 应用程序(即它不是独立的 watchOS 应用程序)。
由于用户在 watch 上的操作,我的 watchOS 应用程序需要向 iOS 发送少量数据(包含字符串和日期的结构),然后 iOS 应用程序会将接收到的数据保存在自己的存储中。 watch 中的数据不需要立即传输,但也不能丢失,最终必须到达 iOS 应用程序。我认为 transferUserInfo(_:) WCSession的方法最适合我的需要。
问题
当我打电话时transferUserInfo_:在 watchOS 模拟器上的默认 WCSession 上,一切都成功了,但数据永远不会到达对应的 iOS 应用程序。
我使用 Xcode 12.3、iOS 14.3 模拟器和配对的 watchOS 7.2 模拟器。
我确保在应用程序启动时激活 WCSession 并检查它是否已成功激活,并在尝试传输用户信息之前检查 session 是否处于事件状态。
奇怪的是,我能够使用 updateApplicationContext(_:) 将数据从 iOS 传输到 watchOS。 WCSession 的方法,但无法将数据从 watch 传输回 iOS 应用程序。
代码
我已经建立了一个最小的例子来说明这个问题。 watchOS 应用程序显示一个按钮,当用户点击它时,它应该向 iOS 发送一个随机数。 iOS 应用程序应该在屏幕上的文本标签中显示收到的号码。
这是示例 iOS 应用程序的完整代码,它只是一个文件:

import os
import SwiftUI
import WatchConnectivity

class WatchConnectivityService: NSObject, ObservableObject {
@Published private(set) var receivedNumber: Int
private let logger = Logger(subsystem: "WCExperimentsiOSApp", category: "WatchConnectivityService")
private let wcSession: WCSession

override init() {
self.receivedNumber = -9999
self.wcSession = WCSession.default
super.init()
if WCSession.isSupported() {
wcSession.delegate = self
wcSession.activate()
}
}
}

extension WatchConnectivityService: WCSessionDelegate {
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
logger.notice("WCSession activationDidCompleteWith state: \(activationState), error: \(error?.localizedDescription ?? "nil")")
}

func sessionDidBecomeInactive(_ session: WCSession) {
logger.notice("WCSession sessionDidBecomeInactive")
}

func sessionDidDeactivate(_ session: WCSession) {
logger.notice("WCSession sessionDidDeactivate")
}

func session(_ session: WCSession, didReceiveUserInfo userInfo: [String : Any] = [:]) {
logger.notice("Received userInfo: \(userInfo)")
if let number = userInfo["number"] as? Int {
DispatchQueue.main.async {
self.receivedNumber = number
}
}
}
}

@main
struct WatchConnectivityExperimentsApp: App {
@StateObject var service = WatchConnectivityService()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(service)
}
}
}

struct ContentView: View {
@EnvironmentObject var service: WatchConnectivityService
var body: some View {
Text("Received number: \(service.receivedNumber)")
}
}
一旦 iOS 应用程序启动,我可以看到一条关于成功激活 WCSession 的日志消息,它看起来是这样的:“WCSession activationDidCompleteWith state:activated, error: nil”。
这是 watchOS 扩展的完整代码:
import os
import SwiftUI
import WatchConnectivity

class WatchConnectivityService: NSObject, ObservableObject {
private let wcSession: WCSession
private let logger = Logger(subsystem: "WCExperimentsWatchApp", category: "WatchConnectivityService")

override init() {
self.wcSession = WCSession.default
super.init()
if WCSession.isSupported() {
wcSession.delegate = self
wcSession.activate()
}
}

func sendNumberToiOS() {
guard wcSession.activationState == .activated else {
logger.error("Error attempting to transfer user info: WCSession is not activated")
return
}
let randomNumber = Int.random(in: 1...1000)
wcSession.transferUserInfo(["number": randomNumber])
}
}

extension WatchConnectivityService: WCSessionDelegate {
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
logger.notice("WCSession activationDidCompleteWith state: \(activationState), error: \(error?.localizedDescription ?? "nil")")
}

func session(_ session: WCSession, didFinish userInfoTransfer: WCSessionUserInfoTransfer, error: Error?) {
logger.notice("WCSession didFinish userInfoTransfer: \(userInfoTransfer.userInfo), error: \(error?.localizedDescription ?? "nil")")
}
}

@main
struct WatchConnectivityExperimentsApp: App {
@StateObject var service = WatchConnectivityService()
var body: some Scene {
WindowGroup {
NavigationView {
ContentView()
.environmentObject(service)
}
}
}
}

struct ContentView: View {
@EnvironmentObject var service: WatchConnectivityService
var body: some View {
VStack {
Button(action: { service.sendNumberToiOS() }, label: {
Text("Send random number to iOS app")
})
}
}
}
在 watchOS 应用程序中,我还看到一条日志消息,表明 WCSession 在启动时已成功激活。
当我点击 watch 模拟器上的按钮时,我看到 WCSessionDelegate 方法 func session(_ session: WCSession, didFinish userInfoTransfer: WCSessionUserInfoTransfer, error: Error?)被调用并且它没有报告错误。例如:“WCSession didFinish userInfoTransfer: ["number": 683], error: nil”。
之后,我在连接到 watch 模拟器的 Console.app 中看到以下日志:

Process: wcd (Foundation) Subsystem:com.apple.foundation.filecoordination Category: claims Message: Writeoptions: 8 -- URL: Library/Application<decode: mismatch for [%20S] got[SCALARsz:8]>upport/com.apple.watchconnectivity/E88632F5-57F5-49F9-9CE8-98C1AA6C31CB/UserInfoTransfers/contents.index-- file:///Users/myusername/Library/Developer/CoreSimulator/Devices/753CCF4F-FFAD-4416-BBC6-E23234D0A500/data/Containers/Data/Application/4802344B-0A89-493C-82B3-60D41C76B8B2/-- purposeID: 2F068AB7-4DC3-4A75-9745-A74AD9179CA4 -- claimID: FF99C583-0CED-44D0-8403-BD342FCE6CAC

Process: WCExperimentsWatchApp Extension Subsystem:com.apple.foundation.filecoordination Category: claims Message: Readoptions: 1 -- URL: Library/Application<decode: mismatch for [%20S] got[SCALARsz:8]>upport/com.apple.watchconnectivity/E88632F5-57F5-49F9-9CE8-98C1AA6C31CB/UserInfoTransfers/contents.index-- file:///Users/myusername/Library/Developer/CoreSimulator/Devices/753CCF4F-FFAD-4416-BBC6-E23234D0A500/data/Containers/Data/Application/4802344B-0A89-493C-82B3-60D41C76B8B2/-- purposeID: D53FBF3C-8B2C-48FB-9390-9058CAD4C757 -- claimID: 62292E97-3529-415A-B6B3-1768387D67B4


在iOS端,WCSessionDelegate方法 session(_ session: WCSession, didReceiveUserInfo userInfo: [String : Any] = [:])永远不会被调用,iOS 应用程序永远不会从 watch 接收任何数据。
我尝试了不同的模拟器,尝试重置模拟器的所有内容和设置,但没有效果。不幸的是,我无法使用真正的 Apple Watch 对其进行测试,因为我没有。
有人可以建议我是否做错了什么吗?如何正确地将用户信息从 watch 发送到 iPhone?
提前致谢。

最佳答案

Apple's docs最后包含以下警告:

Warning

Always test Watch Connectivity data transfers on paireddevices. The Simulator app doesn’t support the transferUserInfo(_:)method.


对于 transferFile(_:metadata:) 也是如此.

关于ios - WatchConnectivity:WCSession.transferUserInfo 在 watch 上成功,但数据从未到达 iPhone,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65530895/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com