可组合的用户通知是一个桥接 Composable Architecture 和 用户通知 的库。
从 0.3.0 版本开始,该库使用 swift 并发 来建模其依赖项。
查看 Example 演示,了解如何使用 ComposableUserNotifications。
要处理传入的用户通知,你可以通过 UserNotificationClient.delegate
的 UserNotificationClient.DelegateAction
观察 UNUserNotificationCenterDelegate
的动作。
import ComposableUserNotifications
struct App: ReducerProtocol {
enum Action {
case userNotification(UserNotificationClient.DelegateAction)
// Your domain's other actions:
...
UserNotificationClient.DelegateAction
包含以下动作:
willPresentNotification(_:completion)
didReceiveResponse(_:completionHandler:)
openSettingsForNotification(_:)
苹果 UNUserNotificationCenter
的包装器 UserNotificationClient
在 DependencyValues
上可用,可以使用 @Dependency(\.userNotifications)
检索。
在某个时刻,你需要订阅 UserNotificationClient.DelegateAction
以免错过任何与 UNUserNotificationCenterDelegate
相关的动作。 这可以在应用程序启动后尽早完成。
func reduce(into state: inout State, action: Action) -> EffectTask<Action> {
switch action {
case let .didFinishLaunching(notification):
...
return .run { send in
for await event in self.userNotifications.delegate() {
await send(.userNotifications(event))
}
}
}
}
}
订阅这些动作后,我们可以如下处理它们。
...
case let .userNotification(.willPresentNotification(notification, completion)):
return .fireAndForget {
completion([.list, .banner, .sound])
}
case let .userNotification(.didReceiveResponse(response, completion)):
return .fireAndForget {
completion()
}
case .userNotification(.openSettingsForNotification):
return .none
...
要请求用户授权,可以使用 requestAuthorization
并将用户的选择作为新动作处理。
func reduce(into state: inout State, action: Action) -> EffectTask<Action> {
switch action {
case .didFinishLaunching:
return .task {
.requestAuthorizationResponse(
TaskResult {
try await self.userNotifications.requestAuthorization([.alert, .badge, .sound])
}
)
}
}
...
}
添加通知请求也很简单。 可以结合 UNNotificationRequest
和 UserNotificationClient.add(_:)
来完成。
case .tappedScheduleButton:
let content = UNMutableNotificationContent()
content.title = "Example title"
content.body = "Example body"
let request = UNNotificationRequest(
identifier: "example_notification",
content: content,
trigger: UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
)
return .task {
await self.userNotifications
.removePendingNotificationRequestsWithIdentifiers(["example_notification"])
return await .addNotificationResponse(
TaskResult {
Unit(try await self.userNotifications.add(request))
}
)
}
...
所有对 UNUserNotificationCenter
的 API 调用都可通过 UserNotificationClient
获得。 这种方法的真正力量在于通知逻辑的可测试性。 有关可测试性的更多信息,请查看 ExampleTests.swift。
你可以通过将其添加为包依赖项,将 ComposableUserNotifications 添加到 Xcode 项目中。
本库采用 MIT 许可证发布。 有关详细信息,请参阅 LICENSE。