(WWDC) 实践 Combine



本篇为 初探 Combine 的续篇。


内容概览

  • Publisher & Subscriber
  • Failure Handling Operator
  • Scheduled Operator
  • Cancellation
  • Subject
  • SwiftUI BindableObject
  • 集成 Combine





Publisher & Subscriber


Publisher

  • 事件流的源头
  • Operators 从现有的 publishers 产生新的 publishers
  • 随着时间产生强类型的值或错误
  • 可以同步,也可以异步
  • 可以附加兼容的 Subscribers


Subscriber

(WWDC) 实践 Combine_第1张图片
Subscriber 的定义
(WWDC) 实践 Combine_第2张图片
接收订阅事件
(WWDC) 实践 Combine_第3张图片
接收值(0个或多个)产生事件
(WWDC) 实践 Combine_第4张图片
接收普通完成事件
(WWDC) 实践 Combine_第5张图片
接收带有错误的完成事件
(WWDC) 实践 Combine_第6张图片
Subscriber 的特点



不同的Subscribers

  • Key Path 赋值
  • Sinks
  • Subjects
  • SwiftUI


1306450-06c6a7b21c9aef3b.png
创建 Publisher
(WWDC) 实践 Combine_第7张图片
使用 map Operator 对输出进行转换
(WWDC) 实践 Combine_第8张图片
使用 tryMap Operator 解析输入值并输出解析后的模型
(WWDC) 实践 Combine_第9张图片
直接使用 decode Operator,操作更简洁高效





Failure Handling Operator


错误处理

  • Publisher 描述如何失败
  • 由 Operator 来响应/恢复错误


(WWDC) 实践 Combine_第10张图片
使用 assertNoFailure Operator
(WWDC) 实践 Combine_第11张图片
当错误发生时,运行时错误会导致崩溃


失败处理 Operator

  • assertNoFailure
  • retry
  • catch
  • mapError
  • setFailureType



Catch

1306450-80d76e0f8da62015.png

(WWDC) 实践 Combine_第12张图片

(WWDC) 实践 Combine_第13张图片
(WWDC) 实践 Combine_第14张图片
使用 catch Operator 需要返回一个备用的 Publisher


结构概览:

(WWDC) 实践 Combine_第15张图片


flatMap

(WWDC) 实践 Combine_第16张图片



结构分析:

(WWDC) 实践 Combine_第17张图片
使用 flatMap Operator


(WWDC) 实践 Combine_第18张图片
flatMap Operator 中的子步骤
(WWDC) 实践 Combine_第19张图片
decode Operator 中发生错误
(WWDC) 实践 Combine_第20张图片
使用 catch Operator 从错误中恢复
(WWDC) 实践 Combine_第21张图片
1306450-d0a037aa9035e6f3.png
flatMap Operator 将恢复后的结果向下传递


Before:

(WWDC) 实践 Combine_第22张图片

After:

(WWDC) 实践 Combine_第23张图片



(WWDC) 实践 Combine_第24张图片
将结果绑定到对象的属性上





Scheduled Operator

描述 在何时 和 在何处 执行
由 RunLoop 和 DispatchQueue 提供支持

  • delay
  • debounce
  • throttle
  • receive(on:)
  • subscribe(on:)


(WWDC) 实践 Combine_第25张图片





Cancellation

内置于 Combine
提前结束订阅


(WWDC) 实践 Combine_第26张图片
(WWDC) 实践 Combine_第27张图片





Subject

可以表现为 Publisher, 也可以表现为 Subscriber
可以通过广播的方式向多个 subscribers 发送值


1306450-1ed59cd815b4907a.png
(WWDC) 实践 Combine_第28张图片
(WWDC) 实践 Combine_第29张图片
(WWDC) 实践 Combine_第30张图片



不同的 Subjects

(WWDC) 实践 Combine_第31张图片
(WWDC) 实践 Combine_第32张图片
(WWDC) 实践 Combine_第33张图片

CurrentValue 会保存结果,而 Passthrough 不会。


示例代码:

(WWDC) 实践 Combine_第34张图片





SwiftUI BindableObject


使用 SwiftUI

SwiftUI持有 Subscriber
你只需要给它提供 Publisher


SwiftUI BindableObject

(WWDC) 实践 Combine_第35张图片
(WWDC) 实践 Combine_第36张图片





集成 Combine


如何使用 Combine 实现以下需求呢?

(WWDC) 实践 Combine_第37张图片




(WWDC) 实践 Combine_第38张图片
(WWDC) 实践 Combine_第39张图片
(WWDC) 实践 Combine_第40张图片



@Published

属性包装器
可以添加 publisher 到任何属性上


使用示例:

(WWDC) 实践 Combine_第41张图片



先实现与密码输入框相关的工作:

(WWDC) 实践 Combine_第42张图片

使用 CombineLatest 结合两个 Publisher 的最新值:

(WWDC) 实践 Combine_第43张图片

使用 validatedPassword 即可订阅密码输入相关的事件:

(WWDC) 实践 Combine_第44张图片

请观察 validatedPassword 的类型,好像有点冗长!

(WWDC) 实践 Combine_第45张图片

假设某个密码一定是无效的:

(WWDC) 实践 Combine_第46张图片

简化 validatedPassword 的类型:

(WWDC) 实践 Combine_第47张图片

至此,与密码输入框相关的工作已完成。

(WWDC) 实践 Combine_第48张图片




下面进行与用户名输入框相关的工作:

(WWDC) 实践 Combine_第49张图片
(WWDC) 实践 Combine_第50张图片
debounce

使用 debounce 可以有效地减少重复请求的次数:

(WWDC) 实践 Combine_第51张图片

设置 debounce 的阈值为 0.5 秒,并且在 Main RunLoop 上调度执行:

(WWDC) 实践 Combine_第52张图片

除此之外,还需要请求网络来进行校验:

(WWDC) 实践 Combine_第53张图片

使用 flatMap :

(WWDC) 实践 Combine_第54张图片

单次网络请求,使用 Future 更适合:

(WWDC) 实践 Combine_第55张图片

完善请求的响应部分:

(WWDC) 实践 Combine_第56张图片


结构概览:

(WWDC) 实践 Combine_第57张图片

至此,与用户名输入框相关的工作已完成。

(WWDC) 实践 Combine_第58张图片



最后,进行与创建帐号按钮相关的工作。


结合用户名、密码相关的 Publisher :

(WWDC) 实践 Combine_第59张图片

绑定结果到按钮上:

(WWDC) 实践 Combine_第60张图片

至此,与创建帐号按钮相关的工作也完成了。

(WWDC) 实践 Combine_第61张图片

结构概览:

(WWDC) 实践 Combine_第62张图片



从现在开始使用 Combine

  • 将小部件组合成 publishers
  • 逐步采用
  • 使用 @Published 为属性添加 Publisher
  • 使用 Future 组合闭包和 Publisher





参考内容:
Combine in Practice




转载请注明出处,谢谢~

你可能感兴趣的:((WWDC) 实践 Combine)