Tag: 反应式编程

一个不真正使用反应性可可的案例

在生产项目中,我已经在生产项目中使用了功能性反应式编程(FRP)和反应性可可粉(以及最近的反应性Swift),并且看到有人采用它。 在整个过程中,我们不仅学会了如何使用FRP,还学会了如何不使用它。 在本文中,我将反思我自己犯下的一些典型的新手失误,以便来自传统命令式或混合语言(如Objective-C,Java或C#)背景的人也许可以从我的错误中学到东西。 我们将考虑一个问题以及三个不同的解决方案: 天真的(和错误的)命令式解决方案, 正确的命令,以及 正确的FRP样式的解决方案 希望最后,您将了解FRP如何有助于解决与UI和异步编程有关的一些问题。 本文假定您熟悉Reactive Swift的基础知识(尤其是Signals和SignalProducers的概念)。 您可以使用ReactiveSwift自述文件快速赶上那些。 问题 假设我们开发了一个带有视图控制器的购物应用程序,该控制器需要显示可从远程API获得的产品描述列表。 有文字说明和图片网址。 该图像将必须使用网络请求进行下载。 假设网络请求是使用Reactive Swift的SignalProducer提取的,我们将专注于以MVVM方式为表视图单元格编写代码。 天真的解决方案 事实证明,这不是我们使用此代码可以获得的唯一问题。 考虑下面的序列图,其中下载发生的速度比滚动使单元1离开屏幕的速度更快。 当重复使用单元格中的产品a的图像替换为正确的产品b的图像时,我们将再次观察到图像的错误归因。 让我们来解决它! 我们是强大的! 我们可以立即修复所有问题! (实际上,这将需要一些时间,但是请注意!)当单元格收到新的viewModel值时,我们将终止任何先前的下载信号订阅。 这样,我们将解决序列1的问题。 然后,对于每个新的viewModel值,我们将使用占位符(在本例中为nil )替换单元格中的图像,以防止显示的文本内容与图像之间的不匹配,如序列2中所述 。 听起来像是个计划? 使用这些修复程序后,单元将仅显示与分配的产品或占位符相对应的图像。 我们终于都准备好了,不是吗?—看这段代码,让我们问问自己,为什么我们这里甚至使用了活性可可粉? 我们从学习和使用新图书馆中获得了哪些好处? 可变属性! —并非如此,我们可以在这里使用内置的Swift的didSet观察器。 信号产生器在此处封装了异步操作的状态! —是的,但是众所周知的Foundation的Operation对象也是如此。 我们可以定义一个具有依赖BlockOperation的DownloadImageOperation ,并且甚至不需要学习Reactive Cocoa就可以完成该任务。 我们可以做得更好吗? —是的。 这里发生的事情是,我们使用FRP的方式与使用常规命令式工具的方式相同,而没有考虑该方法对于在此处理的UI和异步编程问题必须提供的功能。 玻璃钢解决方案 函数式反应式编程可让我们使用(并为方便起见而使用)的两个出色工具是: UI编程的绑定 将信号与功能样式运算符(例如贴图,过滤器和展平器)结合使用,并自然地管理所得信号的寿命。 这是我们如何将其应用于问题的方法(为清楚起见,我们将只专注于awakeFromNib的实现(其余原始代码将保持不变): 让我们确切说明我们在这里做什么。 <~是一个绑定运算符,作用于实现BindingTargetProtocol (左侧)和BindingSourceProtocol (右侧)的值。 将运算符应用于这些值会在目标指定的生存期内(在我们的示例中,这是UILabel和UIImageView的生存期)将目标与源发出的值进行订阅,即,保证订阅将在指定的生存时间内终止。 请注意,在第3行和第4行中,我们如何直接映射属性而不是映射信号生成器。 属性的此功能仅可从Reactive […]

RxSwift ve RxCocoa’yaGiriş

Bugünsizlere 4个版本iOS开发人员hayatımdakullanmaktan ençokkeyifaldığımve beni daha iyi bir开发人员halinegetirdiğineinandığımbiraraçtanbahsetmek istiyorum。 Buyazıyıokuyarakgünümüzdeçokpopülerolan反应性程序,RxSwift和RxCocoa说,迅速发展,大力发展edebilecek seviyeyegeleceğinizeinanıyorum。 首席iOS开发人员olarakçalıştığımBundle News’da dayoğunbirşekildebuyapılarıkullandığımızıve gayet memnunolduğumuzubelirtmek isterim。 RxSwiftkütüphanesi使Swift’i tamamenfarklıbirşekildekullanmamızaolanaksağlıyor。 Bukütüphaneyleasenkron programlama yapmak hemçokkolay hem deçokdahaokunaklıhale geliyor。 dahasağlammimarilertasarlamanızave daha kaliteli uygulamalaryapmanızaolanaksağlıyor。 RxCocoa可以在iOS或OS X上运行,而可乐API可以在反应性中使用。 Buyazıdabilmeniz gereken konseptlerden biri可观察的vediğeriObserver’dır。 可观察到的 (gözlemlenebilir),değişiklikleriyayımlayanyapılardır。 观察员 (gözlemleyici)yapılar可观察到的yapılara订阅olarak,değişlikolduğundahaberleri olanyapılardır。 RxSwift和RxCocoa,ARC已售出DisposeBag denilen biraraçbulundurmaktadır。 DisposeBag’i观察员objeleritaşıyansanal birçantagibidüşünebiliriz。 Observer’larıtanımladığımızebeveyn objelerin(父对象)hafızadanuçtuğundaObserver’larındandadüzgünbirşekildekurtulmakiçinDisposeBagaracınıkullanırız。 Biraz kavramlar konusundakafanızkarışmışolabilir amayazınındevamındadaha iyianlayacaksınız。 大小RxSwift ve RxCocoakütüphanelerinidaha […]

Elm体系结构:将R隐藏在FRP中

函数式反应式编程在移动应用程序开发中风靡一时。 在我以前在Ackee工作期间,我们是ReactiveCocoa / ReactiveSwift的早期采用者。 最初,其他团队可能会因学习曲线而推迟,但到现在,大多数公司已经看到了某种形式的反应式编程,并且许多公司正在包括iOS和Android在内的不同平台上使用Rx框架。 MVVM-OOP的最后一口气 使用FRP,将所有不同的数据源连接到几乎是声明性的视图层就像以可观察的形式存储状态一样容易。 您只需要一个放置这些可观察属性的位置和一些将值填充它们的业务逻辑即可—您需要一个ViewModel。 但是MVVM有它的问题。 您可以以一种方式绘制所有箭头(即View-> ViewModel-> Model ),但是在另一个方向上仍然存在通信。 您声明了反应式绑定,而不必理会它们,就像箭头没有出现一样。 它只是有效…除非出现死锁。 更糟糕的是,找到此类死锁的根源(无论是递归事件还是在错误的时间发送多个信号)都不是最困难的问题。 修复它。 通过使用反应式框架,您已经声明了代码可以处理我们向其抛出的任何输入, 无论何时我们 选择扔它。 除了现在,它不能。 您应该如何解决这个问题? 一个简单的skipRepeats()有时会有所帮助,但有时您最终会编写诸如.skip(first: 2)或.delay(0.0, on: QueueScheduler.main)并祈祷该项目在无法管理之前结束。 此外,ViewModels是对象。 您已经在内部用FRP替换了OOP,但是您的应用仍然由这些需要协调的有状态的参与者组成。 当两个ViewModel需要共享某种状态时,您可以掷硬币— “头说我们将其放在’服务’中,尾部是’经理’”。 无论哪种方式,它都是另一个有状态的对象。 这些之间的通讯又如何呢? 您是否曾经想过编写ManagerManager? 在撰写有关iOS应用程序体系结构的文章时,我已经知道这是我对MVVM的再见。 我对此非常满意,赞赏过去几年为我所做的一切。 但是现在该继续前进了。 现在该摆脱所有这些行为,反应,通讯,同步并导致不一致和死锁的对象了。 现在该停止像没有并发那样行动,而要真正做好随时准备参加任何事件的准备。 效果也可以将事件反馈到程序中,视图也可以。 效果分为命令(用于发出HTTP请求)和订阅(用于侦听数据更改(套接字,本地和远程数据库等))。 因此,我们的最终更新层如下所示: func update(来自模型:Model,带有msg:Msg)->(Model,Cmd ) func订阅(用于模型:模型)-> Sub 和我们的视图层: func view(for model:Model)-> ViewDescription 我失去了时间。 本文越来越长,但这不是我的意思。 我过去是将FRP出售给学生的是功能编程+时间 。 […]

RxSwift:Swift的响应式扩展第1部分

在本博文的第一部分中,我们将探索该理论,以便理解RxSwift,尤其是ReactiveX。 在第二部分中,我们将应用此概念来使用RxSwift创建示例iOS应用程序。 什么是反应性扩展? “ ReactiveX是Observer模式,Iterator模式和函数式编程的最佳创意的结合体” 观察员和演说者? GoF书中描述的Observer和Iterator模式是生产者/消费者方案中使用的两种模式。 只要迭代器模式实现可迭代的接口,它通常就可以从对象集合中提取数据。 这是一个同步和交互的过程,我正在读取当前值并要求下一个值,直到满意为止或收集结束。 观察者模式用于推送数据,对数据感兴趣的对象将在可用时订阅接收数据。 这是异步的,是无功的,当新数据可供订户使用时,他们会收到数据通知。 ReactiveX探索的是这两种模式之间的对应关系,并统一它们之间的语义(观察者对迭代器是双重的)。 事件,任何地方的事件… “ Rx是功能世界和命令世界之间的最佳结合点。 它使您能够使用不可变的定义和纯函数以可靠的可组合方式处理可变状态的快照。” Rx定义了Observable,Observable是一系列元素的序列,可轻松组合异步操作和事件/数据流。 Rx允许我们创建事件/数据流,并使用运算符进行组合和转换。 有一些运算符,例如filter,map,combin,retry,observ,bindTo,zip,throttle。 所有操作员的列表在此处提供:操作员列表。 您还可以订阅任何可观察的流以执行副作用。 Rx在无状态架构下运行良好,数据不需要实际存储在任何地方,它可以从一个系统传递到另一个系统,并应用从纯函数进行的不同转换,即从流转换为另一个流。 例 在此示例中,我们在GitHub上进行搜索,该示例取自RxSwift。 让searchResults = searchBar.rx.text.orEmpty .throttle(0.3,Scheduler:MainScheduler.instance) .distinctUntilChanged() .flatMapLatest {查询-> Observable 在 如果query.isEmpty { 返回.just([]) } 返回搜索GitHub(查询) .catchErrorJustReturn([]) } .observeOn(MainScheduler.instance) 我们通过searchBar文本在主线程上创建一个可观察的对象。 为了避免每次文本更改时都发出请求,请限制此流。 流仅在文本实际更改时发送事件。 我们总是会收到用户输入的最新文本,如果文本不为空,我们会发出搜索请求。 我们可以将此搜索结果绑定到表格视图,以显示用户更新搜索时得到的结果。 搜索结果 .bindTo(tableView.rx.items(cellIdentifier:“ Cell”)){ (索引,存储库:存储库,单元格)在 cell.textLabel?.text = repository.name cell.detailTextLabel?.text = […]

带有RxSwift的MVVM:用户登录

您是否厌倦了使用相同的旧MVC架构模式来开发iOS应用程序,并且足够开放以尝试新的模式,所以嘿! 你是在正确的地方。 注意 :如果您不知道RxSwift是什么,那么我建议您通读我以前的文章,它将带您了解RxSwift的一些非常基础的知识,以便您对我在本文中要解释的代码感到满意。 RxSwift:观察运算符✅ 如果您来自编程背景或具有某种专业知识,那么您一定一定会遇到…… medium.com 现在,我假设您对RxSwift的功能以及如何使用它有一些基本的了解。 因此,现在继续前进,在深入研究一些编码之前,请先讨论MVVM(模型-视图-ViewModel)体系结构。 MVVM与MVC非常相似。 它描绘了视图和控制器的紧密耦合本质,并引入了一个新组件。 在MVVM下,View和ViewController彼此紧密相连,我们将它们视为一体。 视图仍然没有直接引用模型,控制器也没有。 相反,他们引用了新组件ViewModel 。 ViewModel 是放置您所有用于用户输入的验证逻辑,用于视图的呈现逻辑,任何网络请求的发起以及其他各种代码的绝佳场所。 不属于ViewModel的一件事是对视图本身的任何直接引用。 ViewModel中的逻辑在iOS上应与在OS X上一样适用。(换句话说,不要在视图模型中#import UIKit.h,就可以了。) 由于表示逻辑(如将模型值映射到格式化的字符串)属于ViewModel,因此ViewController本身变得far肿得多,代码行数少了。 最好的部分是,当您开始使用MVVM时,您只能在ViewModel中放置少量代码逻辑,当您对范式更加满意时,可以将更多的代码逻辑迁移到它们上。 使用MVVM编写的iOS应用程序具有很高的可测试性。 由于视图模型包含所有表示逻辑并且不引用视图,因此可以通过编程对其进行全面测试。 从理论上讲,现在是时候让我们掌握一些代码示例了,这将使您快速了解如何有效实施MVVM。 LoginModel是一个存储登录凭据(即用户名和密码)的类。 LoginViewModel: 这是主要的ViewModel,它实际上处理Login视图上的所有用户交互。 在这里,我们创建了密码和电子邮件视图模型的实例,还定义了可观察对象,即将 变量绑定为 isSuccess,isLoading,errorMsg ,并将其绑定到视图以进行响应数据更改。 在validateCrentials()函数中,我们实际上通过调用相应的ViewModel函数来比较字段值。 最后, loginUser()使用值初始化模型,然后创建对包含电子邮件,密码的api的请求,最后启动API请求。 无论是成功还是失败响应,我们都会更新我们之前在案例中定义的可观察对象isLoading,isSuccess,errorMessage ,它们使用绑定立即反映在视图中,从而使其具有反应性。 现在,最后我们进入视图,即ViewController,其中ViewModel以反应方式反映数据。 在createViewModelBinding函数中,我们将电子邮件和密码字段与各自的ViewModel的数据变量绑定在一起,简而言之,将文本字段的文本和数据变量值保持同步。 因此,当电子邮件文本字段的值更改时,数据变量值也会更改。 登录按钮的点击监听器首先通过self.emailTextField.resignFirstResponder()关闭键盘,然后验证凭据并相应地调用loginUser函数进行处理。 在createCallbacks函数中,我们订阅了isSuccess和errorMsg可观察的对象,因此,如果其值发生任何更改,我们都将在View中进行回调,并可以执行该过程。 到此为止,希望您能从中学到一些有用的东西。 因此,如果您有任何想法和意见,请随时在下面发表评论。 别忘了通过多次鼓掌来分享您的爱。 您可以在 Twitter,Github,LinkedIn,Facebook 上关注我 。 快乐编码👨‍💻。

Swift Talk:使用RxSwift的高级MVVM [第5集] UITableView绑定

在RxSwift的热身剧集中,我们介绍了使用RxSwift和RxCocoa的UITableView绑定,这将导致删除大量样板代码和从ViewModel到ViewController的委托。 反过来,这会使整体代码更简洁,更清晰。 你还在等什么? 使用RxSwift观看MVVM的最新一集。 观看其他TOP编程教程,网址为: 轻松编写代码 来自行业专家的真实经验的视频教程。 Laravel,AngularJS,iOS,Android,NodeJS… youtube.com 请关注我们: http://letscodeeasy.com www.facebook.com/letscodeeasy https://twitter.com/letscodeeasy

Rx中的反应式编程

首先,我当然建议您阅读官方文档。 在那里,您可以找到RxSwift运算符的基础知识。 本质上,在RxSwift中,所有事物都是围绕可观察对象构造的。 根据其名称,您可能会猜测我们将在整个程序中观察到此类对象的变化。 特别是,这些对象将通知您有关其状态的更改。 此外,我们拥有执行任何必要动作的能力,这些动作将改变返回的对象(过滤器,地图,flatMap等)。 因此,完整的工作流程如下所示:使用某些功能创建一个可观察对象。 例如,一个内部包含单个参数并返回可观察对象的对象。 此外,还有大量其他变体。 您可以在文档中检查它们。 使用不同的运算符(如果状态已更改)描述其行为。 例如,为了在特定条件下获取结果而进行过滤,或者设置一个线程来运行结果代码。 为每个状态(下一步,完成,错误)设置处理程序(如果需要)。 订阅-从现在开始通知观察者我们希望获得其通知。 此代码说明了订阅某些可观察对象的示例。 魔鬼并不像他画的那么黑,所以不要害怕。 该示例非常简单,因此我们将尝试逐步解释它。 您可以在文档中轻松找到所有未知方法。 首先,我们将创建一个OperationQueue。 这个阶段对您来说并不难。 现在,让我们深入探讨其他复杂的问题。 BackgroundWorkScheduler描述了用于从队列的后台执行操作的线程。 下一部分很有趣。 有些对象可以上传视频,我们将订阅其更改。 应该在后台线程上进行工作的设置,我们将在该线程上处理初始结果。 使用“ map”方法转换对象以使其成为字符串。 在主线程中开始工作,以进行UI工作 “设置”,处理下一个状态的功能。 实际上,我们在下面的几行中执行了所有这些操作。 让operationQueue = NSOperationQueue() operationQueue.maxConcurrentOperationCount = 3 operationQueue.qualityOfService = NSQualityOfService.UserInitiated 让backgroundWorkScheduler = OperationQueueScheduler(operationQueue:operationQueue) videoUpload .observeOn(backgroundWorkScheduler) .map({json in 返回json [“ videoUrl”]。stringValue }) .observeOn(MainScheduler.sharedInstance) .subscribeNext {网址 self.urlLabel.text =网址 […]

RxSwift:Mengawasi可观察属性di Semua元素数组Secara Bersamaan dengan Observable.combineLatest()

Judul yang panjang,塔皮萨达提达克menemukan judul yang lebih baik untuk pikirkan oleh程序员pemula dengan kasus yang sama kecuali关键字di atas。 Jadi saya berharap dengan judul yang panjang namun jelas maka tujuan dari artikel ini telah didefinisikan sejak awal。 >简洁明了 就像Swift的方式一样! Kasus: Seperti yang saya katakan tadi,Kasussaya dapat disimpulkan oleh judul dengan cepat。 可以观察到Saya memiliki数组dari sebuah objek yang memiliki属性。 丹·赛亚·英金·琼脂·塞蒂亚普·佩鲁巴汉·达里·特雷塞普·阿塞·迪·塞巴坎·科塞蒂亚普的观察员yang […]

使用RxSwift和ViewModel进行TableView搜索

让我们使用结合了MVVM的RxSwift做一些繁重的工作。 使用UISearchController进行TableView搜索,并使用ViewModel中的Variable绑定搜索文本。 我说过重吗? 我们没有这样做,RxSwift却这样做。 了解过滤后的数组如何与源数组绑定,进而以最少的代码即时更新tableview。 如果您喜欢这些教程的质量,请喜欢,订阅和分享。 请观看以下链接提供的所有剧集: 第1集-https://youtu.be/fH9paWpCvQsEpisode 2- https://youtu.be/qLbUzwZrQjcEpisode 3 — https://youtu.be/qLbUzwZrQjcEpisode 4 — https://youtu.be/b1GadsUtB9s第5集- https://youtu.be/EZtCOQyRK7w第6集- https://youtu.be/T0yT6J_Mp9UE第7章- https://youtu.be/ur-U9nzazbc 观看其他TOP编程教程,网址为: youtube.com/c/letscodeeasy 请关注我们: http://letscodeeasy.com www.facebook.com/letscodeeasy https://twitter.com/letscodeeasy