A tutorial for sharing data between iOS and watchOS with Swift and Xcode

Eric Walker
Jun 15 · 6 min read
WatchConnectivity Demo

Introduction

I’ve been searching the internet for a nicely laid out example (in Swift) for WatchConnectivity.

After searching for a while, I couldn’t really find what I wanted, so I decided I’d learn the topic myself through Apple documentation and some other sources.

I hope to make this topic a series, in that, if there’s something that I can’t find a good tutorial for, I’ll use Apple documentation and other sources to learn the topic myself. I’ll then create a demo application and write a story here, to showcase everything I’ve learned.

I’ll also leave the project files for this tutorial in their own section at the bottom of this post, so you can download them and follow along with this tutorial.


What is it and how is it useful?

WatchConnectivity, at its roots, is an easy way to share data from the iOS app to the watchOS app, and vice versa.

I’ve created a few apps on the App Store that would benefit from having this as a feature. It would be nice to be able to ‘sync’ (for lack of a better word) the score you have on your phone with the score on your watch, and the other way around.

Now that I have learned how to use WatchConnectivity, I will definitely be implementing it in my games.


Requirements

  • Xcode 10
  • Swift 4 (and up)

I will assume you already have Xcode installed and set up, and you’re are ready to start, because this is a slightly more advanced tutorial than just showing you that you can print a variable in Xcode.


Getting Started

First thing is to open Xcode and choose the iOS App with WatchKit App. That way we don’t have to mess with targets later.

In the next screen, choose a Product Name and fill out the rest of the necessary fields. You can uncheck Include Notification Scene, as it is checked by default in Xcode 10.2.1, and we don’t need it for this tutorial.

Now you have a blank Xcode project.


The Interface

I always like to build the interfaces first, as I’m someone who likes to see progress with things I do, and building a UI always helps me feel like I’ve accomplished something.

First, go into Main.storyboard and drag a Text Field and a Button onto the iOS storyboard.

Configure the Text Field and the Button to your requirements. Go into the assistant editor by holding down Command-Alt-Enter and make IBOutlets in ViewController.swift.

This is what my interface looks like after adding a Text Field and a Button.

Now open up your Interface.storyboard, so we can start configuring the way our Apple Watch app will look. One warning tough; the UI’s won’t look great, because I wanted to make the simplest tutorial I could and didn’t want to get hung up on looks.

For the Watch app, all you need is a label at the top of the screen, for it to do the same as the iOS app, and connect the label to an IBOutlet in the InterfaceController.swift.

My Apple Watch UI looked like this when I was done (the dashes in the label are just an example of a placeholder I like to use for these situations).


The Code

We’ve created a bare-minimum UI, but now it’s time for what you came here for — the code that makes everything work.

First, let’s start with the iOS side of things.

Below is a completely finished version of my ViewController.swift. I wanted you to see how little there actually is to making this work.

Underneath the code will be an explanation of everything in the file.

  • Line 3. In order to get your watch and phone to talk to each other, we need to import a framework that will allow this, so we Import WatchConnectivity.
  • Line 5. After the deceleration Class ViewController: UIViewController, we have to allow the iOS app to make use of the above import statement, so we add the WCSessionDelegate for the app to take advantage of the WatchConnectivity framework.
  • Line 9. This is just the outlet for the Text Field on Main.storyboard.
  • Line 13. To make accessing the WCSession class a little easier I’ve stored it in a variable.
  • Lines 20–22. Setting the variable from above to a default session and setting the WCSession delegate to the ViewController, and finally activating the WCSession session.
  • Line 28. This is the action for the Button on Main.storyboard.
  • Line 30. This sets the variable txt to the Text Field, which is currently in the field itself
  • Line 31. For us to be able to send any data to the watch, we have to create a dictionary with the data we want to send. For this tutorial I’m just sending a string (txt) to the watch, under the key message.
  • Lines 33–37. This is the method that actually sends data to the watch. I also did some error handing with the print(error.localizedDescription), but you don’t have to. Just pass the variable message into the method wcSession.sendMessage() and you should be good to go.
  • Lines 42–58. These are just default methods that come with the delegate WCSessionDelegate but we don’t need them for this tutorial.

So once you’re done with that, your iOS app should be ready to go.


The WatchOS Side of Things

Now, let’s get started on the watchOS side of things. You’ll find the complete version of my InterfaceController.swift below, but I will still go through it in relative detail.

  • Line 4. Just like in ViewController.swift we need to import WatchConnectivity so we can use that framework.
  • Line 6. We need to add WCSessionDelegate to the InterfaceController (this will again come with default methods that we won’t use for this tutorial).
  • Line 10. The label outlet from Interface.storyboard.
  • Line 14. WCSession variable just like above.
  • Lines 26–28. The same code from ViewController.swift, which is basically just making sure that the WCSession session starts as soon as the ViewController and the InterfaceController start up.
  • Line 37. Method from WCSessionDelegate that allows the watch to run code when a message from the iOS app is received.
  • Line 39. Setting a variable, text, to the message that the iOS app sends. The didRecieveMessage method passes through a dictionary of data. This dictionary is the same dictionary that the iOS app sent, so the string inside the brackets must be the same as the key in the dictionary in ViewController.swift.
  • Line 41. This sets the label text to the value from the dictionary that’s passed to the didRecieveMessage method.

And that is it for the watchOS code!


Running the Apps

Now all you have to do is run the scheme that deploys the app to the Apple Watch. Once the Apple Watch app loads (it may take a few minutes the first time), click the app on the iPhone home screen. Now you should have both apps running.

All that’s left to do, is type a message into the text field and click the button — and watch the label on the Apple Watch update within a few seconds of clicking the button. A demo of this can be shown at the top of the page.


Conclusion

I’ve enjoyed writing this piece on Medium. I’m fairly new to tutorial writing, so please leave any comments or feedback below.

I think this has been a great start to writing and experimenting with some great stuff! Thanks for reading.


Better Programming

Advice for programmers.

Eric Walker

Written by

Studying Mechanical Engineering at The University of Akron. Cancer survivor since 2015.

Better Programming

Advice for programmers.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade