Apple Watch / Watch Kit with Ionic

Is anyone building anything for Apple Watch with Ionic? I have started using MMWormhole and have a “glance” working, displaying real data from my Ionic app, and also the watchkit app itself that is communicating both ways with the Ionic App. It seems to be fine.

HOWEVER.

Communication only happens whilst the Ionic app is open on the iPhone (either real or simulator). Now obviously we are dealing with two different domains here - the WatchKit stuff is an embedded Objective C binary within my Xcode project, and the Ionic stuff is sitting in JavaScript files that obviously aren’t getting run in the background.

My question is whether I need to replicate some of my $http calls within Angular into Objective C in order to talk to my back end?

3 Likes

Hmm, so I’d use a solid plugin, this looks promising

Then add this plugin to let the app run in the background.

I am doing it right now!

So get ready to have your mind blown, because interfacing with the apple watch ESPECIALLY via cordova is a really weird thing to get used to. You’ve really got to get creative. That first plugin from Lee Crossly is what i’m using and it works really well.

So, getting to your answer:

If your app is already running, the watch kit extension can communicate with it via a type of socket layer that lee’s plugin will give you. HOWEVER if the app is not running in the background (aka memory pressure termination, or the user hasn’t opened it yet since restarting, or they closed it) then it won’t work. That is where you have to get creative. My watch app only relays data it doesn’t provide any real time functionality because it’s not consistent enough for it to be a good user experience in my opinion.

Relaying data over a period of time can be done using the NSUserDefaults, i’ve had great luck with these.

As for any real time networking, you will want to write your calls in objective-c. You can get your watch kit app set up with swift, however I’m not familiar with how to interface an objective-c library with swift. It’s doable, just haven’t tried it.

If you don’t have an apple watch to test on I would recommend getting one asap, my design and the way things work in my watch app changed dramatically once I got my watch because now I know first hand how people are using it.

Side note, a good way to think of how it all communicates is:

Your main app talks to the extension, if it’s open. The extension is like an app that runs when your watch app opens. The watch app holds all the interface and should have as little of logic as possible.

I hope I could answer some questions, it’s been a rough road figuring this out but I’ve got mine nailed down.

Thanks both - I’ll take a look at Lee’s plugin, although for what I’ve done so far the regular MMWormhole seems fine; I get two way communication between app and watch whilst the app is active.

I had pretty much decided on the NSUserDefaults method to pass remote API key etc. through to the Objective C world and then call my specific services form there. There’s no real overlap with what the app does and what the watchkit app does, so I’m not going to be repeating much, if anything. Just a shame that the two worlds remain separated.

And yes, I have a watch to test on :slight_smile:

1 Like

Just remember that the NSUserDefaults are stored in plain text and can be ready by anyone with basic computer skills. As long as the key is just for API access and the API handles all permissions then you should be fine.

Good luck and yay for the watch! I love mine haha.

I thought I’d replied to this, but just found the window open with a part-completed response! Apologies. I’ve deleted my partial reply, as I’ve gone the NSUserDefaults route which is working fine :slight_smile: Thanks for the pointers guys.

Steve

1 Like

And yes, the key is just for API access, with actual permissions handled at the back end.

1 Like

Here’s another plugin (I wrote!) that eases the communication between the watch and the javascript code by setting up a reliable way of sending messages back and forth between Watch/Objective-C and Cordova/JS (even if the app was not in the background) : https://github.com/ogoguel/cordova-apple-watch-conduit.

1 Like

Hi guys, I’m currently working on making it easy for Cordova devs to add AppleWatch support.

The current solutions (plugins) are excellent (and I’m borrowing ideas) but as most of us are JavaScript programmers the task of creating a storyboard and related controllers (let alone wiring of the communication bits like Wormhole and OpenParentApplication) is too high a barrier IMO.

The goal of this plugin is you don’t have to touch native code at all to create a WatchKit extension: https://github.com/Telerik-Verified-Plugins/AppleWatch

