Update UIapplicationshortcutitem from Extension

3D touch quick actions preview view controller only one time

I'm guessing you're trying to present a view controller from a view controller that's not visible. You can use extensions like:

    extension UIViewController {
func topMostViewController() -> UIViewController {
if self.presentedViewController == nil {
return self
}
if let navigation = self.presentedViewController as? UINavigationController {
return navigation.visibleViewController.topMostViewController()
}
if let tab = self.presentedViewController as? UITabBarController {
if let selectedTab = tab.selectedViewController {
return selectedTab.topMostViewController()
}
return tab.topMostViewController()
}
return self.presentedViewController!.topMostViewController()
}
}

extension UIApplication {
func topMostViewController() -> UIViewController? {
return self.keyWindow?.rootViewController?.topMostViewController()
}
}

You can place both of these in your app delegate.swift, above your app delegate class, to get the currently visible view controller.Sample Image Then present the search view controller on that. For example:

func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {
if shortcutItem.type == "com.traning.Search" {

let sb = UIStoryboard(name: "Main", bundle: nil)

let searchVC = sb.instantiateViewControllerWithIdentifier("searchVC") as! UINavigationController

let topViewController = UIApplication.sharedApplication.topMostViewController()
topViewController.presentViewController(searchVC, animated: false, completion: { () -> Void in
completionHandler(true)
})

}
}

3D Touch Quick Actions not working properly with SpriteKit

Your code is not working because in your app delegate you create a new instance of GameViewController instead of referencing the current one

let gameViewController = GameViewController() // creates new instance

I am doing exactly what you are trying to do with 3d touch quick actions in 2 of my games. I directly load the scene from the appDelegate, dont try to change the gameViewController scene for this.

I use a reusable helper for this. Assuming you set up everything correctly in your info.plist. (I use small letters in the enum so end your items with .first, .second etc in the info.plist), remove all your app delegate code you had previously for the 3d touch quick actions.
Than create a new .swift file in your project and add this code

This is swift 3 code.

import UIKit

/// Shortcut item delegate
protocol ShortcutItemDelegate: class {
func shortcutItemDidPress(_ identifier: ShortcutItemIdentifier)
}

/// Shortcut item identifier
enum ShortcutItemIdentifier: String {
case first // I use swift 3 small letters so you have to change your spelling in the info.plist
case second
case third
case fourth

private init?(fullType: String) {
guard let last = fullType.componentsSeparatedByString(".").last else { return nil }
self.init(rawValue: last)
}

public var type: String {
return (Bundle.main.bundleIdentifier ?? "NoBundleIDFound") + ".\(rawValue)"
}
}

/// Shortcut item protocol
protocol ShortcutItem { }
extension ShortcutItem {

// MARK: - Properties

/// Delegate
private weak var delegate: ShortcutItemDelegate? {
return self as? ShortcutItemDelegate
}

// MARK: - Methods

func didPressShortcutItem(withOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
guard let shortcutItem = launchOptions?[.shortcutItem] as? UIApplicationShortcutItem else { return false }
didPressShortcutItem(shortcutItem)
return true
}

/// Handle item press
@discardableResult
func didPressShortcutItem(_ shortcutItem: UIApplicationShortcutItem) -> Bool {
guard let _ = ShortcutItemIdentifier(fullType: shortcutItem.type) else { return false }

switch shortcutItem.type {

case ShortcutItemIdentifier.first.type:
delegate?.shortcutItemDidPress(.first)

case ShortcutItemIdentifier.second.type:
delegate?.shortcutItemDidPress(.second)

case ShortcutItemIdentifier.third.type:
delegate?.shortcutItemDidPress(.third)

case ShortcutItemIdentifier.fourth.type:
delegate?.shortcutItemDidPress(.fourth)

default:
return false
}

return true
}
}

Than in your app delegate create an extension with this method (you missed this in your code)

extension AppDelegate: ShortcutItem {

/// Perform action for shortcut item. This gets called when app is active
func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {
completionHandler(didPressShortcutItem(shortcutItem))
}

Than you need to adjust the didFinishLaunchingWithOptions method in your AppDelegate to look like this

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.

...

return !didPressShortcutItem(withOptions: launchOptions)
}

And than finally create another extension confirming to the ShortcutItem delegate

extension AppDelegate: ShortcutItemDelegate {

func shortcutItemDidPress(_ identifier: ShortcutItemIdentifier) {

switch identifier {
case .first:
let scene = GameScene(size: CGSize(width: 1024, height: 768))
loadScene(scene, view: window?.rootViewController?.view)
case .second:
//
case .third:
//
case .fourth:
//
}
}

func loadScene(scene: SKScene?, view: UIView?, scaleMode: SKSceneScaleMode = .aspectFill) {
guard let scene = scene else { return }
guard let skView = view as? SKView else { return }

skView.ignoresSiblingOrder = true
#if os(iOS)
skView.isMultipleTouchEnabled = true
#endif
scene.scaleMode = scaleMode
skView.presentScene(scene)
}
}

The load scene method I normally have in another helper which is why I pass the view into the func.

Hope this helps.

3D Touch Shortcut Widget

There is a new Info.plist key UIApplicationShortcutWidget which you need to set to the bundle identifier of your widget.

See the documentation at: https://developer.apple.com/library/prerelease/content/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/uid/TP40009252-SW32



Related Topics



Leave a reply



Submit