How To Detect If Your Apple Watch App Was Launched From A Complication

In some instances, you may want to determine if the user launched your Apple Watch app by tapping on a complication on the watch face.

watchOS makes use of handoff when this occurs. As such, you can use the regular handleUserActivity(:) method to detect this.

You can detect this in your extension delegate using the CLKLaunchedTimelineEntryDateKey key (as below, or you can also handle handoff in your interface controllers).

import WatchKit

class ExtensionDelegate: NSObject, WKExtensionDelegate {
    func handleUserActivity(_ userInfo: [AnyHashable : Any]?) {
        
        if let date = userInfo?[CLKLaunchedTimelineEntryDateKey] as? Date {
            // Handoff from complication
        }
        else {
            // Handoff from elsewhere
        }
    }
}

The date variable in this example corresponds to the time that was displayed on the watch when the user tapped the complication. This means if your compilation support time travel, you can tell the time and date the user was viewing.

Unfortunately though, it's not possible to detect which complication the user came from. For example, if the user is displaying your app on the modular face in both the "large" and "small" positions, you won't be able to tell which one they tapped.

However, since CLKComplicationServer.activeComplications only returns the complications from the current watch face (and not other faces that also may have your complication added to it), you can at least narrow it down to at most two different complication sizes:

import ClockKit

// ...

func activeComplicationFamilies() -> Set<CLKComplicationFamily> {
    let server = CLKComplicationServer.sharedInstance()
        
    guard let complications = server.activeComplications else {
        return []
    }

    let allFamilies = complications.map { return $0.family }

    // Return only unique families, since some allFamilies may contain duplicates

    return Set(allFamilies)
}