SwiftUI

2023 年 9 月 3 日

在 SwiftUI 串接 AppKit 的 AppDelegate

已複製到剪貼板


用 NSApplicationDelegateAdaptor 在 SwiftUI 處理 AppKit 的 AppDelegate。

SwiftUI 和 AppKit
SwiftUI 和 AppKit

在 SwiftUI 中使用 AppKit 的 AppDelegate

在以 SwiftUI 為主要框架的專案中,如果要使用 AppKit 的 app delegate,要先定義一個遵從 NSApplicationDelegate protocol 的 class,並在裡面實作我們需要用到的 delegate methods。舉例來說,我們可以實作 application(_:didRegisterForRemoteNotificationsWithDeviceToken:) 在成功註冊 Apple Push Notification service(APNs)時做某件事。

class MyAppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
    func application(
        _ application: NSApplication,
        didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
    ) {
        // Record the device token.
    }
}

在定義完 AppDelegate 之後,就可以在 App 底下,使用 NSApplicationDelegateAdaptor property wrapper 來告訴 SwiftUI 我們的 AppDelegate 型別:

@main
struct MyApp: App {
    @NSApplicationDelegateAdaptor private var appDelegate: MyAppDelegate

    var body: some Scene { ... }
}

這裡可能會覺得奇怪,因為我們並沒有在宣告時就 init AppDelegate,而只告訴它型別,其實 SwiftUI 會自己建立 AppDelegate,並在對應的生命週期裡去呼叫 delegate methods。

注意

盡可能不使用 AppKit 的 app delegate 來處理 app 的生命週期事件,而應優先使用 SwiftUI 自身提供的。如:優先使用 ScenePhase,而非使用 delegate callback application(_:didFinishLaunchingWithOptions:)

ObservableObject:macOS 11.0+

如果我們定義的 AppDelegate 像上面的例子一樣遵從了 ObservableObject protocol,那 SwiftUI 就會把這個 delegate 放進 Environment 裡,我們可以在任何 Scene、任何 View 裡,用 Environment property wrapper 去取得 AppDelegate:

@EnvironmentObject private var appDelegate: MyAppDelegate

如果我們在自己定義的 AppDelegate 中有用到 @Published 的話,就可以直接使用錢字號($)來拿到 binding。

Observable:macOS 14.0+

相對於 ObservableObject,Observable 是比較新的 protocol,效果一樣,但不再需要使用 @Published。要從 Environment 中拿到遵從 Observable 的 AppDelegate 方法如下:

@Environment(MyAppDelegate.self) private var appDelegate

我們也可以直接使用錢字號($)來拿到 AppDelegate 中變數的 binding。

分享文章

已複製到剪貼板

主題文章

查看 SwiftUI

超級感謝

關於 XcodeProject

XcodeProject 創立於 2023,致力於協助開發者探索 Apple 的創新世界,學習在 iOS、iPadOS、macOS、tvOS、visionOS 與 watchOS 上開發 App,發現眾多技術與框架,讓開發者獲得更多能力。


Contacts

Ricky Chuang

XcodeProject

RickyChuang.xcodeproj@gmail.com

XcodeProject 聯絡

contact.xcodeproj@gmail.com

最新文章