For instance, if you want a user to give feedback in your Watch app, you can add a button via JS in your index.html like this:

  'userInputButton': {
    'inputMode': 'WKTextInputModeAllowAnimatedEmoji',
    'suggestions': ['Yes', 'No', 'Maybe'],
    'title': {
      'value': 'Going?',
      'color': '#FFFFFF', // label color (red)
      'font': {
        'size': 10
      }
    },
    'color': '#CC0000', // button color
    'callback': 'onVoted'
  },

Aftter pressing the red button (not shown here) in the Watch app, the user will see this (standard WatchKit) UI:

And after selecting an option (like ‘Yes’), the JS callback ‘onVoted’ will be called, which can be anything, even a request to your server’s REST API, because your connected phone app will get some background time (even if it wasn’t running on the phone!).

  function onVoted(val) {
    console.log("The user selected this value on the watch: " + val);
  }

Force Touch context menu
That’s all cool, but it gets really funky when you can program a Force Touch event in JavaScript(!) WatchKit allows a ‘context menu’ per interfacecontoller (‘page’), so you can send the context menu config to the watch from JS as well. Here’s a menu showing a Play and Resume option:

'contextMenu': {
  // configure up to 4 items
  'items': [
    {
      'title': 'Play',
      'iconNamed': 'Play', // https://developer.apple.com/library/ios/documentation/WatchKit/Reference/WKInterfaceController_class/index.html#//apple_ref/doc/c_ref/WKMenuItemIcon
      'callback': 'onContextMenuPlay'
    },
    {
      'title': 'Resume',
      'iconNamed': 'Resume',
      'callback': 'onContextMenuResume'
    }
  ]

Which results in this UI after force touching the watch (or long pressing in the simulator):

And of course the JS callback onContextMenuPlay or onContextMenuResume will be invoked after the user selected the option.

Work in progress

The plugin is in alpha, so things will break and not all ideas have been implemented yet. This is a good time to give feedback if you have any helpful thoughts. We’re planning on releasing a 1.0 later this month.

Any and all feedback is much appreciated!

2 Likes

Hello,

I also use this plugin:
https://github.com/leecrossley/cordova-plugin-apple-watch591

But i cant get it working. I have configured my app groups, imported MMWormhole in the Xcode Project.
This is how the javasacript file looks like:

/******************************************************************************
*

  • Apple Watch Service

******************************************************************************/
myApp.service(‘watch’, function () {

var self = this;
var success = false;

// Init 
this.init = function (groupId) { // group.com.company.app
    document.addEventListener('deviceready', function () {
        applewatch.init(function (appGroupId) {
            // Success
            console.log("Apple Watch init success: " + appGroupId);
            success = true;
            
            // Add 'test' listener adn send message
            self.sendMessage("Test message", "channel1");
            self.addListener("channel2");

        }, function (err) {
            // Error
            console.log("Apple Watch init failed: " + err);
            success = false;

        }, groupId);

    }, false);
}


// Send message
this.sendMessage = function (message, queueName) {
    document.addEventListener('deviceready', function () {
        if (success) {
            applewatch.sendMessage(message, queueName);
            console.log("Apple Watch message send.");
        } else {
            console.log("Apple Watch not initialized: message not send.");
        }

    }, false);
}



// Add Listener
this.addListener = function (queueName) {
    document.addEventListener('deviceready', function () {
        if (success) {
            console.log("Apple Watch listener added.");
            applewatch.addListener(queueName, function (message) {
                console.log("Message received:: " + message);
                alert("Message received: " + message);
            });
        } else {
            console.log("Apple Watch not initialized: listener not added.");
        }

    }, false);
}

});

Any suggestions/help?

Would you please help , as i’m unable to install the plugin

Error: npm: Command failed with exit code 1 Error output:
npm ERR! code ENOPACKAGEJSON
npm ERR! package.json Non-registry package missing package.json: git+https://github.com/Telerik-Verified-Plugins/AppleWatch.
npm ERR! package.json npm can’t find a package.json file in your current directory.