You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS应用快捷菜单无法启动系统App问题求助

解决3D Touch快捷操作无法打开系统应用的问题

问题根源

  1. 冷启动时机过早:在application(_:didFinishLaunchingWithOptions:)中直接调用UIApplication.shared.open()时,应用尚未完全完成初始化流程,系统可能拦截该跳转请求。
  2. Notes URL Scheme错误:使用了无效的mobilenotes://,正确的Notes唤起Scheme是notes://。
  3. 启动返回值错误:处理快捷操作后返回false,会让系统判定应用启动未完成,干扰后续操作逻辑。

修复步骤

1. 修正Notes的URL Scheme

在AppDelegate的openNotes()方法中,替换Scheme为正确值:

private func openNotes() {
    openApp(withURLScheme: "notes://")
}

同时更新Info.plist中的LSApplicationQueriesSchemes数组,把mobilenotes替换为notes:

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>maps</string>
    <string>notes</string>
    <string>calshow</string>
</array>

2. 调整冷启动时的快捷操作处理逻辑

在application(_:didFinishLaunchingWithOptions:)中,将跳转操作延迟到主线程下一个运行周期,确保应用初始化完成后再执行,并且返回true:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    print("Application did finish launching with options.")

    self.window = UIWindow()
    self.window?.rootViewController = UIHostingController(rootView: ContentView())
    self.window?.makeKeyAndVisible()

    if let shortcutItem = launchOptions?[.shortcutItem] as? UIApplicationShortcutItem {
        print("Launching from Quick Action: \(shortcutItem.type)")
        DispatchQueue.main.async {
            self.handleShortcutItem(shortcutItem)
        }
    }

    return true
}

3. 确保跳转操作在主线程执行

在openApp(withURLScheme:)中明确在主线程执行跳转,避免潜在线程问题:

private func openApp(withURLScheme urlScheme: String) {
    print("Attempting to open app with URL Scheme: \(urlScheme)")
    guard let url = URL(string: urlScheme) else {
        print("Invalid URL Scheme: \(urlScheme)")
        return
    }
    
    DispatchQueue.main.async {
        if UIApplication.shared.canOpenURL(url) {
            print("Opening app with URL Scheme: \(urlScheme)")
            UIApplication.shared.open(url, options: [:], completionHandler: { success in
                print("Open result: \(success)")
            })
        } else {
            print("Cannot open URL Scheme: \(urlScheme)")
        }
    }
}

修改后的完整AppDelegate代码

import SwiftUI
import UIKit

class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?

    override init() {
        super.init()
        print("AppDelegate initialized")
    }

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        print("Application did finish launching with options.")

        self.window = UIWindow()
        self.window?.rootViewController = UIHostingController(rootView: ContentView())
        self.window?.makeKeyAndVisible()

        if let shortcutItem = launchOptions?[.shortcutItem] as? UIApplicationShortcutItem {
            print("Launching from Quick Action: \(shortcutItem.type)")
            DispatchQueue.main.async {
                self.handleShortcutItem(shortcutItem)
            }
        }

        return true
    }

    func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
        print("Received a Quick Action while running: \(shortcutItem.type)")
        handleShortcutItem(shortcutItem)
        completionHandler(true)
    }


    private func handleShortcutItem(_ shortcutItem: UIApplicationShortcutItem) {
        print("Handling Shortcut Item: \(shortcutItem.type)")

        switch shortcutItem.type {
        case "com.launcher.openMaps":
            print("Opening Maps...")
            openMaps()
        case "com.launcher.openCalendar":
            print("Opening Calendar...")
            openCalendar()
        case "com.launcher.openNotes":
            print("Opening Notes...")
            openNotes()
        default:
            print("Unhandled Shortcut Item: \(shortcutItem.type)")
        }
    }

    private func openMaps() {
        openApp(withURLScheme: "maps://")
    }

    private func openCalendar() {
        openApp(withURLScheme: "calshow://")
    }

    private func openNotes() {
        openApp(withURLScheme: "notes://")
    }

    private func openApp(withURLScheme urlScheme: String) {
        print("Attempting to open app with URL Scheme: \(urlScheme)")
        guard let url = URL(string: urlScheme) else {
            print("Invalid URL Scheme: \(urlScheme)")
            return
        }
        
        DispatchQueue.main.async {
            if UIApplication.shared.canOpenURL(url) {
                print("Opening app with URL Scheme: \(urlScheme)")
                UIApplication.shared.open(url, options: [:], completionHandler: { success in
                    print("Open result: \(success)")
                })
            } else {
                print("Cannot open URL Scheme: \(urlScheme)")
            }
        }
    }
}

@main
struct LauncherApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

额外验证点

  • 确保真机上的Maps、Calendar、Notes系统应用未被删除(模拟器默认存在)。
  • 测试时先完全退出应用,再通过3D Touch快捷操作唤起,验证冷启动场景下的跳转是否正常。

内容的提问来源于stack exchange,提问作者Victor Ricci

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 23:20:38