可组合的用户通知

CI

可组合的用户通知是一个桥接 Composable Architecture用户通知 的库。

从 0.3.0 版本开始,该库使用 swift 并发 来建模其依赖项。

示例

查看 Example 演示,了解如何使用 ComposableUserNotifications

基本用法

要处理传入的用户通知,你可以通过 UserNotificationClient.delegateUserNotificationClient.DelegateAction 观察 UNUserNotificationCenterDelegate 的动作。

import ComposableUserNotifications

struct App: ReducerProtocol {
  enum Action {
  case userNotification(UserNotificationClient.DelegateAction)
  // Your domain's other actions:
...

UserNotificationClient.DelegateAction 包含以下动作:

苹果 UNUserNotificationCenter 的包装器 UserNotificationClientDependencyValues 上可用,可以使用 @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])
        }
      )
    }
  }
  ...
}

添加通知请求也很简单。 可以结合 UNNotificationRequestUserNotificationClient.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 项目中。

  1. 文件菜单中,选择Swift Packages › Add Package Dependency…
  2. 在包存储库 URL 文本字段中输入 "https://github.com/miiha/composable-user-notifications"

许可

本库采用 MIT 许可证发布。 有关详细信息,请参阅 LICENSE