2016-11-12 6 views
7

मैं ऐप्पल वॉच ऐप विकसित करने के लिए ज़ैमरिन का उपयोग कर रहा हूं। मैं अपने घड़ी से अपने SendMessage फ़ंक्शन के साथ आईफोन में एक संदेश भेजने की कोशिश कर रहा हूं। जब मैं ऐसा करता हूं, तो मुझे out संदेश payload could not be delivered त्रुटि में मिलता है। मैं केवल संदेश का हिस्सा पढ़ सकता हूं ("पेलोड एन एन ...") क्योंकि मैं इसे लेबल पर लिख रहा हूं (क्योंकि मेरा डीबगर ज़ैमरिन में काम नहीं करता है, मैं संदेश पर नज़र डाल सकता हूं), लेकिन बाद में कुछ googling कर रहा हूँ मैं मान रहा हूँ कि यह क्या लिखा है। कोई विचार क्यों? यहां मेरा कोड है:WCSession संदेश भेजें त्रुटि देता है "पेलोड वितरित नहीं किया जा सका"

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 

उत्तर

7

मैंने इसे हल किया। IWCSessionDelegate को लागू करने के बजाय, मैं बस इसके बजाय WCSessionDelegate लागू करता हूं और आवश्यकतानुसार कार्यों को ओवरराइड करता हूं।

+1

कूल ment कहने के लिए मैंने इसे इस जिस्ट में अपडेट किया है https://gist.github.com/b099l3/e5a361477168053f0d58ac3907ea16d6 मैं इसे xamarin नमूने में जोड़ दूंगा –

+0

यह अब विलय हो गया है https://github.com/xamarin/ आईओएस-नमूने/पुल/131 –

+0

मैं 'WCSessionDelegate' लागू कर रहा हूं लेकिन मुझे एक ही त्रुटि मिल रही है –

संबंधित मुद्दे