Introduction

The SmartWatch market has grown a lot in the past few years. If you are currently developing a smartphone application you may be tempted to add an extension to this app running on a smartwatch.

In this tutorial, you will not learn how to build an apple watch app using react-native. Nevertheless, you will learn how to add a native Apple Watch extension to your existing react-native application.

You will need :

a mac

Xcode

basic knowledge on react-native

You will not need :

knowledge about how to build a native iOS/WatchOS application

Setup

Start a new react-native project using the react-native CLI.

react-native init RNWithAppleWatch



Then check if the initialization went well by running the app on an iOS device.

cd RNWithAppleWatch && react-native run-ios



You should see this screen :

Then, open the project with your favorite text editor. We are going to modify our app.js file to look like this :

import React, {useState} from 'react' ;

import {SafeAreaView, StyleSheet, TextInput, Button, Alert} from 'react-native' ;



const App = () => {

const [message, setMessage] = useState( '' );

const sendMessageToAppleWatch = () => {

Alert.alert( `the message " ${message} " has been sent` );

};

return (

< SafeAreaView style = {styles.container} >

< TextInput

value = {message}

onChangeText = {setMessage}

placeholder = "message"

/>

< Button onPress = {sendMessageToAppleWatch} title = "SEND" />

</ SafeAreaView >

) ;

};



const styles = StyleSheet.create({

container: {

flex: 1 ,

alignItems: 'center' ,

justifyContent: 'center' ,

},

});



export default App;



Now our app should look like this :

Now let the fun part begin.

Create a Watch app

Open the ios subdirectory of your react-native project using Xcode .

On the left side of the screen :

Select the project navigator. Click on your project file.

You will see the list of all the targets of your iOS application. A target defines a single product that can be built. By default, we have targets for iOS and tvOS. We are going to add a new target for WatchOS. Click on the + button at the bottom of the targets list.

We have multiple options here. We will focus on the Application list. Game App is not what we want in this tutorial. Watch App will create a standalone Watch application that doesn’t need a related iOS app to run. Watch App for iOS App will create a watch application related to an iOS application. We will select this option in our case. On the next page, you have to :

Set the name of your watch app Set the name of your organization Unselect Include Notification Scene , it is needed only if we want to customize them.

When you click on finish, a prompt will appear and ask you if you want to activate a scheme for your watch target, click on activate .

When you go back to your project file, you should now see two new folders WatchApp and WatchApp Extension .



Both folders are essentials to build a watch App:

WatchApp is responsible for displaying the UI. It will contain your storyboards (your Views) and your assets.

is responsible for displaying the UI. It will contain your storyboards (your Views) and your assets. WatchApp Extensions is responsible for the logic of your application. It will contain your application code.

Only the WatchApp target will be installed on the watch. The WatchApp Extension will run on the device and the data processed will be sent back to the Watch App.

At this step, you can run the generated Watch App on a Watch App simulator. To do so :

Select the WatchApp scheme. Click on the build and run button.

You should see a watch simulator appearing on which an empty application is running :





WatchOS apps are based on the Model-View-Controller (MVC) pattern. To add some graphical elements we will modify the interface.storyboard file (the View) inside the WatchApp folder. To add a new object, click on the library button at the top right corner of the Xcode window.

Tap label in the search bar to find the label object and drag and drop it in the middle of the watch two times. You should get :

By default, the labels will be placed in the vertical direction. If you click on a label, you can modify its style and its content in the attribute inspector in the left pan of Xcode.

Now we have to add some logic to handle the receipt of a message from the iOS application.

To do so, open the file interfaceController.swift in the WatchApp Extension folder.

Change the content of this file with the following code :

import Foundation

import WatchKit

import WatchConnectivity



class InterfaceController : WKInterfaceController , WCSessionDelegate {

@IBOutlet weak var textToDisplay: WKInterfaceLabel !

var session: WCSession ?





override func awake (withContext context: Any?) {

super .awake(withContext: context)

if WCSession .isSupported() {

self .session = WCSession . default

self .session?.delegate = self

self .session?.activate()

}

}





func session ( _ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {}





func session ( _ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void ) {

print ( "watch received message" , message);

let text = message[ "message" ] as ? String

self .textToDisplay.setText(text)

}

}



Our controller implements two interfaces :

WKInterfaceController, used to control our storyboard and react to events

WCSessionDelegate, defines methods to handle messages from the WCSession object.

The session variable initiates the communication between the Watch App and the iOS App.

The textToDisplay variable will be linked to our second label to display the message received from the iOS app. However, it is not connected yet. You can know this by looking at the circle on the left which is empty.

To correct this, open the interface.storyboard file inside the WatchApp folder. Above the representation of the watch, the little circle is a direct link to your controller. If you ctrl + click on it, you will be able to drag an arrow. Point this arrow to the second label and chose the outlet textToDisplay .

Now your storyboard and your controller can interact.

That’s all for the native part! In the next part, we will move on to the react-native part of the tutorial.

Connect your React Native App with your WatchOS App

As our application is developed in react-native, we need to use a bridge to have access to the WatchConnectivity API. Fortunately, react-native-watch-connectivity already implements everything we need. To install this library, run :

yarn add react-native-watch-connectivity

react-native link



In your App.js file replace the code of sendMessageToAppleWatch with the following one :

const sendMessageToAppleWatch = () => {

Watch.sendMessage({message}, error => {

if (error) {

Alert.alert(`the message "${message}" can't be sent`);

}

});

};



Restart the application. You can now send a message from the iPhone simulator to the apple watch simulator!

Conclusion

Congratulations! You have run your first Apple Watch Application. If you want to go deeper on this subject, react-native-watch-connectivity gives you everything you need to handle the reachability of the watch, the paring status, file transfer and more. You will quickly be able to add more value to your react-native application!