SwiftUI 与 Combine(简介)

什么是SwiftUI?

苹果开发平台的新UI框架,基于swift。由于swift ABI 稳定,将会诞生更多的swift框架。SwiftUI是用来替换原IOS平台的UIKit和macOS的APPKit的UI框架,特性是声明式的编程。

什么是Combine?

Combine框架为你的应用程序处理事件提供了一种声明性的方法。你可以为给定的事件源创建单个处理链,而不是潜在地实现多个委托回调或完成处理程序闭包。链的每个部分都是一个合并运算符,对从上一步接收到的元素执行不同的操作。(类似于RXSwift中的Observable和各种操作符)

响应式编程:

对于苹果的平台,已经有几个第三方响应式框架,比如RxSwift,它实现了Rx标准;ReactiveSwift,它受到了Rx的启发;intercellar,它是一个自定义实现。
Combine实现了一个与Rx不同但类似的标准,称为响应流。响应流与Rx有一些关键的区别,但它们都有着大多数相同的核心概念。
如果您以前没有使用过上面提到的一个或另一个框架,请不要担心。到目前为止,反应式编程已经成为苹果平台的一个相当小的概念,特别是在Swift中
如果你之前有RXSwift或者ReactiveCocoa的响应式编程经验,你将很容易学习SwiftUI+Combine编程。如果没有这部分知识,没有关系,并且你可以忽略以下文章中所有关于RXSwift的内容,但你需要了解这将是一种和原本UIKIt和AppKit都不同的UI编程方式,原本的UIKit更新界面操作的是UI组件对象的属性,而新的编程方式则是将数据和UI进行绑定,需要更改UI界面时,直接修改数据源或者页面状态,而UI页面将自动过渡到新的状态。

异步编程:

原本的Foundation+UIKIt/AppKit通过通知、代理、闭包和GCD等提供了丰富的异步编程方式,这些处理方式在过去一直服务于苹果应用开发,在SwiftUI早期我们仍然可能会用到这部分内容,但是SwiftUI+Combine也提供了其独有的异步处理事件方式

15783790827109.jpg

Combine旨在向Swift生态系统引入一种新的语言,帮助您在异步编程世界的混乱中带来更多的秩序。苹果已经将Combine的API深深地集成到了基础框架中,因此Timer、NotificationCenter和核心框架(比如CoreData)已经在使用它的语言。幸运的是,Combine也很容易集成到您自己的代码中。
为了让您了解Apple如何致力于使用Combine进行响应式编程,这里有一个简单的图表,显示了Combine在系统层次结构中的位置:


15783793242050.jpg

各种系统框架,从Foundation一直到SwiftUI,都依赖于Combine,并提供Combine集成作为其“传统”api的替代。
因为Combine是一个Apple框架,所以它并不是要取消经过良好测试的、可靠的api(如Timer或NotificationCenter)的角色。这些基础类型仍然存在,并尽了自己的职责。相反,Combine与它们集成,并允许应用程序中的所有类型通过一种新的通用语言彼此异步对话。
因此如果理想的话我们可以使用同一种异步工具链接应用的各个部分 ,从数据模型到网络层直至用户界面。

何时可以使用新的框架

在iOS 13/macOS Catalina中,苹果通过内置的系统框架Combine为其生态系统带来了响应式编程支持。
与苹果的任何新技术一样(比如当初的Swift),它的应用程序起初都有点有限:您只能将Combine用于支持iOS 13/macOS Catalina或更高版本的应用程序。但与苹果押注的任何技术一样,它的支持将迅速普及,对Combine编程的技能需求将激增。
话虽如此,从学习Combine的一些基本知识开始,看看它如何帮助您编写安全可靠的异步代码。

Combine基础

简单来说Combine编程具有三个重要成员:publishers、operators、subscribers,我们将在之后慢慢介绍着三大成员以及适用于这些成员的操作符。

Publishers

