3D Touch Quick actions not working at all
Asked Answered
H

1

6

Ive been through all the other questions and I can't figure out what's wrong. I downloaded the sample project from the Apple Developer site Add Home Screen Quick Actions and that works no problem, but when I start a new Xcode project and copy that exactly it doesn't work for me. I must be missing something. At this point I just want it to print in the console saying "shortcut pressed". When I add print("Shortcut pressed") to the Apple project I downloaded it works fine.

At this point I am just trying random things.

I updated my info.plist with an Array and a dictionary and strings and I just copy and past the values as to not make any typo mistakes.

UIApplicationShortcutItems, Item 0, UIApplicationShortcutItemType, UIApplicationShortcutItemIconType, UIApplicationShortcutItemTitle

The shortcut appears when pressing the app icon but it just opens the app.

This is my very basic AppDelegate.Swift file just trying to get it to do anything Could it be my project settings, my version of Xcode is up to date - Version 11.1 (11A1027)

Ive never used Quick actions before and it seamed simple but what seamed simple, just add some lines to the plist and add some code to the AppDelegate.Swift file but is taking ages to get working.

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

     var shortcutItemToProcess: UIApplicationShortcutItem?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        if let shortcutItem = launchOptions?[UIApplication.LaunchOptionsKey.shortcutItem] as? UIApplicationShortcutItem {
            shortcutItemToProcess = shortcutItem
            print("Shortcut pressed")
        }
        return true
    }

    func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {
        print("Shortcut pressed")
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        print("Shortcut pressed")
    }

    // MARK: UISceneSession Lifecycle

    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.
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
        // Called when the user discards a scene session.
        // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
        // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
    }


}

Thank you.

Hatchway answered 18/10, 2019 at 20:55 Comment(0)
T
23

Looks like your app is Scene based. For Scene based apps you can almost forget about the AppDelegate and focus on the SceneDelegate. There are two methods you now need to override in the SceneDelegate and one in the AppDelegate. I'll mimic Apple's guide for clarity:

If the user is opening the app and it's a fresh launch, you handle this in the AppDelegate:

     // 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)
     }

If your app is still running in the background when the user clicks on the shortcut item, you handle that in the SceneDelegate:

    // SceneDelegate.swift
    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
    }

Once the scene is ready, you can do what you need to with the shortcut :

    // SceneDelegate.swift
    func sceneDidBecomeActive(_ scene: UIScene) {
        // Is there a shortcut item that has not yet been processed?
        if let shortcutItem = (UIApplication.shared.delegate as! AppDelegate).shortcutItemToProcess {
            // In this sample an alert is being shown to indicate that the action has been triggered,
            // but in real code the functionality for the quick action would be triggered.
            var message = "\(shortcutItem.type) triggered"
            if let name = shortcutItem.userInfo?["Name"] {
                message += " for \(name)"
            }
            let alertController = UIAlertController(title: "Quick Action", message: message, preferredStyle: .alert)
            alertController.addAction(UIAlertAction(title: "Close", style: .default, handler: nil))
            window?.rootViewController?.present(alertController, animated: true, completion: nil)

            // Reset the shorcut item so it's never processed twice.
            (UIApplication.shared.delegate as! AppDelegate).shortcutItemToProcess = nil
        }
    }
Taproom answered 20/10, 2019 at 6:13 Comment(7)
Thanks Mate, I will take a look at your answer in detail. I had a similar problem with Notification Actions, everything I did in the AppDelegate file gave me no results, and I put everything into the ViewController.swift file and it started working. I was thinking this might be the case for this problem as well and I appreciate you're response and Ill let you know tomorrow if it helps.Hatchway
Thankyou for helping. I now have "Shortcut pressed" showing up in my Active console. Whoo Hoo! Thanks again, I can now start making it do stuff. Have a great day. - Kurt.Hatchway
Hi @BillyBrawner, you might have seen this coming from a mile away but I'm going to ask while I do some research, the app opens and I have a function in the ViewController.swift file that id like to start when they press the shortcut, its called startAct() Would you be kind enough to point me in the right direction as to starting that from the SceneDelegate.swift when they press the quick action, because obviously at the moment it says Use of unresolved identifier 'startAct'Hatchway
@KurtLane you just need a reference to the ViewController. Assuming you have that, you would call viewController.startAct(). If this is the same ViewController that you're setting as the rootViewController, then you can get it with window.rootViewControllerTaproom
Thanks for replying I tried putting this into the SceneDelegate under where it prints shortcut pressed vc = ViewController () vc.startAct() but it crashed when it tried to run the function with a red line on the first line for the function startAct() about trying to unwrap an optional thing. The first line is startButton.isHidden = true Im guessing it can't find the start button from the SceneDelegateHatchway
I made a new question, (#58479513) why do people down vote questions without any comment, does someone not like me?Hatchway
To access that shortcutItem in the SceneDelegate rather than the app delegate, you can also access this delegate func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) this will turn the above to if let shortcutItem = connectionOptions.shortcutItem { shortcutItemToProcess = shortcutItem }Dithionite

© 2022 - 2024 — McMap. All rights reserved.