# watchOS app integration

watchOS apps can be developed in both Swift and Objective-C.

{% hint style="warning" %}
**Independent** watchOS apps are **not** supported, watchOS apps **must** be bundled inside a **companion** iOS app. (The companion iOS app's Appfigurate Library is used to proxy any configuration payloads applied to the watchOS app).
{% endhint %}

## Prerequisites

You must perform the following before starting watchOS native integration:

* [iOS native app integration](https://docs.electricbolt.co.nz/getting-started/ios-native-app-integration) of Appfigurate Library.

In addition to the [iOS native app integration prerequisites](https://docs.electricbolt.co.nz/ios-native-app-integration#prerequisites), you must also have:

* watchOS SDKs and associated watchOS Simulators.
* Use paired iOS and watchOS Simulators.
* Appfigurate Simulator app installed into one or more paired iOS Simulators (use the [AppfigurateSE macOS app](https://docs.electricbolt.co.nz/appfigurate-se-user-guide/setup-ios-simulator-app) for easy 1 click installation).
* Your watchOS app must target watchOS 5.0+ in order to link Appfigurate Library.

## Add AppfigurateLibrary.xcframework to the watchOS app target

In Xcode:

* Tap on your watchOS app target.
* Tap the General tab. Tap the `+` button under the `Frameworks, Libraries, and Embedded Content` section.
* Select `AppfigurateLibrary` package.

## Add new app into Appfigurate Simulator

Run Appfigurate in the paired iOS Simulator.

Tap `≡` `YOUR-IOS-APP` app. The [Edit app](https://docs.electricbolt.co.nz/appfigurate-user-guide/edit-app) screen will be displayed.

Tap `Duplicate row` row. The [Duplicate app](https://docs.electricbolt.co.nz/appfigurate-user-guide/edit-app#duplicate-app) screen will be displayed.

Select app type `watchOS`.

Tap `Duplicate`.

## Share the iOS app APLConfiguration subclass with the watchOS app

Share the iOS app's [<mark style="color:blue;">`APLConfiguration`</mark>](https://www.electricbolt.co.nz/api/Classes/APLConfiguration.html) subclass with the watchOS app extension.&#x20;

Open your [<mark style="color:blue;">`APLConfiguration`</mark>](https://www.electricbolt.co.nz/api/Classes/APLConfiguration.html) subclass (e.g. `Configuration.swift/m` file) into the Xcode editor. In the `Target Membership` inspection pane tick on your watchOS app target.

## WKApplicationDelegate/WKExtensionDelegate

{% tabs %}
{% tab title="Swift (SwiftUI)" %}
For watchOS apps using SwiftUI, you must call [<mark style="color:blue;">`APLApplicationDidFinishLaunching()`</mark>](https://www.electricbolt.co.nz/api/Functions.html#/c:@F@APLApplicationDidFinishLaunching) in the [`WKApplicationDelegate`](https://developer.apple.com/documentation/watchkit/wkapplicationdelegate)'s [`applicationDidFinishLaunching`](https://developer.apple.com/documentation/watchkit/wkapplicationdelegate/applicationdidfinishlaunching\(\)) method.

> Swift `WKApplicationDelegate` example

```swift
import AppfigurateLibrary

...

class MyApplicationDelegate: NSObject, WKApplicationDelegate, ObservableObject {
    func applicationDidFinishLaunching() {
        APLApplicationDidFinishLaunching()
    }
}
```

Ensure you use the [`WKApplicationDelegateAdaptor`](https://developer.apple.com/documentation/swiftui/wkapplicationdelegateadaptor) property wrapper inside your [`App`](https://developer.apple.com/documentation/swiftui/app) declaration to tell SwiftUI about the delegate type:

> Swift `WKApplicationDelegateAdaptor` example

```swift
@main
struct MyApp: App {
    @WKApplicationDelegateAdaptor private var applicationDelegate: MyApplicationDelegate

    var body: some Scene { ... }
}
```

{% endtab %}

{% tab title="Swift (Storyboard)" %}
For watchOS apps using Storyboards, you must call [<mark style="color:blue;">`APLApplicationDidFinishLaunching()`</mark>](https://www.electricbolt.co.nz/api/Functions.html#/c:@F@APLApplicationDidFinishLaunching) in the [`WKExtensionDelegate`](https://developer.apple.com/documentation/watchkit/wkextensiondelegate)'s [`applicationDidFinishLaunching`](https://developer.apple.com/documentation/watchkit/wkextensiondelegate/applicationdidfinishlaunching\(\)) method.

> Swift `WKExtensionDelegate` example

```swift
import AppfigurateLibrary

...

func applicationDidFinishLaunching {
    APLApplicationDidFinishLaunching()
}
```

{% endtab %}

{% tab title="Objective-C" %}
You must call [<mark style="color:blue;">`APLApplicationDidFinishLaunching()`</mark>](https://www.electricbolt.co.nz/api/Functions.html#/c:@F@APLApplicationDidFinishLaunching) in the [`WKExtensionDelegate`](https://developer.apple.com/documentation/watchkit/wkextensiondelegate)'s [`applicationDidFinishLaunching`](https://developer.apple.com/documentation/watchkit/wkextensiondelegate/applicationdidfinishlaunching\(\)) method.

> Objective-C `WKExtensionDelegate` example

```objectivec
@import AppfigurateLibrary;

...

- (void) applicationDidFinishLaunching {
    APLApplicationDidFinishLaunching();
}
```

{% endtab %}
{% endtabs %}

## WCSessionDelegate

If your watch app has an existing `WCSessionDelegate`, then you must add a call to the [<mark style="color:blue;">`APLSessionDidReceiveMessage()`</mark>](https://www.electricbolt.co.nz/api/Functions.html#/c:@F@APLSessionDidReceiveMessage) method. If your watch app does not have a `WCSessionDelegate` then a default implementation is automatically provided.

{% tabs %}
{% tab title="Swift" %}

> Swift `WCSessionDelegate` example

```swift
import AppfigurateLibrary

...

func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) {
    let reply = APLSessionDidReceiveMessage(message)
    if reply != nil {
        replyHandler(reply)
    } else {
        ...
```

{% endtab %}

{% tab title="Objective-C" %}

> Objective-C `WCSessionDelegate` example

```objectivec
@import AppfigurateLibrary;

...

- (void) session: (WCSession*) session didReceiveMessage: (NSDictionary<NSString*,id>*) message replyHandler: (void (^)(NSDictionary<NSString*,id>*)) replyHandler {
    NSDictionary* reply = APLSessionDidReceiveMessage(message);
    if (reply != nil) {
        replyHandler(reply);
    } else {
        ...

```

{% endtab %}
{% endtabs %}

## Test your watchOS app

To test that you've successfully updated your watchOS app to use Appfigurate:

* Compile and run your watchOS app to the paired Simulator instance.
* Launch the Appfigurate Simulator app.
* Tap your watchOS applications row.  The companion iOS app will be run and made visible. The companion iOS app will read the watchOS apps configuration, then swap back to Appfigurate.
* Appfigurate's [Configure app](https://docs.electricbolt.co.nz/appfigurate-user-guide/configure-app) screen will now be displayed. You can now change the `debugLogging` and `serverURL` properties. Tap `Apply⌄` to apply the configuration to your watchOS app.

Now jump to [Supported property types](https://docs.electricbolt.co.nz/configuration-subclasses/supported-property-types).
