Darius Darius - 26 days ago 23
C# Question

Get data from iPhone to Apple Watch with Xamarin

I am developing an iPhone app on Xamarin and have added an Apple Watch extension for watchOS 3.

I need to get data that is save on the iPhone to the watch extension.

I only need to get it once, and then save it on the watch so it can be used without the iPhone's presence. How can I do this?

EDIT

After reading some tutorials and sample code, I found how to send data from the iPhone to the watch. However, it's not working for me. Here is all the relevant code:

My

WCSessionDelegate
implementation on the iPhone project:

public class WatchConnectivityDelegate : WCSessionDelegate
{
public WatchConnectivityDelegate()
{
}

public override void DidReceiveApplicationContext(WCSession session, Foundation.NSDictionary<Foundation.NSString, Foundation.NSObject> applicationContext)
{
// I never get data from the watch (or try to). I only send data to the watch.
}
}


In the
FinishedLaunching
method in my
AppDelegate
:

public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
// Other code...
WatchConnectivity.WCSession.DefaultSession.Delegate = new WatchConnectivityDelegate();
WatchConnectivity.WCSession.DefaultSession.ActivateSession();
// Other code...
}


In my
WCSessionDelegate
implementation on the watch extension project:

public class WatchConnectivityDelegate : WCSessionDelegate
{
public WatchConnectivityDelegate()
{
}

public event EventHandler DataReceived;

public override void DidReceiveApplicationContext(WCSession session, Foundation.NSDictionary<Foundation.NSString, Foundation.NSObject> applicationContext)
{
DataReceived?.Invoke(this, EventArgs.Empty);
}
}


In my
ExtensionDelegate
class:

[Register("ExtensionDelegate")]
public class ExtensionDelegate : WKExtensionDelegate
{
public static WatchConnectivityDelegate WatchConnectivityDelegate;

public override void ApplicationDidFinishLaunching()
{
// Perform any final initialization of your application.

WatchConnectivityDelegate = new WatchConnectivityDelegate();
WatchConnectivity.WCSession.DefaultSession.Delegate = WatchConnectivityDelegate;
WatchConnectivity.WCSession.DefaultSession.ActivateSession();
}

public override void ApplicationDidBecomeActive()
{
// Restart any tasks that were paused (or not yet started) while the application was inactive.
// If the application was previously in the background, optionally refresh the user interface.
}

public override void ApplicationWillResignActive()
{
// Sent when the application is about to move from active to inactive state.
// This can occur for certain types of temporary interruptions
// (such as an incoming phone call or SMS message) or when the user quits the application
// and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, etc.
}
}


In my
InterfaceController
class:

public partial class InterfaceController : WKInterfaceController
{
protected InterfaceController(IntPtr handle) : base(handle)
{
// Note: this .ctor should not contain any initialization logic.
}

public override void Awake(NSObject context)
{
base.Awake(context);

ExtensionDelegate.WatchConnectivityDelegate.DataReceived += this.FunctionThatNeverGetsCalled;

// Configure interface objects here.
Console.WriteLine("{0} awake with context", this);
}
}


EDIT

Solved by using Iain Smith's
WCSessionManager
class

Answer

Depending on the data you could use update Application Context messages. In brief, application context is best used for transferring data that always needs to be updated to the latest information. This is important because, for all of the data that you’re transferring over, only the latest copy of that data will actually appear at your final destination.

Have a look at this sample once you get the message then you could save it in NSUserDefault or whatever suits.

It is written for watchOS 2.0+

WCSessionManager is class that handles the delegate calls have a look here

It is basically a singleton that helps manage the connection, so you dont have to put it in all your interface conteroller or viewcontrollers.

Its starts in ExtensionDelegate on the watch and in ApplicationDelegate on the phone.

Comments