Combine 系列
- Swift Combine 从入门到精通一
- Swift Combine 发布者订阅者操作者 从入门到精通二
- Swift Combine 管道 从入门到精通三
- Swift Combine 发布者publisher的生命周期 从入门到精通四
- Swift Combine 操作符operations和Subjects发布者的生命周期 从入门到精通五
- Swift Combine 订阅者Subscriber的生命周期 从入门到精通六
- Swift 使用 Combine 进行开发 从入门到精通七
- Swift 使用 Combine 管道和线程进行开发 从入门到精通八
- Swift Combine 使用 sink, assign 创建一个订阅者 从入门到精通九
- Swift Combine 使用 dataTaskPublisher 发起网络请求 从入门到精通十
- Swift Combine 用 Future 来封装异步请求 从入门到精通十一
- Swift Combine 有序的异步操作 从入门到精通十二
- Swift Combine 使用 flatMap 和 catch错误处理 从入门到精通十三
- Swift Combine 网络受限时从备用 URL 请求数据 从入门到精通十四
- Swift Combine 通过用户输入更新声明式 UI 从入门到精通十五
- Swift Combine 级联多个 UI 更新,包括网络请求 从入门到精通十六
- Swift Combine 合并多个管道以更新 UI 元素 从入门到精通十七
- Swift Combine 通过包装基于 delegate 的 API 创建重复发布者 从入门到精通十八
1. 响应 NotificationCenter 的更新
目的:作为发布者接收 NotificationCenter 的通知,以声明式的对所提供的信息做出响应。
单元测试在 UsingCombineTests/NotificationCenterPublisherTests.swift
大量的框架和用户界面组件通过 NotificationCenter 的通知提供有关其状态和交互的信息。 Apple 的文档包括一篇关于 receiving and handling events with Combine 的文章,特别提及了 NotificationCenter。
通过 NotificationCenter 发送的 Notifications 为你应用中的事件提供了一个通用的中心化的位置。
你还可以将自己的通知添加到你的应用程序中,在发送通知时,还可以在其 userInfo
属性中添加一个额外的字典来发送数据。 一个定义你自己通知的示例 .myExampleNotification
:
extension Notification.Name {
static let myExampleNotification = Notification.Name("an-example-notification")
}
通知名称是基于字符串的结构体。 当通知发布到 NotificationCenter 时,可以传递对象引用,表明发送通知的具体对象。 此外,通知可以包括 userInfo
,是一个 [AnyHashable : Any]?
类型的值。 这允许将任意的字典(无论是引用类型还是值类型)包含在通知中。
let myUserInfo = ["foo": "bar"]
let note = Notification(name: .myExampleNotification, userInfo: myUserInfo)
NotificationCenter.default.post(note)
虽然在 AppKit 和 macOS 应用程序中普遍地使用了通知,但并非所有开发人员都乐于大量使用 NotificationCenter。 通知起源于更具动态性的 Objective-C runtime ,广泛利用 Any 和 optional 类型。 在 Swift 代码或管道中使用它们意味着管道必须提供类型检查并处理与预期或非预期的数据相关的任何可能错误。
创建 NotificationCenter 发布者时,你提供要接收的通知的名称,并可选地提供对象引用,以过滤特定类型的对象。 属于 NSControl
子类的多个 AppKit 组件共享了一组通知,过滤操作对于获得这些组件的正确的通知至关重要。
订阅 AppKit 生成通知的示例:
let sub = NotificationCenter.default.publisher(for: NSControl.textDidChangeNotification, // 1
object: filterField) // 2
.map { ($0.object as! NSTextField).stringValue } // 3
.assign(to: \MyViewModel.filterString, on: myViewModel) // 4
- AppKit 中的 TextField 在值更新时生成
textDidChangeNotification
通知。 - 一个 AppKit 的应用程序通常可以具有大量可能被更改的
TextField
。 包含对发送控件的引用可用于过滤你特别感兴趣的文本的更改通知。 map
操作符可用于获取通知中包含的对象引用,在这个例子中,发送通知的 TextField 的.stringValue
属性提供了它更新后的值。- 由此产生的字符串可以使用可写入的
KeyValue
路径进行 assign。
一个订阅你自己的通知事件的示例:
let cancellable = NotificationCenter.default.publisher(for: .myExampleNotification, object: nil)
// can't use the object parameter to filter on a value reference, only class references, but
// filtering on 'nil' only constrains to notification name, so value objects *can* be passed
// in the notification itself.
.sink { receivedNotification in
print("passed through: ", receivedNotification)
// receivedNotification.name
// receivedNotification.object - object sending the notification (sometimes nil)
// receivedNotification.userInfo - often nil
}
参考
https://heckj.github.io/swiftui-notes/index_zh-CN.html
代码
https://github.com/heckj/swiftui-notes