2016-11-12 25 views
7

Tôi đang sử dụng Xamarin để phát triển ứng dụng Apple Watch. Tôi đang cố gắng gửi tin nhắn từ đồng hồ của mình đến iPhone với chức năng SendMessage của tôi. Khi tôi làm điều này, tôi nhận được trong các out lỗi thông báo payload could not be delivered. Tôi chỉ có thể đọc một phần của thông điệp ("tải trọng có thể n ...") bởi vì tôi đang viết nó trên một nhãn (vì trình gỡ lỗi của tôi không hoạt động trong Xamarin, tôi không thể xem thông báo), nhưng sau làm một số googling tôi giả định đó là những gì nó được viết. Bất kỳ ý tưởng tại sao? Đây là mã của tôi:Thông báo Gửi tin nhắn WCSession cung cấp lỗi "không thể gửi tải trọng"

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 

Trả lời

7

Tôi đã giải quyết. Thay vì thực hiện IWCSessionDelegate, tôi chỉ cần triển khai WCSessionDelegate thay thế và ghi đè các chức năng nếu cần.

+1

Thật thú vị khi nói rằng tôi đã cập nhật điều này trong gist này https://gist.github.com/b099l3/e5a361477168053f0d58ac3907ea16d6 Tôi sẽ thêm nó vào các mẫu xamarin –

+0

Thats it merged now now https://github.com/xamarin/ ios-samples/pull/131 –

+0

Tôi đang triển khai 'WCSessionDelegate' nhưng tôi gặp lỗi tương tự –

Các vấn đề liên quan