Blockchain Transactions: UTxO vs. Account-Based Models
Gustavo Martins | Oct 31, 2024
In 2023, the Apple Watch had an impressive 31% market share. This handy wearable device lets you measure your fitness, track meaningful health insights, connect with companion apps, make calls, and more right from your wrist.
With all that power, creating companion Apple Watch apps for your iOS apps can help enhance the overall user experience and make great use of this feature-packed device.
Let’s look at how the Apple Watch can help you bring new functionality to your apps and how to build an Apple Watch app that communicates with an existing Flutter app.
Creating synchronous and asynchronous communication between wearable devices and apps is a great way to add a new layer of functionality — and we’re no stranger to the task thanks to our work with Thaw.
Here are just a few of the ways this approach helps improve the user experience:
These are just a few great advantages this approach enables, in addition to all the exciting benefits of Flutter app development.
With all those advantages in mind, let’s look at how to get the two types of apps to talk to one another.
Although Flutter provides a way to directly build iOS apps, adding an Apple Watch app to a project can be tricky. Though the Apple Watch exists within the same Apple ecosystem, it runs WatchOS, which is a separate operating system from iOS.
So, if we want to build an Apple Watch app that communicates with a Flutter app we need to follow a few steps and meet some specific requirements:
Let’s now explore how we’ll implement these three requirements.
First, open your iOS folder from a Flutter project with Xcode, create a new target (File -> New -> Target), and select a watchOS “App”.
Then, fill in the “Product Name” field and select the “Watch App for Existing iOS App” option.
After you click on “Finish”, you’ll see a new folder like the example below:
Now that we have added the watchOS app to our project, we can develop the interfaces and some logic using SwiftUI. For this article, we’ll create an app that allows the user to increase or decrease a counter.
This is the result:
To create a communication channel between the watchOS and the iOS, we need to use the WCSession from the WatchConnectivity library. According to Apple’s WCSession documentation, “Your iOS app and watchOS app must both create and configure an instance of this class at some point during their execution. When both session objects are active, the two processes can communicate immediately by sending messages back and forth.”
Let’s see how that works in our example.
First, at “Runner/AppDelegate.swift” add the following code to start the session and create an extension that implements the WCSessionDelegate protocol. This will listen when the watchOS sends a message to the iOS app.
You also have to start the session from the watchOS extension. For this example, we’ll start it from our view model as the following:
Now we can send and receive data from our iOS app to our watchOS app extension. But we still need to communicate with our Flutter code. Here’s how to make that happen.
Usually, when we want to develop an integration between Flutter and the native code we use MethodChannels. But, this method can take a lot of extra effort to set up all that communication between platforms. Instead, we’ve found that Pigeon is a great option.
Pigeon is a code generator tool that makes it easy to facilitate communication between Dart (the programming language used by Flutter) and other platforms like Kotlin, Swift, and Objective-C.
It’s especially useful for Flutter developers who need to interact with native code or libraries that are not directly accessible from Dart. Pigeon makes communication between Flutter and the host platform type-safe, easier, and faster and removes the need to manage strings across multiple platforms and languages.
According to Pigeon’s documentation, it also “improves efficiency over common method channel patterns” and “removes the need to write custom platform channel code, since Pigeon generates it for you.”
It’s a great tool, and perfect for our example.
After adding Pigeon as a development dependency to your Flutter project, create a dart file in the root folder (out of the lib folder). Then, let’s define the interfaces to generate the code through Pigeon.
Run the “flutter pub run pigeon –input path/to/watch_interface.dart” to generate the files.
After running the above command, two files will be generated:
For Swift we’ll have:
For Flutter we’ll have:
That is how the implementation of those APIs will look like:
Now we can send messages from the watchOS session, receive them in the iOS app, and send them to our Flutter code.
After those simple steps, you can see our finished product: a Flutter + Apple Watch application, that dependably communicates and executes our Dart code to provide data to watchOS — all made possible by using Pigeon.
As you interact with either app, the other updates give you seamless communication and integration.
Want to play around with this example yourself? Check out the code here.
At Cheesecake Labs, we’re always keeping a close eye on Apple’s hardware releases and looking for ways to create unique and useful app experiences across the Apple ecosystem.
To learn more about our approach to developing Apple products (like the company’s other wearable, Vision Pro) head to the Cheesecake Labs blog.