React Native iOS向WatchOS Swift发送消息失败问题排查(WCSession)
问题:React Native iOS 向 WatchOS Swift 应用发消息失败(错误码EWCERRORDOMAIN7014)
我需要从React Native开发的iOS应用,向Swift开发的WatchOS应用发送消息,但点击发送按钮后收到「Payload data could not be sent」错误(错误码EWCERRORDOMAIN7014),WatchOS端也没收到任何消息或错误提示。
React Native 端代码
import React from 'react'; import {Button, View} from 'react-native'; import * as Watch from 'react-native-watch-connectivity'; const Component = () => { const sendMessageToWatch = () => { Watch.getIsWatchAppInstalled().then((isInstalled) => { if (!isInstalled) { console.log('getIsWatchAppInstalled -> No'); } else { console.log('getIsWatchAppInstalled -> Yes'); } }); Watch.getIsPaired().then((isPaired) => { if (!isPaired) { console.log('isPaired -> No'); } else { console.log('isPaired -> Yes'); } }); Watch.sendMessageData('valueMessage') .then((response) => { console.log('response -> ', response); }) .catch((error) => { console.log('error -> ', error); console.log('error.code -> ', error.code); console.log('error.message -> ', error.message); }); }; return ( <View> <Button title="Send Message" onPress={sendMessageToWatch} /> </View> ); }; export default Component;
React Native 端点击按钮后的日志
getIsWatchAppInstalled -> Yes isPaired -> Yes error.code -> EWCERRORDOMAIN7014 error.message -> Les données utiles n’ont pas pu être envoyées. //In English -> Payload data could not be sent. error.code -> {"code": "EWCERRORDOMAIN7014", "domain": "WCErrorDomain", "message": "Les données utiles n’ont pas pu être envoyées.", "nativeStackIOS": ["0 SwimWorkout 0x00000001030c11b0 RCTJSErrorFromCodeMessageAndNSError + 112", "1 SwimWorkout 0x00000001030c1100 RCTJSErrorFromNSError + 236", "2 SwimWorkout 0x00000001030627d8 __41-[RCTModuleMethod processMethodSignature]_block_invoke_4.56 + 132", "3 SwimWorkout 0x0000000102fb11ac __56-[RNWatch sendMessageData:encoding:replyCallback:error:]_block_invoke.73 + 72", "4 WatchConnectivity 0x000000022cdb2ff4 E79B7B28-4F4E-36F7-BB22-2E9D64BE49C3 + 94196", "5 Foundation 0x00000001b0aa5c00 60F744F4-1345-325E-8970-D37BB5A1A31D + 302080", "6 Foundation 0x00000001b0ad70ec 60F744F4-1345-325E-8970-D37BB5A1A31D + 504044", "7 Foundation 0x00000001b0ad4974 60F744F4-1345-325E-8970-D37BB5A1A31D + 493940", "8 Foundation 0x00000001b0ad3a64 60F744F4-1345-325E-8970-D37BB5A1A31D + 490084", "9 Foundation 0x00000001b0ad657c 60F744F4-1345-325E-8970-D37BB5A1A31D + 501116", "10 Foundation 0x00000001b0ad62e8 60F744F4-1345-325E-8970-D37BB5A1A31D + 500456", "11 libdispatch.dylib 0x00000001b99ed6a8 149FF9CD-3E92-321D-B92F-EF58717C70B6 + 9896", "12 libdispatch.dylib 0x00000001b99ef300 149FF9CD-3E92-321D-B92F-EF58717C70B6 + 17152", "13 libdispatch.dylib 0x00000001b99f27b8 149FF9CD-3E92-321D-B92F-EF58717C70B6 + 30648", "14 libdispatch.dylib 0x00000001b99f1dd4 149FF9CD-3E92-321D-B92F-EF58717C70B6 + 28116", "15 libdispatch.dylib 0x00000001b9a00be4 149FF9CD-3E92-321D-B92F-EF58717C70B6 + 89060", "16 libdispatch.dylib 0x00000001b9a013ec 149FF9CD-3E92-321D-B92F-EF58717C70B6 + 91116", "17 libsystem_pthread.dylib 0x000000021acaa928 _pthread_wqthread + 228", "18 libsystem_pthread.dylib 0x000000021acaaa04 start_wqthread + 8"], "userInfo": {"NSLocalizedDescription": "Les données utiles n’ont pas pu être envoyées."}}
WatchOS 端代码(应用启动时执行)
import WatchKit import SwiftUI import WatchConnectivity class WatchSessionManager: NSObject, WCSessionDelegate { func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { print("WCSession activation completed with state: \(activationState.rawValue)") if let error = error { print("WCSession activation failed with error: \(error.localizedDescription)") } } func session(_ session: WCSession, didReceiveMessage message: [String : Any]) { print("Received message from iPhone: \(message)") } } @main struct SwimWorkoutWatch_Watch_AppApp: App { let watchSessionManager = WatchSessionManager() init() { if WCSession.isSupported() { let session = WCSession.default session.delegate = watchSessionManager session.activate() print("WCSession is supported and activated.") } else { print("WCSession is not supported on this device.") } } var body: some Scene { WindowGroup { ContentView() } } }
WatchOS 端启动日志
WCSession is supported and activated. WCSession activation completed with state: 2
问题排查与解决
1. 消息格式不匹配
WatchConnectivity要求发送的消息必须是字典类型([String: Any]),而你在RN端使用sendMessageData传递了纯字符串,不符合接口要求。应改用sendMessage方法传递字典:
// 替换原sendMessageData调用 Watch.sendMessage({ content: 'valueMessage' }) .then((response) => { console.log('response -> ', response); }) .catch((error) => { console.log('error -> ', error); });
2. 修复Watch端会话管理器生命周期
当前Watch端的WatchSessionManager是局部实例,可能被提前释放导致代理失效。改用@StateObject持有实例,保证其生命周期与App一致:
@main struct SwimWorkoutWatch_Watch_AppApp: App { @StateObject private var watchSessionManager = WatchSessionManager() init() { if WCSession.isSupported() { let session = WCSession.default session.delegate = watchSessionManager session.activate() print("WCSession is supported and activated.") } else { print("WCSession is not supported on this device.") } } var body: some Scene { WindowGroup { ContentView() } } }
3. 补充必要的WCSession代理方法
WatchConnectivity要求代理实现所有必需的方法,否则会导致会话异常。在WatchSessionManager中补充以下方法:
extension WatchSessionManager { // 处理带回复的消息接收 func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) { print("Received message from iPhone: \(message)") replyHandler(["status": "success"]) } // 处理会话状态变化 func sessionDidBecomeInactive(_ session: WCSession) { print("WCSession became inactive") } func sessionDidDeactivate(_ session: WCSession) { print("WCSession deactivated") session.activate() } }
4. 验证设备连接状态
- 确保iPhone与Apple Watch处于同一Wi-Fi或蓝牙连接正常
- 重启两端应用,重新激活会话
- 确认Watch应用与iOS应用使用同一开发者账号签名,且配置了相同的App Group(若需要共享数据)
内容的提问来源于stack exchange,提问作者Lucas Bodin
相关产品推荐
相关产品推荐

