WatchKit FAQ

Check out the answers to the most commonly asked questions about WatchKit – Apple’s framework for making Apple Watch apps! By Soheil Azarpour.

Leave a rating/review
Save for later
Share
You are currently viewing page 2 of 4 of this article. Click here to view the first page.

Contents

Hide contents

WatchKit FAQ

30 mins

Under The Hood

Select the appropriate scheme

Select the appropriate scheme

How can I test a glance or a notification using the simulator?

Each glance or notification requires its own dedicated build scheme to run in the simulator. Then you simply select the appropriate scheme, and build and run.

Can I position interface elements on top of each other?

No, interface elements can’t be positioned on top of each other natively. However, there are workarounds. For example, you can use a WKInterfaceGroup and set its background image to something that represents the control you want to overlay. Inside the group you can then add the necessary labels, buttons and so on.

Can I customize the CALayer property of interface elements?

No. There is no CALayer property available on the Apple Watch interface elements, as they don’t descend from either UIView or CALayer.

Can I subclass the classes available in WatchKit?

There is nothing to stop you from subclassing a class in WatchKit, but you might find you’re unable to use it. You can subclass some classes, such as WKInterfaceController and WKUserNotificationInterfaceController and use those in your storyboard.

However, the storyboard of a watch app doesn’t allow you to change the class of any interface elements. And you’ve can’t dynamically create interface elements and insert or remove them as subviews; you can only hide or show interface elements that are already present in the storyboard.

Can I mix page-based and navigation-based interface controllers?

Yes, but with some limitations.
If you have a hierarchical interface, you can present a page-based interface modally. If any of the pages is a hierarchical interface, the root of that interface is displayed and you won’t be able to push anything on its stack.
If you have a page-based interface, you can present a hierarchical interface modally, but only the root interface controller is displayed and you won’t be able to push anything on its stack.

Are there equivalents for UIActivityIndicator or UIAlertController on the Apple Watch?

No, but in lieu of a UIAlertController, you can display a custom WKInterfaceController modally.
You can work around an activity indicator by adding a sequence of images to create the necessary animation, or simply display a label with the appropriate text. For an example of this, check out Apple’s Lister example. In the Watch App’s glance, you’ll see there are 360 images representing a single circular animation!

Lister

Can I use Core Graphics to generate images dynamically and then use them in a watch app? Can they be cached on the watch?

Yes, but the composition of any images using Core Graphics must take place on the iPhone as part of the extension. Once you have rendered the Core Graphics drawing context into an instance of UIImage you can then cache it on the watch using addCachedImage(_:name:) from WKInterfaceDevice.

Can I use custom views in the Apple Watch? Can I customize the interface elements beyond their public API?

No. You can’t use custom views. WatchKit only supports certain native interface elements. None of the interface elements can be subclassed or customized beyond their public API. The available interface elements are WKInterfaceLabel, WKInterfaceButton, WKInterfaceImage, WKInterfaceGroup, WKInterfaceSeparator, WKInterfaceTable, WKInterfaceSwitch, WKInterfaceMap, WKInterfaceSlider and WKInterfaceTimer.

How does the Apple Watch communicate with your iPhone?

The Apple Watch leverages both Bluetooth LE and Wi-Fi technologies to communicate with its paired iPhone. The exact nature of the communication and its implementation is opaque to both users and developers.

Turn on Wi-Fi and Bluetooth after turning on Airplane mode

Turn on Wi-Fi  and Bluetooth after turning on Airplane mode

Can I use the Apple Watch while in Airplane Mode?

Yes. In fact, you can turn Bluetooth and Wi-Fi on after enabling Airplane mode to enable communications and continue using your watch.

What happens to my app when the Apple Watch can’t communicate with its paired iPhone?

Simply put, your app won’t run, and if it’s already running it’ll be suspended.

In the WatchKit extension, didDeactivate() will be called on the current interface controller and you’ll be given the chance to do any necessary cleanup. A red iPhone icon will display in the status bar on the watch to indicate loss of connectivity, and the interface will remain on screen, but won’t be interactive. Users can either restore connectivity or exit the app.

How can a watch app communicate with its companion iPhone app?

There are various techniques you may use, a popular being that the watch app writes or updates data in a shared container, and then it notifies the iPhone app. Afterwards, the iPhone app can pull in the changes from the shared container.

Another technique is to pass data to the iPhone app via a dictionary, but this can only be initiated by the watch app. There is a single API for this in the WatchKit extension; call the class method openParentApplication(userInfo:reply:) of WKInterfaceController, as shown in the following code snippet:

// Notify companion iPhone app of some changes in the shared container.
let kSharedContainerDidUpdate = "com.rayWenderlich.shared-container.didUpdate"
let requestInfo: [NSObject: AnyObject] = [kSharedContainerDidUpdate: true]
WKInterfaceController.openParentApplication(requestInfo) { (replyInfo: [NSObject : AnyObject]!, error: NSError!) -> Void in
  // Handle the reply from the companion iPhone app...
}

In the userInfo dictionary, you simply pass a flag or some data for the companion iPhone app to act upon. To receive this communication, the companion iPhone app must implement application(_:handleWatchKitExtensionRequest:reply:) in its app delegate:

func application(application: UIApplication!, handleWatchKitExtensionRequest userInfo: [NSObject : AnyObject]!, reply: (([NSObject : AnyObject]!) -> Void)!) {
let kSharedContainerDidUpdate = "com.rayWenderlich.shared-container.didUpdate"
  if let isUpdate = userInfo[kSharedContainerDidUpdate] as? Bool {
    // Process request, then call reply block
    reply(...)
  }
 }

If the companion iPhone app is suspended or terminated, the system will launch it in the background. Depending on the purpose of the communication, the companion iPhone app may return something in the reply block which the watch app can then process accordingly.

How can an iPhone app communicate with its watch app?

There is no way for an iPhone app to initiate communication with its extension. Aside from writing to a shared container, or responding to the watch app’s requests, the iPhone app may use the Darwin Notification Center to notify the WatchKit extension about a particular event — Darwin Notification Center is an API of the Core Foundation framework.

If you decide to use the Darwin Notification Center, there are some very important things to remember:

  • An application has only one Darwin Notification Center.
  • All Darwin notifications are system-wide.
  • The main thread’s run loop must be running in one of the common modes, such as kCFRunLoopDefaultMode, for notifications to be delivered.
  • The watch app must be running in the foreground to handle sending and receiving Darwin notifications.
  • You can’t pass objects via Darwin notifications because they only carry a name and a userInfo dictionary.
  • Darwin notifications are not persisted, rather, they are delivered immediately. Therefore, if an observer is suspended, terminated or placed in the background, the notification is lost.