2016-11-12 22 views
7

Bir Apple Watch uygulaması geliştirmek için Xamarin kullanıyorum. Saatimden iPhone'a SendMessage işlevimle bir ileti göndermeye çalışıyorum. Bunu yaptığımda, payload could not be deliveredout hata mesajını alıyorum. Mesajın bir kısmını okuyabilirim ("yük yükü n ...") çünkü bir etikete yazıyorum (hata ayıklayıcım Xamarin’de çalışmıyor çünkü mesaja bakamıyorum) Biraz googling yapıyorum, yazdığı şey bu. Bir fikrin neden?WCSession Send Message Hata veriyor "yük getirilemedi"

public sealed class WCSessionManager : NSObject, IWCSessionDelegate 
{ 
    // Setup is converted from https://www.natashatherobot.com/watchconnectivity-say-hello-to-wcsession/ 
    // with some extra bits 
    private static readonly WCSessionManager sharedManager = new WCSessionManager(); 
    private static WCSession session = WCSession.IsSupported ? WCSession.DefaultSession : null; 

#if __IOS__ 
    public static string Device = "Phone"; 
#else 
    public static string Device = "Watch"; 
#endif 

    public event ApplicationContextUpdatedHandler ApplicationContextUpdated; 

    public delegate void ApplicationContextUpdatedHandler(WCSession session, Dictionary<string, object> applicationContext); 

    public event MessageReceivedHandler MessageReceived; 

    public delegate void MessageReceivedHandler(Dictionary<string, object> message, Action<Dictionary<string, object>> replyHandler); 

    private WCSession validSession 
    { 
     get 
     { 
#if __IOS__ 
      // Even though session.Paired and session.WatchAppInstalled are underlined, it will still build as they are available on the iOS version of WatchConnectivity.WCSession 
      Console.WriteLine($"Paired status:{(session.Paired ? '✓' : '✗')}\n"); 
      Console.WriteLine($"Watch App Installed status:{(session.WatchAppInstalled ? '✓' : '✗')}\n"); 
      return (session.Paired && session.WatchAppInstalled) ? session : null; 
      //return session; 
#else 
      return session; 
#endif 
     } 
    } 

    private WCSession validReachableSession 
    { 
     get 
     { 
      return session.Reachable ? validSession : null; 
     } 
    } 

    private WCSessionManager() : base() { } 

    public static WCSessionManager SharedManager 
    { 
     get 
     { 
      return sharedManager; 
     } 
    } 

    public void StartSession() 
    { 
     if (session != null) 
     { 
      session.Delegate = this; 
      session.ActivateSession(); 
      Console.WriteLine($"Started Watch Connectivity Session on {Device}"); 
     } 
    } 

    [Export("sessionReachabilityDidChange:")] 
    public void SessionReachabilityDidChange(WCSession session) 
    { 
     Console.WriteLine($"Watch connectivity Reachable:{(session.Reachable ? '✓' : '✗')} from {Device}"); 
     // handle session reachability change 
     if (session.Reachable) 
     { 
      // great! continue on with Interactive Messaging 
     } 
     else { 
      // prompt the user to unlock their iOS device 
     } 
    } 

    #region Application Context Methods 

    public void UpdateApplicationContext(Dictionary<string, object> applicationContext) 
    { 
     // Application context doesnt need the watch to be reachable, it will be received when opened 
     if (validSession != null) 
     { 
      try 
      { 
       var NSValues = applicationContext.Values.Select(x => new NSString(JsonConvert.SerializeObject(x))).ToArray(); 
       var NSKeys = applicationContext.Keys.Select(x => new NSString(x)).ToArray(); 
       var NSApplicationContext = NSDictionary<NSString, NSObject>.FromObjectsAndKeys(NSValues, NSKeys); 

       UpdateApplicationContextOnSession(NSApplicationContext); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine($"Exception Updating Application Context: {ex.Message}"); 
      } 
     } 
    } 

    public void GetApplicationContext() 
    { 
     UpdateApplicationContext(new Dictionary<string, object>() { { "GET", null } }); 
    } 

