2

I've passed to my complicationDescriptors a userInfo dictionary that includes the names of my complications so I can be notified of which complication the user tapped on and launch them to that View. I'm using the new @App and @WKExtensionDelegateAdaptor for other reasons, so I have access to handleUserActivity in my extensionDelegate and can unpack the source of the complication tap, but how do I launch them to a specific view in SwiftUI? handleUserActivity seems to be set up to work with WKInterfaceControllers?

class ExtensionDelegate: NSObject, WKExtensionDelegate {

    let defaults = UserDefaults.standard
    
    func applicationDidFinishLaunching() {
        //print("ApplicationDidFinishLanching called")
        
        scheduleNextReload()
        
    }
    
    
    func applicationWillResignActive() {
        //print("applicationWillResignActive called")
    }
    
    func handleUserActivity(_ userInfo: [AnyHashable : Any]?) {
        
        if let complication = userInfo?[TrackerConstants.complicationUserTappedKey] as? String {
            
            if complication == TrackerConstants.recoveryDescriptorKey {
                //What now?
            } else if complication == TrackerConstants.exertionDescriptorKey {
                //What now?
            }
        }
        
    }
GarySabo
  • 5,806
  • 5
  • 49
  • 124
  • I am trying to achieve the same thing. Have you figured it out? Trying to programatically navigate to a new view. – alamodey Oct 06 '21 at 02:35
  • @alamodey no I was never able to get this to work – GarySabo Oct 06 '21 at 15:04
  • Are you able to pass through to `handlUserActivity` which complication value is being presented? I have a complication that shows a new value each minute and I can't figure out how to pass which value is being presented. – Steve Walsh Mar 06 '22 at 08:48

1 Answers1

1

I managed to update my view according to the tapped complication userInfo by using notifications, inspired by this answer.

First declare a notification name:

extension Notification.Name {
    static let complicationTapped = Notification.Name("complicationTapped")
}

In your ExtensionDelegate:

func handleUserActivity(_ userInfo: [AnyHashable : Any]?) {
    if let complication = userInfo?[TrackerConstants.complicationUserTappedKey] as? String {
        NotificationCenter.default.post(
            name: Notification.Name.complicationTapped,
            object: complication
        )
    }   
}

Finally in your view:

struct ContentView: View {
    @State private var activeComplication: String? = nil

    var body: some View {
        NavigationView { // or TabView, etc
        // Your content with NavigationLinks
        }
        .onReceive(NotificationCenter.default.publisher(
            for: Notification.Name.complicationTapped
        )) { output in
            self.activeComplication = output.object as? String
        }
    }
}

For more information on how to activate a view from here, see Programmatic navigation in SwiftUI

Mart
  • 5,608
  • 3
  • 32
  • 45
  • Are your complications also using SwiftUI? I can't get handleUserActivity to get called for some reason. – saagarjha Nov 25 '22 at 05:45