Do something with Quick Action
Asked Answered
B

1

0

Sorry if this is a dumb question, Setting up a 3D Touch quick action. I put everything into the .plist file and I had to put this into my AppDelegate.swift file

AppDelegate.swift

func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
    // Called when a new scene session is being created.
    // Use this method to select a configuration to create the new scene with.

    // Grab a reference to the shortcutItem to use in the scene
    if let shortcutItem = options.shortcutItem {
        shortcutItemToProcess = shortcutItem
    }

    // Previously this method only contained the line below, where the scene is configured
    return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) }

and this into my SceneDelegate.swift

// Shortcut code
    func windowScene(_ windowScene: UIWindowScene, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
        // When the user opens the app through a quick action, this is now the method that will be called
        (UIApplication.shared.delegate as! AppDelegate).shortcutItemToProcess = shortcutItem

    }
    // Shortcut code
    func sceneDidBecomeActive(_ scene: UIScene) {
        // Is there a shortcut item that has not yet been processed?
        if let shortcutItem = (UIApplication.shared.delegate as! AppDelegate).shortcutItemToProcess {


            if shortcutItem.type == "com.application.Start" {
                print("Start Shortcut pressed")

                //let vc = ViewController ()
                //vc.startAct()

            }
            // Reset the shorcut item so it's never processed twice.
            (UIApplication.shared.delegate as! AppDelegate).shortcutItemToProcess = nil
        }
    }

I want to run the function startAct() { ... } that's in the Main app file called ViewController.swift

I tried

let vc = ViewController ()
vc.startAct()

and it sort of starts to run but crashed straight away on the first line with an error about unwrapping a nil value or something. Im guessing its not actually loading the Main view but trying to run it from the SceneDelegate.swift which cannot be correct.

Thank you in advance.

Biddie answered 21/10, 2019 at 2:15 Comment(3)
I don't understand what you think the stuff in configurationForConnecting is for. I would just delete that method entirely if I were you; it serves no purpose in most apps. Your job is to implement windowScene(_:performActionFor:completionHandler:) and that's all; it will be called when the user taps an action. You are not implementing it correctly; you should not be interspersing this stuff about sceneDidBecomeActive or storing the info in a global as you are doing. Just do whatever the action tells you to do, now. And call the completion handler!Causerie
Thanks for your reply, the Quick action was doing nothing at all until a member helped be set it up as above here (#58458589)Biddie
Yes, well, I don’t agree with all of that and it isn’t working for you is it?Causerie
C
5

This seems to be causing some confusion so I'll show what I do.

You have to implement your response to the shortcut item in two places: in the scene delegate's willConnectTo and in performActionFor. To help you test, I'll just delete all my error checking and parsing and just demonstrate that we are in fact responding to the shortcut item:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    if let shortcutItem = connectionOptions.shortcutItem {
        let alert = UIAlertController(title: "Hello", message: "", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default))
        self.window?.makeKeyAndVisible()
        self.window?.rootViewController?.present(alert, animated: true)
    }
}

func windowScene(_ windowScene: UIWindowScene, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
    let alert = UIAlertController(title: "Hello", message: "", preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "OK", style: .default))
    self.window?.rootViewController?.present(alert, animated: true)
    completionHandler(true)
}

That shows the alert whether the app is suspended or terminated beforehand.

Causerie answered 22/10, 2019 at 4:31 Comment(4)
Ill keep trying but Im a little confused because all the examples I can find online are showing how to make an alert window pop up. I want to go the the main storyboard screen that my app is on and run a function the user would normally click on a. button to make happen, that is called startAct(). Im not sure how to change the alert to call that function to start.Biddie
Yes, I appreciate that the alert example is very artificial! But look at what both my calls have in common: they make sure the interface really exists, and they work their way to the root view controller. If you can do that, you can manipulate the interface as desired.Causerie
Thanks for your help. I got the alert to pop up following your instructions, then I tried every which way combination of this print("Start Shortcut pressed 0") let vc = ViewController() self.window?.rootViewController?.present(vc, animated: true) self.window?.makeKeyAndVisible() vc.startAct() - but I still get this error on the first line when it tried to hide the start button, Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value: fileBiddie
I hope I don't have to go and put ? in front of all the buttons and variables etc. cause that would take ages. I could make the short cut item named Open Application, because that's all it does. lolBiddie

© 2022 - 2024 — McMap. All rights reserved.