使用 UIApplicationShortcutItem 启动

Launching with UIApplicationShortcutItem

我正在 swift 中为我的 iOS 9 应用程序实施一些 3D 触摸快速操作,但我遇到了一个奇怪的问题。当我的应用程序在后台并且我以快速操作启动时,一切都按计划进行。当我的应用程序完全死机时(即我从多任务菜单中将其杀死),并且我以快速操作启动时,应用程序崩溃了。我在调试这个应用程序时遇到了麻烦,因为一旦我终止了应用程序,Xcode 中的调试会话就会分离。有没有办法让我像平常一样连接到应用程序进行调试,或者我的代码中有什么东西会导致它?提前致谢。

代码:

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

    //Check for ShortCutItem
    if let shortcutItem = launchOptions?[UIApplicationLaunchOptionsShortcutItemKey] as? UIApplicationShortcutItem
    {
        launchedFromShortCut = true
        self.handleShortCutItem(shortcutItem)
    }

    return !launchedFromShortCut
}

func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void)
{
    self.handleShortCutItem(shortcutItem)
}

func handleShortCutItem(shortcutItem: UIApplicationShortcutItem)
{
    //Get type string from shortcutItem
    if let shortcutType = ShortcutType.init(rawValue: shortcutItem.type)
    {
        //Get root navigation viewcontroller and its first controller
        let rootNavigationViewController = window!.rootViewController as? UINavigationController


        if let rootViewController = rootNavigationViewController?.viewControllers.first as! LaunchViewController?
        {
            //Pop to root view controller so that approperiete segue can be performed
            rootNavigationViewController?.popToRootViewControllerAnimated(false)

            switch shortcutType
            {
                case .Compose:
                    rootViewController.shouldCompose()
                    break
            }
        }
    }
}

谢谢!

  1. 在 Xcode 中,打开产品 -> 方案 -> 编辑方案
  2. 在您的 运行 方案中,将启动设置更改为 'Wait for executable to be launched'

现在,如果您打开调试并 运行 您的应用程序,Xcode 将等待您从主屏幕启动您的应用程序,以便您能够使用 3D Touch 测试启动它快捷方式项目。

我终于搞定了。这是我的 AppDelegate.swift 文件的结尾;

class AppDelegate: UIResponder, UIApplicationDelegate {

// Properties
var window: UIWindow?
var launchedShortcutItem: UIApplicationShortcutItem?

func applicationDidBecomeActive(application: UIApplication) {

    guard let shortcut = launchedShortcutItem else { return }

    handleShortcut(shortcut)

    launchedShortcutItem = nil

}

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

    // Override point for customization after application launch.
    var shouldPerformAdditionalDelegateHandling = true

    // If a shortcut was launched, display its information and take the appropriate action
    if let shortcutItem = launchOptions?[UIApplicationLaunchOptionsShortcutItemKey] as? UIApplicationShortcutItem {

        launchedShortcutItem = shortcutItem

        // This will block "performActionForShortcutItem:completionHandler" from being called.
        shouldPerformAdditionalDelegateHandling = false

    }

    return shouldPerformAdditionalDelegateHandling
}


func handleShortcut( shortcutItem:UIApplicationShortcutItem ) -> Bool {

    // Construct an alert using the details of the shortcut used to open the application.
    let alertController = UIAlertController(title: "Shortcut Handled", message: "\"\(shortcutItem.localizedTitle)\"", preferredStyle: .Alert)
    let okAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
    alertController.addAction(okAction)

    // Display an alert indicating the shortcut selected from the home screen.
    window!.rootViewController?.presentViewController(alertController, animated: true, completion: nil)

    return handled

}

func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {

    completionHandler(handleShortcut(shortcutItem))

}

大部分内容取自 Apple 的 sample code for UIApplicationShortcuts,当我让我的应用程序启动警报以证明它正在识别选择了正确的快捷方式时,这可以适应您的代码弹出视图控制器。

我认为 func applicationDidBecomeActive 是我遗漏的关键部分,并从 didFinishLaunchingWithOptions 中删除了 self.handleShortCut(shortcutItem) (否则它调用了 handleShortCut 两次,看起来).

以上方法都试过了,都没有解决问题 比我在 handleShortcut 方法延迟后尝试处理快捷方式:

self.performSelector("action1", withObject: self, afterDelay: 0.5)

并为每个动作添加了一个方法,效果非常好

用这个替换你的 didfinishlaunching 方法。

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

  if let shortcutItem =
       launchOptions?[UIApplicationLaunchOptionsShortcutItemKey]
       as? UIApplicationShortcutItem {

    handleShortcut(shortcutItem)
    return false
  }
  return true
}

对于Swift 4.2

   func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    var isLaunchedFromQuickAction = false
    if let shortcutItem = launchOptions?[UIApplication.LaunchOptionsKey.shortcutItem] as? UIApplicationShortcutItem {
        isLaunchedFromQuickAction = true
        handleQuickAction(shortcutItem: shortcutItem)
    }

    return isLaunchedFromQuickAction
}

XCode11.6,Swift5

我们可以在运行时附加一个进程。 XCode 将等到进程启动,并在手动启动应用程序时附加到它。

XCode -> Debug -> Attach to process by PID or Name -> ("在弹出窗口中输入应用的名称")

路线:

  1. 确保应用程序是全新安装在设备或模拟器上的。
  2. 终止应用程序
  3. 在XCode中附上上述进程的名称。
  4. 通过所需的快捷方式打开应用程序

P.S:如果您使用的是 SceneDelegate,可以在

中找到快捷方式项
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
       switch connectionOptions.shortcutItem?.localizedTitle {
       case "Search":
       break
       case "DoSomething":
       break
       default:
       break
       } 
    }

调试愉快:)