    [Export("session:didReceiveApplicationContext:")] 
    public void DidReceiveApplicationContext(WCSession session, NSDictionary<NSString, NSObject> applicationContext) 
    { 
     Console.WriteLine($"Recieving Message on {Device}"); 
     if (ApplicationContextUpdated != null) 
     { 
      var keys = applicationContext.Keys.Select(k => k.ToString()).ToArray(); 

      IEnumerable<object> values; 

      try 
      { 
       values = applicationContext.Values.Select(v => JsonConvert.DeserializeObject(v.ToString(), typeof(DoorWatchDTO))); 
      } 
      catch (Exception) 
      { 
       values = applicationContext.Values.Select(v => JsonConvert.DeserializeObject(v.ToString())); 
      } 

      var dictionary = keys.Zip(values, (k, v) => new { Key = k, Value = v }) 
           .ToDictionary(x => x.Key, x => x.Value); 

      ApplicationContextUpdated(session, dictionary); 
     } 
    } 

    [Export("session:didReceiveMessage::")] 
    public void DidReceiveMessage(WCSession session, NSDictionary<NSString, NSObject> message, WCSessionReplyHandler replyHandler) 
    { 
     if (MessageReceived != null) 
     { 
      var keys = message.Keys.Select(k => k.ToString()).ToArray(); 

      IEnumerable<object> values; 

      values = message.Values.Select(v => JsonConvert.DeserializeObject(v.ToString())); 

      var dictionary = keys.Zip(values, (k, v) => new { Key = k, Value = v }) 
           .ToDictionary(x => x.Key, x => x.Value); 

      MessageReceived(dictionary, (dict) => 
      { 
       var NSValues = dict.Values.Select(x => new NSString(JsonConvert.SerializeObject(x))).ToArray(); 
       var NSKeys = dict.Keys.Select(x => new NSString(x)).ToArray(); 
       var NSDict = NSDictionary<NSString, NSObject>.FromObjectsAndKeys(NSValues, NSKeys); 

       replyHandler.Invoke(NSDict); 
      }); 
     } 
    } 

    public void SendMessage(Dictionary<string, object> message, Action<Dictionary<string, object>> replyHandler, WKInterfaceLabel label) 
    { 
     if (validSession != null) 
     { 
      try 
      { 
       var NSValues = message.Values.Select(x => new NSString(JsonConvert.SerializeObject(x))).ToArray(); 
       var NSKeys = message.Keys.Select(x => new NSString(x)).ToArray(); 
       var NSMessage = NSDictionary<NSString, NSObject>.FromObjectsAndKeys(NSValues, NSKeys); 

       var reply = new WCSessionReplyHandler((replyMessage) => 
       { 
        var values = replyMessage.Values.Select(x => JsonConvert.SerializeObject(x)).ToArray(); 
        var keys = replyMessage.Keys.Select(x => x.ToString()).ToArray(); 

        var dict = keys.Zip(values, (k, v) => new { Key = k, Value = v }) 
            .ToDictionary(x => x.Key, x => (object)x.Value); 

        replyHandler.Invoke(dict); 
       }); 

       validSession.SendMessage(NSMessage, reply, (error) => 
       { 
        label.SetText(error.ToString()); // I can see the error in here: "payload could n..." 
       }); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine($"Exception sending message: {ex.Message}"); 
      } 
     } 
    } 

    private void UpdateApplicationContextOnSession(NSDictionary<NSString, NSObject> NSApplicationContext) 
    { 
     NSError error; 
     var sendSuccessfully = validSession.UpdateApplicationContext(NSApplicationContext, out error); 
     if (sendSuccessfully) 
     { 
      Console.WriteLine($"Sent App Context from {Device} \nPayLoad: {NSApplicationContext.ToString()} \n"); 

      #if __IOS__ 
      Logging.Log("Success, payload: " + NSApplicationContext.ToString()); 
      #endif 
     } 
     else 
     { 
      Console.WriteLine($"Error Updating Application Context: {error.LocalizedDescription}"); 

      #if __IOS__ 
      Logging.Log("error: " + error.LocalizedDescription); 
      #endif 
     } 
    } 

    #endregion 

cevap

7

ben onu çözdüm: İşte benim kodudur. IWCSessionDelegate'u uygulamak yerine, WCSessionDelegate'u uygulamak yerine, işlevleri gerektiği gibi geçersiz kıldım.

+1

Bunu söylemek için sabırsızlanıyorum bu özeti https://gist.github.com/b099l3/e5a361477168053f0d58ac3907ea16d6 xamarin örneklerine ekleyeceğim –

+0

Şu anda bu birleştirilmiş https://github.com/xamarin/ ios-samples/pull/131 –

+0

"WCSessionDelegate" uygulamıyorum ama aynı hatayı alıyorum –

İlgili konular