2

I'm using the App Intents API to provide an automation through the iOS Shortcuts app. When my intent runs, I'd like to be able to decide if I want to open the app (bring it to the foreground) or not. I know openAppWhenRun can be used to open the app, but its value cannot be modified.

I tried using openAppWhenRun, but it does not have a setter. Therefore, I cannot dynamically update this variable to determine if the app should be opened in the foreground or not.

3 Answers3

1

Inside your intent's perform-method, return .result(opensIntent:), opening another intent, that brings your app to the foreground. Should the conditions to do so not apply, you can throw a custom error (otherwise perform wouldn't return some IntentResult). Just make sure your Error-enum adheres to CustomLocalizedStringResourceConvertible, so the user gets a useful message.

szagun
  • 123
  • 8
1

you don't need a setter in this case you must override it:

static var openAppWhenRun: Bool = true

Hope it helps!

calm
  • 363
  • 2
  • 9
0

This is possible as of iOS 16.4 via the ForegroundContinuableIntent protocol. It will run in the background until you decide to bring the app to the foreground. Here's an example:

import AppIntents

@available(iOS 16.4, *)
struct TestIntent: ForegroundContinuableIntent {
    static var title: LocalizedStringResource = "Test Intent"

    @Parameter(title: "Open App")
    var shouldOpenApp: Bool

    @MainActor
    func perform() async throws -> some IntentResult & ProvidesDialog {
        if shouldOpenApp {
            // Stop performing the app intent and ask the user to continue to open the app in the foreground
            throw needsToContinueInForegroundError()

            // You can customize the dialog and/or provide a closure to do something in your app after it's opened
            throw needsToContinueInForegroundError("Please continue to open the app.") {
                UIApplication.shared.open(URL(string: "yourapp://deeplinktocontent")!)
            }

            // Or you could ask the user to continue performing the intent in the foreground - if they cancel the intent stops, if they continue the intent execution resumes with the app open
            // This API also accepts an optional dialog and continuation closure
            try await requestToContinueInForeground()
            return .result(dialog: "I opened the app.")
        } else {
            return .result(dialog: "I did not open the app.")
        }
    }
}
Jordan H
  • 52,571
  • 37
  • 201
  • 351