publishers可以随时间推移向一个或多个订阅者(如subscribers)发送值类型数据。不管Publisher的内部逻辑(几乎可以是任何东西,包括数学计算、联网或处理用户事件),每个Publisher都可以发出这三种类型的多个事件:

  1. 泛型类型的值(类似RXSwift的next事件)。

  2. successful completion完成事件。(类似RXSwift的complete事件)

  3. error completion 错误事件。(类似RXSwift的error事件)

一个publisher 可以发出零个或多个值,如果发出success或者error事件这不再发出更多值

下面是发布Int值的Publisher在时间线上的可视化效果:


15783811303415.jpg

publishers也内置了错误处理,因此如果你需要的话,你也可以自定义错误处理。
Publisher协议有两个泛型类型,从上图中可以看出:
•Publisher.Output是Publisher的输出值类型。如果publisher专门化为Int,则它永远不会发出字符串或日期值。
•Publisher.Failure是publisher在失败时可能引发的错误类型。如果发布服务器永远不会失败,则可以使用Never来指定。
当您订阅一个给定的Publisher时,你知道期望从它获得什么类型的值,以及它可能会失败的错误。

Operators

操作符是在Publisher协议上声明的方法,返回相同或新的Publisher。(类似于Swift标准库中数组的操作符map、filter、zip等的作用,RXSwift中也是类似的)
操作符是高度耦合和可组合的,当一个操作符的输出试下一个操作符的输入时你可以想拼图一样将他们组装在一起,的到想要的值

15783824143836.jpg

用明确的声明式方法定义每个处理过程,你可以确定每个处理的顺序,以及得到正确的输入输出值类型

Subscribers

最后,你到达订阅链的末端:每个订阅链都以Subscriber结束,来对Publisher发出的输出或完成事件执行“操作”。


15783827341859.jpg

目前,Combine提供了两个内置的subscriber,这使得处理数据流变得简单

  • sink subscriber 允许您提供闭包和接收值和完成事件。你可以订阅到任何发出的事件。
  • assign subscriber允许您在不需要自定义代码的情况下,将结果输出绑定到数据模型或UI控件上的某个属性,以便通过key Path直接在屏幕上显示数据。

如果您对数据有其他需求,创建自定义Subscriber甚至比创建Publisher更容易。Combine使用一组非常简单的协议,允许您构建自己的自定义工具。

Subscriptions

当您在订阅链的末尾添加subscriber时,它会在链的开头一直“激活”publisher。这是一个需要记住的奇怪但重要的细节-如果没有subscriber潜在地接收输出,则publisher不会发出任何值。
一旦订阅代码编译成功,并且自定义代码中没有逻辑问题,就完成了!按照设计,每当某个事件(如用户手势、计时器关闭或其他事件)唤醒某个publisher时,订阅将异步“启动”。
更好的是,由于Combine提供了一个称为Cancellable的协议,您不需要专门管理内存订阅。

两个系统提供的subscriber都符合Cancellable协议的,这意味着您的订阅代码(例如,整个publisher、operator和subscriber调用链)返回一个可取消的对象。每当您从内存中释放该对象时,它将取消整个订阅并从内存中释放其资源。(作用类似RXSwift DisposeBag)

例如,这意味着您可以通过将订阅存储在视图控制器上的属性中,轻松地管理“绑定”订阅的生命周期。这样,每当用户从视图堆栈中解除视图控制器时,将释放属性,同时也将取消您的订阅。

应用程序架构

可能碰到这个问题时那你会说这超出了你学习的预期值,但是不要担心,Combine不是一个影响应用程序结构的框架,你可以在MVC(Model-View-Controller)应用程序中使用Combine,也可以在MVVM(Model-View-ViewModel)代码、VIPER等中使用Combine。您可以迭代和有选择地添加Combine代码,只在希望在代码库中改进的部分使用它。这不是一个“要么全有要么全无”的选择。
如果你同时采用Combine和SwiftUI,情况就稍微不同了。在这种情况下,将C从MVC架构中删除确实是有意义的。但这要归功于Combine和SwiftUI的协同使用——这两种物资在同一个房间里都会发生反应。
你不再需要Viewcontroller去控制你的视图显示,当你的到数据后这一切都交给SwiftUI和Combine处理就行了

15783851256113.jpg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容