我正在尝试使用最新版本的 Swift 创建一个 iOS 应用程序,用户可以在主屏幕上强制触摸我们的应用程序。然后可以选择打开苹果日历、笔记或地图。但是,当我们点击这些时,只会打开我们的应用程序,而不会打开相应的苹果应用程序。
这是我的 LauncherApp.swift 文件:
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)")
handleShortcutItem(shortcutItem)
return false
}
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: "mobilenotes://")
}
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
}
if UIApplication.shared.canOpenURL(url) {
print("Opening app with URL Scheme: \(urlScheme)")
UIApplication.shared.open(url, options: [:], completionHandler: nil)
} else {
print("Cannot open URL Scheme: \(urlScheme)")
}
}
}
@main
struct LauncherApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
这是我的 info.plist 文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>maps</string>
<string>mobilenotes</string>
<string>calshow</string>
</array>
<key>UIApplicationShortcutItems</key>
<array>
<dict>
<key>UIApplicationShortcutItemIconType</key>
<string>UIApplicationShortcutIconTypeLocation</string>
<key>UIApplicationShortcutItemTitle</key>
<string>Open Maps</string>
<key>UIApplicationShortcutItemType</key>
<string>com.launcher.openMaps</string>
</dict>
<dict>
<key>UIApplicationShortcutItemIconType</key>
<string>UIApplicationShortcutIconTypeDate</string>
<key>UIApplicationShortcutItemTitle</key>
<string>Open Calendar</string>
<key>UIApplicationShortcutItemType</key>
<string>com.launcher.openCalendar</string>
</dict>
<dict>
<key>UIApplicationShortcutItemIconType</key>
<string>UIApplicationShortcutIconTypeCompose</string>
<key>UIApplicationShortcutItemTitle</key>
<string>Open Notes</string>
<key>UIApplicationShortcutItemType</key>
<string>com.launcher.openNotes</string>
</dict>
</array>
</dict>
</plist>
这里是 ContentView.swift,它可以完美地打开地图:
import SwiftUI
struct ContentView: View {
var body: some View {
Button("Test Open Maps") {
openApp(withURLScheme: "maps://")
}
}
func openApp(withURLScheme urlScheme: String) {
guard let url = URL(string: urlScheme) else { return }
if UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
我是 iOS 开发新手,很抱歉只是转储代码,我已经尝试在模拟器和 iPhone 上进行测试,但它在两者上都不起作用。
我什至尝试询问多个人工智能服务,这就是我们现在的情况😅
在 iOS 13 及更高版本下运行时,App Delegate 不用于处理快捷方式。您现在需要处理场景委托中的快捷方式项目。
将名为 SceneDelegate.swift 的文件添加到您的项目中,其中包含以下内容:
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let _ = (scene as? UIWindowScene) else { return }
// This will be true if a shortcut item is selected while the app is not running
if let shortcutItem = connectionOptions.shortcutItem {
_ = handleShortcutItem(shortcutItem)
}
}
// Called if a shortcut item is selected while the app is already running
func windowScene(_ windowScene: UIWindowScene, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
let res = handleShortcutItem(shortcutItem)
completionHandler(res)
}
private func handleShortcutItem(_ shortcutItem: UIApplicationShortcutItem) -> Bool {
print("Handling Shortcut Item: \(shortcutItem.type)")
switch shortcutItem.type {
case "com.launcher.openMaps":
print("Opening Maps...")
openMaps()
return true
case "com.launcher.openCalendar":
print("Opening Calendar...")
openCalendar()
return true
case "com.launcher.openNotes":
print("Opening Notes...")
openNotes()
return true
default:
print("Unhandled Shortcut Item: \(shortcutItem.type)")
}
return false
}
private func openMaps() {
openApp(withURLScheme: "maps://")
}
private func openCalendar() {
openApp(withURLScheme: "calshow://")
}
private func openNotes() {
openApp(withURLScheme: "mobilenotes://")
}
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
}
if UIApplication.shared.canOpenURL(url) {
print("Opening app with URL Scheme: \(urlScheme)")
UIApplication.shared.open(url, options: [:], completionHandler: nil)
} else {
print("Cannot open URL Scheme: \(urlScheme)")
}
}
}
在 AppDelegate.swift 中,删除用于处理快捷方式的私有函数(所有代码现在都在
SceneDelegate
中)。删除 performActionFor
应用程序委托方法,因为从 iOS 13 开始不再使用它。从 if let...
应用程序委托方法中删除 didFinishLaunchingWithOptions
块,因为它也在场景委托中处理。
对于 UIKit 应用程序来说,这就是所需要的。
对于 SwiftUI 应用程序,您需要将以下内容添加到您的
AppDelegate
:
// Setup the scene delegate
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
let configuration = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role)
if connectingSceneSession.role == .windowApplication {
configuration.delegateClass = SceneDelegate.self
}
return configuration
}
这让 SwiftUI 应用程序了解您的
SceneDelegate
类。
这些更改与 Info.plist 中快捷方式项目和 URL 方案查询的现有设置相结合,将使您的应用程序能够按预期响应快捷方式项目。