Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add "quick actions" to my iOS 9 app

I would like to add the quick actions of iOS 9 to my app.

I put this code in my app delegate:

import UIKit
enum ShortcutType: String {
    case NewScan = "QuickAction.NewScan"
    case Settings = "QuickAction.Settings"
}
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    static let applicationShortcutUserInfoIconKey = "applicationShortcutUserInfoIconKey"

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

        UIViewController.prepareInterstitialAds()

        if(UIApplication.instancesRespondToSelector(Selector("registerUserNotificationSettings:"))) {
            UIApplication.sharedApplication().registerUserNotificationSettings(UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil))
        }

        // QUICK ACTIONS
            var launchedFromShortCut = false

            if #available(iOS 9.0, *) {
                if let shortcutItem = launchOptions?[UIApplicationLaunchOptionsShortcutItemKey] as? UIApplicationShortcutItem {
                    launchedFromShortCut = true
                    handleShortCutItem(shortcutItem)
                }
            } else {
                return true
            }
            return !launchedFromShortCut

    }

    /**************** QUICK ACTIONS ****************/
    @available(iOS 9.0, *)
    func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: Bool -> Void) {
            let handledShortCutItem = handleShortCutItem(shortcutItem)
            completionHandler(handledShortCutItem)
    }
    @available(iOS 9.0, *)
    func handleShortCutItem(shortcutItem: UIApplicationShortcutItem) -> Bool {
        var handled = false
        if let shortcutType = ShortcutType.init(rawValue: shortcutItem.type) {
            let rootNavigationViewController = window!.rootViewController as? UINavigationController
            let rootViewController = rootNavigationViewController?.viewControllers.first as UIViewController?
            rootNavigationViewController?.popToRootViewControllerAnimated(false)
            switch shortcutType {
                case .NewScan:

                    rootViewController?.performSegueWithIdentifier("goToCamera", sender: nil)
                    handled = true

                case.Settings:
                    rootViewController?.performSegueWithIdentifier("goToSettings", sender: nil)
                    handled = true
            }
        }
        return handled
    }
}

Now I can make a force touch on my app icon > quick actions will be shown > I select the Quick Action "New Scan" > the app will open and show me the last view, which I have leave.

But the segue will not be execute.

Here is a part of my storyboard:

enter image description here

Explanation:

A: Navigation Controller and initiale Controller

B: ViewController, after a check this will make a segue to navigation Controller C

C: Navigation Controller

D: Table View Controller

E: ViewController

If I select New Scan with quick actions - I would like to show ViewController E.

like image 845
Ghost108 Avatar asked Sep 28 '15 10:09

Ghost108


People also ask

How do I add actions to my iPhone apps?

In the Shortcuts app on your iOS or iPadOS device, tap on a shortcut. In the shortcut editor, tap to display a list of action categories. Tap an action category in the list, then tap for a specific action.

How do you set up quick actions on iPhone?

Perform quick actions from the Home Screen and App LibraryOn the Home Screen and in App Library, touch and hold apps to open quick actions menus. For example: Touch and hold Camera , then choose Take Selfie.

Where is the Quick Actions menu?

The Quick Actions menu provides you with quick access to commonly used functions of the app. To open the Quick Actions menu, tap the access_time icon on the right side of the Command bar. The menu is split into two parts, the top icon row and the main body of the menu.

What is quick action in iOS Shortcuts?

Quick actions are a great way to provide your users fast access to your app's common functionality within the home screen. iOS 13 introduced the concept of quick actions, where a user can touch and hold an app icon to display a set of shortcuts or actions to perform right from the home screen.


1 Answers

It appears that you're doing things correctly based on the example code in the documentation. However, you've got a lot of optional chaining in your handleShortCutItem: implementation. Have you used the debugger to verify none of those expression have nil values? Also, from what I can see (although the image is blurry), the root view controller of the first nav controller in that storyboard does not have a segue to E. So I'm not sure how you intend to get there.

I would suggest that you set a breakpoint in your handleShortCutItem: implementation to first validate that the values you're working with are not nil and the code is actually executing. Once you've done this, you can use your storyboard to instantiate the view controls you want and just create an array of them as you want your view controller hierarchy to be in your navigation controller and set the navigation controller's viewControllers property to this array. Again, it's hard to tell exactly what you want from your image, but perhaps something like this:

func handleShortCutItem(shortcutItem: UIApplicationShortcutItem) -> Bool {
    guard let shortcutType = ShortcutType.init(rawValue: shortcutItem.type) else {
        return false
    }

    guard let rootNavigationController = window?.rootViewController as? UINavigationController else {
        return false
    }

    guard let rootViewController = rootNavigationController?.viewControllers.first else {
        return false
    }

    guard let storyboard = rootNavigationController.storyboard else {
        return false
    }

    var viewControllers = [rootViewController]
    switch shortcutType {
    case .NewScan:
        // Instantiate the necessary view controllers for this case
        viewControllers += [storyboard.instantiateViewControllerWithIdentifier("<#Identifier for some view controller#>")]
        ...
        viewControllers += [storyboard.instantiateViewControllerWithIdentifier("<#Identifier for some other view controller#>")]

    case.Settings:
        // Instantiate the necessary view controllers for this case
        viewControllers += [storyboard.instantiateViewControllerWithIdentifier("<#Identifier for some view controller#>")]
        ...
        viewControllers += [storyboard.instantiateViewControllerWithIdentifier("<#Identifier for some other view controller#>")]
    }

    // Set the new view controllers array
    rootNavigationController.setViewControllers(viewControllers, animated: false)

    return true
}

Note: Since you tagged this question with Swift2, I've taken the liberty of adjusting the code to use guard statements.

like image 200
Charles A. Avatar answered Jan 02 '23 19:01

Charles A.