WCSession sendMessage:replyHandler错误代码7014(WCErrorCodeDeliveryFailed)

gse*_*mpe 18 ios watchos-2 wcsession

我有一个Watch OS 2应用程序,通过WCSession方法与iOS应用程序通信sendMessage:replyHandler:errorHandler:

iOS应用程序正确回复,但我不时收到7014域代码错误WCErrorDomain:"无法传递Payload"

当iOS应用程序不是前台时,它会更频繁地发生.

我没有找到任何这个问题的解决方案,我希望你们中的一个知道这个问题的解决方案

Pet*_*ert 11

对于在iOS10 beta 6和GM上遇到问题的任何人,并且您使用的是Swift3,解决方案是将iOS应用中的委托功能标题更改为以下内容:

    func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) {
Run Code Online (Sandbox Code Playgroud)

注意@escaping和Any而不是AnyObject类型.


sta*_*Man 5

就我而言,我必须实现两个代表:

  1. 在一个没有任何replyHandler

    func session(_ session: WCSession,
                     didReceiveMessage message: [String : Any])
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在一个 replyHandler

    func session(_ session: WCSession,
                 didReceiveMessage message: [String : Any],
                 replyHandler: @escaping ([String : Any]) -> Void)
    
    Run Code Online (Sandbox Code Playgroud)

如果您在没有a replyHandler的情况下发送消息,则第一个委托运行.
如果您发送带有a的消息,replyHandler则第二个代理运行.


在某些情况下,我只发送一条消息,而在其他情况下,我发送了一条消息并期待对方的回复.
但是......我只实施了第二个代表-_-

无论如何,最终减少重复的代码我实现了一个常见的方法,最终得到:

func session(_ session: WCSession,
             didReceiveMessage message: [String : Any]) {
    handleSession(session, 
                  didReceiveMessage: message)
}

func session(_ session: WCSession,
             didReceiveMessage message: [String : Any],
             replyHandler: @escaping ([String : Any]) -> Void) {
    handleSession(session, 
                  didReceiveMessage: message, 
                  replyHandler: replyHandler)
}

//Helper Method
func handleSession(_ session: WCSession,
                   didReceiveMessage message: [String : Any],
                   replyHandler: (([String : Any]) -> Void)? = nil) {
    //Common logic
}
Run Code Online (Sandbox Code Playgroud)

观看OS 4


Vis*_*. S 4

试试这个,这解决了我的问题。在 InterfaceController 内部添加以下方法将数据传递到手机。

-(void)sendDataToPhone:(NSDictionary* _Nonnull)dictData
{
    if(WCSession.isSupported){

        WCSession* session = WCSession.defaultSession;
        session.delegate = self;
        [session activateSession];

        if(session.reachable)
        {
            [session sendMessage:dictData replyHandler: ^(NSDictionary<NSString *,id> * __nonnull replyMessage) {

                dispatch_async(dispatch_get_main_queue(), ^{
                    NSLog(@".....replyHandler called --- %@",replyMessage);
                    // Play a sound in watch
                    [[WKInterfaceDevice currentDevice] playHaptic:WKHapticTypeSuccess];
                });
            }
                    errorHandler:^(NSError * __nonnull error) {
                        dispatch_async(dispatch_get_main_queue(), ^{
                            NSLog(@"Error = %@",error.localizedDescription);
                        });
                    }
             ];
        }
        else
            NSLog(@"Session Not reachable");
    }
    else
        NSLog(@"Session Not Supported");
}



#pragma mark - Standard WatchKit delegate

-(void)sessionWatchStateDidChange:(nonnull WCSession *)session
{
    if(WCSession.isSupported){
        WCSession* session = WCSession.defaultSession;
        session.delegate = self;
        [session activateSession];

    }
}
Run Code Online (Sandbox Code Playgroud)

在手机端添加以下代码,用于接收手表数据。

在 didFinishLaunchingWithOptions 中添加以下内容。

// Allocating WCSession inorder to communicate back to watch.
    if(WCSession.isSupported){
        WCSession* session = WCSession.defaultSession;
        session.delegate = self;
        [session activateSession];
    }
Run Code Online (Sandbox Code Playgroud)

现在添加 WCSessionDelegate。

#pragma mark - WCSession Delegate

- (void)session:(WCSession *)session didReceiveMessage:(NSDictionary<NSString *, id> *)message replyHandler:(void(^)(NSDictionary<NSString *, id> *replyMessage))replyHandler
{
    if(message){
        NSData *receivedData = [message objectForKey:@"AudioData"];
        NSDictionary* response = @{@"response" : [NSString stringWithFormat:@"Data length: %lu",(unsigned long)receivedData.length]} ;
        replyHandler(response);
    }
}


#pragma mark - Standard WatchKit Delegate

-(void)sessionWatchStateDidChange:(nonnull WCSession *)session
{
    if(WCSession.isSupported){
        WCSession* session = WCSession.defaultSession;
        session.delegate = self;
        [session activateSession];

        if(session.reachable){
            NSLog(@"session.reachable");
        }

        if(session.paired){
            if(session.isWatchAppInstalled){

                if(session.watchDirectoryURL != nil){

                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

希望这对您有帮助:)