2

I am trying to integrate Siri WorkOut intent to my app.I am struck with strange error.

class StartWorkOutRequestHandling : NSObject, INStartWorkoutIntentHandling {
    func handle(startWorkout intent: INStartWorkoutIntent, completion: @escaping (INStartWorkoutIntentResponse) -> Void) {
        if let _ = intent.workoutName {
            if #available(iOSApplicationExtension 11.0, *) {
                let userActivity = NSUserActivity(activityType: "test")
                let response = INStartWorkoutIntentResponse(code: .handleInApp, userActivity: userActivity)
                completion(response);
            }
            else {
                // Fallback on earlier versions
                let userActivity = NSUserActivity(activityType: "test")
                let response = INStartWorkoutIntentResponse(code: .continueInApp, userActivity: userActivity)
                completion(response)
            }

        }
        else {
            let response = INStartWorkoutIntentResponse(code: .failureNoMatchingWorkout, userActivity: .none)
            completion(response);
        }
    }
}

As you can see in handle(startWorkout am checking whether the iOS version is 11 or greater if yes I use handleInApp response code if not I use continueInApp. This is because

Definition of public enum INStartWorkoutIntentResponseCode : Int { says

@available(iOS, introduced: 10.0, deprecated: 11.0, message: "INStartWorkoutIntentResponseCodeContinueInApp is deprecated on iOS. Please use INStartWorkoutIntentResponseCodeHandleInApp instead") case continueInApp

I understand .handleInApp opens the app in background where as continueInApp opens the app.

But when I use handleInApp and say "Start workout with My AppName" to Siri, Siri Says

"Sorry,You'll need to continue in the app"

and provides a Open MyApp button. On the other hand if I use simply

    func handle(startWorkout intent: INStartWorkoutIntent, completion: @escaping (INStartWorkoutIntentResponse) -> Void) {
    if let _ = intent.workoutName {
        let userActivity = NSUserActivity(activityType: "test")
        let response = INStartWorkoutIntentResponse(code: .continueInApp, userActivity: userActivity)
        completion(response);
    }
    else {
        let response = INStartWorkoutIntentResponse(code: .failureNoMatchingWorkout, userActivity: .none)
        completion(response);
    }
}

Ignoring the warnings Siri opens the App as expected. Whats worth noting though is in both the case

- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
 restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler {
    //this is a legacy app hence part of code is still in Objective-C
} 

app delegates method gets called properly.

Though I found a similar question here

Siri always responds 'Continue in the app' when starting workout with SiriKit

but it uses deprecated continueInApp. So cant use it in iOS 11.

What am I making a mistake here? Why using handleInApp won't open the app and why Siri complains that I need to continue in App! How to open the app using handleInApp.

If I am not supposed to open App from Siri while using Workout intent, I believe there is no way to trigger IntentUI also for Workout intent. Refer: SiriKit, How to display response for start Workout Intent?

Please help.

Sandeep Bhandari
  • 19,999
  • 5
  • 45
  • 78

1 Answers1

1

Please check this one.....

func handle(intent: INStartWorkoutIntent, completion: @escaping (INStartWorkoutIntentResponse) -> Void) {

        if let _ = intent.workoutName {
            let userActivity = NSUserActivity(activityType: "test")
            let response = INStartWorkoutIntentResponse(code: INStartWorkoutIntentResponseCode(rawValue: 2)!, userActivity: userActivity)
            completion(response);
        }
        else {

            let response = INStartWorkoutIntentResponse(code: INStartWorkoutIntentResponseCode(rawValue: 6)!, userActivity: .none)
            completion(response);
        }
    }
Keyur Hirani
  • 1,607
  • 14
  • 22