使用 UIApplicationShortcutItem 启动

问题描述 投票:0回答:7

我正在为我的 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
            }
        }
    }
}

谢谢!

ios swift ios9 3dtouch
7个回答
67
投票
  1. 在 Xcode 中,打开产品 -> 方案 -> 编辑方案
  2. 在您的运行方案中,将启动设置更改为“等待可执行文件启动”

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

See Screenshot in Xcode of the Setting


28
投票

我终于成功了。 这是我的 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的UIApplicationShortcuts的示例代码,当我让我的应用程序启动警报以证明它正在识别选择了正确的快捷方式时,这可以适应您的代码以弹出视图控制器.

我认为

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


3
投票

对于斯威夫特 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
}

1
投票

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

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

并为每个动作添加了一个方法,它就像一个魅力


1
投票

用这个方法替换你的 didfinishlaunching 方法。

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

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

    handleShortcut(shortcutItem)
    return false
  }
  return true
}

0
投票

XCode 11.6、Swift 5

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

XCode -> 调试 -> 通过 PID 或名称附加到进程 -> (“在弹出窗口中输入应用程序的名称”)

路线:

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

调试愉快:)

Debug ->进程名称

Name of a target


0
投票

对于 2024 年在这里寻找解决方案的 Ionic 开发人员,我就是这么做的:

1.使用 Perform(#selector(handleShortcut(_:)), with:shortcutItem, afterDelay: 0.5) 在处理快捷方式时添加延迟,让应用程序完成初始化。

  1. 在 application(:didFinishLaunchingWithOptions:) 中,存储快捷方式以便稍后在 applicationDidBecomeActive(:) 中处理。

准备一个示例如下: AppDelegate 类:UIResponder、UIApplicationDelegate {

var window: UIWindow?
var launchedShortcutItem: UIApplicationShortcutItem?

func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
    // Check for a shortcut item in launch options
    if let shortcutItem = launchOptions?[.shortcutItem] as? UIApplicationShortcutItem {
        launchedShortcutItem = shortcutItem
    }
    return true
}

func applicationDidBecomeActive(_ application: UIApplication) {
    // If there was a shortcut item on cold start, handle it with a delay
    if let shortcut = launchedShortcutItem {
        self.perform(#selector(handleShortcut(_:)), with: shortcut, afterDelay: 0.5)
        launchedShortcutItem = nil
    }
}

@objc func handleShortcut(_ shortcutItem: UIApplicationShortcutItem) {
    // Example: Handle different shortcut types
    switch shortcutItem.type {
    case "pay-bills":
        performActionForPayBills()
    case "airtime-Topup":
        performActionForAirtimeTopup()
    case "transfer-money":
        performActionForTransferMoney()
    case "snap-2-pay":
        performActionForSnap2Pay()
    default:
        break
    }
}

func application(
    _ application: UIApplication,
    performActionFor shortcutItem: UIApplicationShortcutItem,
    completionHandler: @escaping (Bool) -> Void
) {
    // Handle shortcuts when the app is already running
    self.perform(#selector(handleShortcut(_:)), with: shortcutItem, afterDelay: 0.5)
    completionHandler(true)
}

// MARK: - Action Methods for Shortcuts

private func performActionForPayBills() {
    print("Shortcut: Pay Bills")
    let bridge = (self.window?.rootViewController as! CAPBridgeViewController).bridge
    bridge?.webView?.evaluateJavaScript("handleQuickAction('pay-bills')")
}

private func performActionForAirtimeTopup() {
    print("Shortcut: Airtime Topup")
    let bridge = (self.window?.rootViewController as! CAPBridgeViewController).bridge
    bridge?.webView?.evaluateJavaScript("handleQuickAction('airtime-Topup')")
}

private func performActionForTransferMoney() {
    print("Shortcut: Transfer Money")
    let bridge = (self.window?.rootViewController as! CAPBridgeViewController).bridge
    bridge?.webView?.evaluateJavaScript("handleQuickAction('transfer-money')")
}

private func performActionForSnap2Pay() {
    print("Shortcut: Snap2Pay")
    let bridge = (self.window?.rootViewController as! CAPBridgeViewController).bridge
    bridge?.webView?.evaluateJavaScript("handleQuickAction('snap-2-pay')")
}

}

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.