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 delivered
out
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
Bunu söylemek için sabırsızlanıyorum bu özeti https://gist.github.com/b099l3/e5a361477168053f0d58ac3907ea16d6 xamarin örneklerine ekleyeceğim –
Şu anda bu birleştirilmiş https://github.com/xamarin/ ios-samples/pull/131 –
"WCSessionDelegate" uygulamıyorum ama aynı hatayı alıyorum –