Tag: Rxswift

RxSwift:Swift中的反应式编程

RxSwift是iOS的反应式编程库。 它使对响应应用程序中的数据更改和用户事件的动态应用程序进行编程变得容易。 为什么使用它: 多平台 简化多线程 可比较的组件。 清洁代码与架构 因为您可以用一种优雅的方式处理异步问题。 因为您可以编写更好,更简洁的代码,并创建可以在健壮的代码库中重用的组件,所以这些代码库可以不断发展。 缺点: 一开始,学习过程可能会令人生畏–没有一篇文章可以教您RxSwift 内存管理问题-如果您不小心闭包内部的自引用,很容易造成内存泄漏 考虑到堆栈跟踪要大得多,调试可能很难 最后的话: 选择应用程序的隔离部分,然后将其迁移到反应式 支持MVVM和MVC的最佳架构 为什么要使用RxSwift? : 因为您可以用一种优雅的方式处理异步问题。 因为您可以编写更好,更简洁的代码,并创建可以在健壮的代码库中重用的组件,所以这些代码库可以不断发展。 您应该一直使用它吗? 作为任何工具,如果适合,则应使用它。 考虑您的团队知识,背景,时间表,并尝试做出有根据的决定。 从长远来看,我认为值得付出努力。 阅读更多:https://medium.com/@leandromperez/why-use-rxswift-a176b553a705 建议〜慢点RxSwift : 将RxSwift应用于项目时,不要全力以赴。 选择应用程序的隔离部分,将其迁移到响应式,然后权衡此新方法的优点,区别,优点和缺点。 阅读更多:https://techbeacon.com/reactive-programming-rxswift-how-get-started

RxSwift:对变量的BehaviorRelay

由于RxSwift,全球许多iOS开发人员都使用了Reactive编程。 而且,如果您也使用它,那么您将习惯于编写Variables 。 好吧,我最近了解到,这个广受欢迎的BehaviorSubject包装器已经过时了。 此折旧尚处于初期阶段,目前不会发出任何警告。 但是,该路径已经布置好了,并且选择了其后继者: BehaviorRelay 。 为什么? 根据Krunoslav Zaher的说法,出于许多有关Variables的原因: 它不是标准的跨平台概念,因此在RxSwift目标中不合适。 它没有事件管理的可扩展副本( PublishRelay )。 它仅对状态建模。 它的命名与*Relay不一致 与RxSwift的其他部分相比,它的内存管理模型不一致(在dealloc上完成) 那么这对我们的代码意味着什么呢? 好吧,这: 可变方式 现在变成: 行为中继方式 但是,完成这一迁移是最后一步。 实际上, BehaviorRelay位于RxCocoa中 ,因此需要import 。 但是,将导入添加到不需要应用程序相关组件的应用程序的低层中似乎有点奇怪。 Zaher先生在此问题中提出了这个问题,并建议“将*Relay和SharedSequence提取到自己的框架中”。 整个冒险过程应该在RxSwift的下一个主要版本中结束。 *Relay类是RxSwift 4引入的。与BehaviorSubject不同,该ObservableType不能因错误或完成而终止。 您可以在Minh Vu Nhat的这篇文章中阅读有关它们的更多信息。 到底 我亲自做出了决定,现在,它是Koolicar的iOS行业协会的标准,可以在不延迟编写新代码的情况下使用BehaviorRelay 。 由于已确定弃用,因此我认为使用此全新代码缓慢开始过渡很有用。 同时,我尝试迁移我在任务中可能且安全的情况下遇到的Variables (如果合适)。 这个想法是试图尽可能地平滑过渡。 最后,我不耐烦地等待BehaviorRelay位置的最终答案。 我想从独立于UIKit的实体中删除RxCocoa 。 2018年9月17日,星期一: RxSwift开发人员昨天发布了其4.3.0“RotWeiß”版本。 自从Playgrounds,示例项目和测试中删除Variable的用法以来,对Variable的弃用一直在进行。

带标签栏控制器的RxSwift

今天,我们将讨论如何在Tab Bar Controlled应用程序中实现RxSwift,并了解响应式编程的魔力🙂 我将尝试尽可能详细地解释RxSwift的基础。 让我们转到RxSwift的github repo并将其安装在我们的应用程序中。 我将项目命名为RxSwiftExample,并且将使用cocoapods将其安装为: #取消注释下一行以定义项目的全局平台 #platform:ios,’9.0’target’RxSwiftExample’做 #如果您不使用Swift并且不想使用动态框架,请注释下一行 use_frameworks! pod’RxSwift’,’〜> 4.0′ pod’RxCocoa’,’〜> 4.0′ #RxSwiftExampleend的广告连播 现在转到情节提要,然后将ViewController嵌入到选项卡栏控制器中。 然后将另一个ViewController添加到场景中。 控制从选项卡栏控制器拖动到新的vc,并将关系设置为视图控制器。 然后为标签栏项目提供一些随机项目,以便可以在标签栏中进行区分。 (我将使用“更多”和“搜索”标签栏项目) 到目前为止,您的情节提要应该看起来像这样: 创建一个UIViewController的可可触摸类,并将其命名为UserViewController.swift,并在情节提要中将新的vc的Class设置为UserViewController。 由于本文将主要关注RxSwift,因此我不会花太多时间来解释UI组件,约束等。 然后从对象库中拖动一个表视图并插入到User vc中,为其赋予0–0–0–0约束。 然后转到属性检查器,并给其提供原型单元格,其标识符为“单元格”。 控制从tableView拖动到vc,并设置其数据源和委托属性。 打开助手编辑器,然后将控件从表视图拖动到UserViewController.swift并作为tableView进行引用。 然后在第一个vc中添加三个标签,对其施加一些约束,打开助手编辑器,并从情节提要中获取对nameController,ageLabel,cityLabel的引用,以指向故事板。 现在该创建模型了。 创建一个名为User的快捷文件,然后复制下面的代码。 现在该使我们的应用程序更有趣了。 转到您的UserViewController并在课程开始时在下面声明变量 var userToShowInFirstVc =变量(用户(名称:“ Alex”,年龄:25,城市:“慕尼黑”))var userToShowInFirstVcObservable:Observable { 返回userToShowInFirstVc.asObservable() } var userArray =变量([User]())var userArrayObservable:Observable { 返回userArray.asObservable() } 在这里,我们创建了两个变量及其可观察对象,分别为userToShowInFirstVC和userArray,第一个是用户变量,我们将在第一个vc中显示其详细信息。 我们以用户Alex作为占位符用户开始。 userArray是由Users组成的数组。 我们将使用来自userArray的用户填充tableView。 让我们创建一个将Users添加到我们的userArray的方法: 由于我们的userArray也是RxSwift变量,因此当我们想要进行更改或获取其引用时,我们需要以userArray.value的形式获取它的值。 […]

测试可观察的dengan RxTest

Setelah merefresh bagaimana caranya memakai RxSwift untuk keperluan开发iOS,supaya tidak lupa dan空白。 Saya sekalian aja belajar bagaimana melakukan testing可观察的memakai RxTest。 在UICollectionView中无限滚动UICollectionView UIAPIView的内容,并在API API dari Pokeapi中显示。 Jadi,Yang akan di test,apakah data pada集合视图akan bertambah sebanyak 20项目,setiap menyentuh akhir dari UICollectionView 。 Misalkan saya punya视图模型sederhana seperti ini 拜克拉(Baiklah),北穆莱(kula mulai)buat kasus ujinya dulu,塞德拉(sederhana saja)… 事件:-(0,())-(100,())-(150,())-(200,())-(250,())—>预期结果:5 * 20项= 100项 好吧,bagaimana langkah […]

使用RxSwift时应避免的8个错误​​-第1部分

细节可能会有所不同,但是不管您的观察对象,观察者或订阅如何,基本含义都保持订阅的含义。 要发现的关键是,忽略参考周期管理器 (又称disposable ,可以使您摆脱自己破坏参考周期的可能性。 它是进入内存配置的门户药物,一旦无法使用,就再也没有回头路了。 如果使用_ =语法,则基本上可以说,释放observable observer和observer的唯一方法是完成可观察序列。 有时候这可能正是您想要的! 例如,如果您要调用Observable.just ,则不必确保打破周期,这并不重要。 单个元素被瞬时发出,随后是.completed事件。 但是,在许多情况下,您可能无法完全确定所讨论的可观察性的完成可能性: 您从另一个对象获得了Observable ,文档没有说明它是否完成, 您从另一个对象获得了Observable ,并且文档确实说明该对象已完成,但是在此过程中该对象的内部实现发生了一些变化,没有人记得要更新文档, Observable明显未完成(示例包括Variable , Observable.interval ,subject), 可观察的实现中存在错误,例如忘记在Observable.create闭包中发送.completed事件。 由于您几乎无法控制应用程序中的所有可观察对象,即使那样也有可能出错,因此经验法则是确保自己打破参考周期。 要么保留对disposable的引用,并在时间到时调用.dispose()方法,要么使用方便的助手(例如DisposeBag来帮您完成。 您还可以使用.takeUntil运算符提供一个单独的可观察到的循环中断。 选择哪种方式取决于您的具体情况,但请始终记住: 既然我们已经解决了所有问题,我觉得我欠您一点解释。 我上面绘制的心理模型很好,这是一种心理模型,因此并不严格正确。 当前的RxSwift实现(在撰写本文时版本3.x / 4.x)发生了一些复杂的事情。 要了解实际行为,让我们更深入地研究RxSwift内部。 在哪里实现subscribe方法? 毫无疑问,搜索的第一位将是ObservableType.swift文件。 它包含订阅方法的声明,作为ObservableType协议的一部分: func subscribe( _ observer: O ) -> Disposable where OE == E 什么实现了此协议? 基本上,所有各种类型的可观察物。 让我们集中讨论称为Observable的主要实现,因为它是RxSwift中定义的所有可观察对象(除了其中之一)的基类。 其subscribe方法版本简短而简单: public func subscribe( _ […]

RxFlow第1部分:理论上

RxFlow是基于Reactive Flow Coordinator模式的iOS应用程序导航框架。 该项目是RxSwiftCommunity组织的一部分。 这三篇文章对它的详细概念进行了解释: RxFlow第1部分:理论上 RxFlow第2部分:实践中 RxFlow第3部分:提示和技巧 这是Github存储库:https://github.com/RxSwiftCommunity/RxFlow 感谢您的反馈,随时可以贡献contribute 我将介绍RxFlow :我的设计框架,在iOS应用程序中实现了Reactive Flow Coordinator。 RxFlow是RxSwiftCommunity支持的项目。 关于iOS应用程序中的导航,有两种选择: 使用Apple和Xcode提供的内置机制:Storyboard和Segues 直接在代码中实现自定义机制 这两种解决方案的缺点: 内置机制:导航是相对静态的,并且情节提要非常庞大。 导航代码污染了UIViewControllers 自定义机制:根据所选的设计模式(路由器,协调器),代码可能难以设置并且可能很复杂 RxFlow旨在: 促进将故事板切割成原子单元,以实现协作和UIViewControllers的可重用性 允许根据导航上下文以不同方式呈现UIViewController 简化依赖注入的实现 从UIViewControllers删除任何导航机制 促进反应式编程 在处理大多数导航案例的同时,以声明的方式表示导航 促进将应用程序切成逻辑导航块 从情节提要到协调器模式 随着我作为iOS开发人员(以及Android或Web应用程序开发人员)的经验的增长,我一直面临着有关导航的同样疑问。 对于所有其他概念问题,有很多模式可以解决常见的体系结构问题和关注点需求分离(MVC,MVP,MVVM,VIPER等)。 但是,一旦设计导航,我就被撕碎了: 如何在Storyboard / Segues中使用依赖项注入? 如何控制应用程序的流程? 如何摆脱UIViewControllers中的导航样板代码? 随着时间的流逝,我对iOS应用程序的构想从带有一个Storyboard的MVC到带有多个Storyboard的MVC,最终达到了我们可以称为当今最佳实践之一:带有Flow Coordinator的 MVVM。 这非常好,因为我们可以玩依赖注入,UIViewControllers可重用性和可测试性。 我有机会将这种模式应用于生产中的大型复杂应用程序。 但是最后,仍然有一些问题困扰着我: 我总是不得不一次又一次地编写协调器模式, 有很多委派模式用于允许ViewModel与协调器进行回通讯。 我开始研究Redux模式,尤其是导航状态机制。 我们可能有一个全局导航状态,该状态通过RxSwift Observables公开,并且有人在监听此状态并驱动导航。 我发现唯一令人不安的是这种导航状态的独特性以及它可能具有的不受控制的责任(以及它可以存储的海量数据) 导航只是一种状态的反射,这种状态可以逐步修改的想法开始出现。 一种状态,将散布在整个应用程序结构中,而不是存储在单个位置中,而是由观察者统一起来,可以对它作出反应并因此驱动导航。 在本文的后面,这些散布在应用程序中的小状态称为“ 步骤” […]

具有纹理的模型视图意图

ASRenderModelProtocol和ASRenderModelIdentifier是用于在ASModelSyncronizer上标识模型的便捷ID对象和协议。 ASModelSyncronizer是基于模型唯一标识符的模型管理器。 它与线程安全性在后台调度程序上并发工作 您可以在基本模型对象上继承ASRenderModelProtocol 你应该做一些这样的业务逻辑 我说过我的目标是,必须在Node初始化完成之前初始化所有子节点属性。 GeekTree0101 / RxMVVM-纹理 RxMVVM纹理– RxSwift MVVM模式最佳实践,建立在Texture(AsyncDisplayKit)上,并用Swift编写 github.com 在大型仓库中,您可以看到alll子节点是异步初始化的。 即使在超级节点完成其初始化之后,所有子节点也不知道其属性值已被自己初始化。 首先,意图将使用模型初始化 接下来,意图应该与业务逻辑一起订阅(突变关闭) 变异是业务逻辑的封闭 update(to :)是更新目标视图属性,表示输出 interact(from :)表示输入 如果需要在绑定值之后更新布局。 然后在update(to 🙂 setNeedsLayout参数上插入更新目标节点。 您可以从上图看到在节点初始化之前初始化的所有子节点属性都已完成。 用户将触摸个人资料图片。 届时,个人资料视图将发出点击事件 配置文件点击事件将调用从后端服务下载图像 3. ASModelSyncronizer将使用业务逻辑自动更新所有已识别的用户模型。 [1〜2]用户交互>发出>目的 [2〜3]意图>后端服务 [3〜4]后端服务>更新模型的突变关闭 [4〜5]变异>模型更新 [5〜6]模型>突变关闭以进行更新视图 GeekTree0101 / Rx可可纹理 RxCocoa纹理– RxCocoa纹理扩展库。 github.com

Dyno版本:AWS,Swifter

上一次,我们做了很多设置以开始使用Amazon Web Services的DynamoDB ,包括使用Swift-Python桥,以便我们可以使用官方的AWS接口boto3与DynamoDB进行通信。 但是boto3除了基于Python并因此没有Swift类型安全性之外,还具有一些局限性:它很复杂,难以使用—并且存在同步的主要问题。 要查看该问题,请运行上次到达的代码: …现在,请尝试关闭计算机的WiFi ,然后重新运行。 怎么了? table.scan()行仅挂起那里30秒钟,直到出现令人讨厌的异常并且程序崩溃(带有不可恢复的致命错误)。 实际上,这不是我们希望库调用或可能具有间歇性网络连接的应用程序(例如移动应用程序¹)所期望的行为。 本文-更好的boto Dyno库旨在做得更好。在本文中,我们将介绍如何做! 和以前一样,尽管这个想法是产生一个有用的库,但我也希望展示可以在自己的代码中使用的技术。 我们将使boto3调用异步。 这将演示信号量,工作队列和工作项的使用 Dyno将利用新的Swift 5 Result类型发布一个Observable结果流。 在这里,我们将演示带有复杂数据流的Observable和Reactive编程 我们将添加一些有用的,类型安全的方法来从DynamoDb(原生于Swift)读取和写入数据。 这说明了 我们数据类型上的 一些出色的功能构造,例如 zip 和 flatMap 在本文的最后,我们将直接从Swift将Dinosaurs(当然是🦕和))写到DynamoDB数据库中,然后以异步方式读回它们,并适当考虑网络延迟。 这将成为我们Dyno库的开始。 和以前一样,该库正在公开开发中,因此您可以在github( swiftify分支)上查看源代码。 有很多事情要做,让我们开始吧! 可观察的流 正如我在上一篇文章中提到的,可观察对象是表示数据流的一种方式。 我们可以将它们连接到Reactive组件,以便能够以功能强大和声明性的方式处理数据流。 这是表示数据操作的一种非常强大的方法-我们将在以后的文章中介绍,但是现在我们将看看如何将DynamoDB交互表示为Observable。 建模数据交互的关键是要注意它们都看起来像这样: 要求DynamoDB做某事(扫描表,更新行等) 等待结果(返回200行,更新成功)… 或出现错误,例如 超时或数据完整性错误。 我们使用DynoActivity数据类型的可观察流对这些阶段进行DynoActivity : 它就像一串可观察的事物(橙色和红色的大理石代表可观察的事件)看起来像这样: 现在,我们要做的一件事是假设即使一次大型查询(例如,返回了数百行),我们也一次性获得了所有数据:我们不对输出进行“分页”。 我们将来可能会改变它²。 您可能还会注意到,我们希望我们的可观察流以多线程的方式异步工作:我们可以让多个流同时运行,有的读取数据,有的写入。 为什么我们不将Future用于这种类型的异步数据请求/响应? 使用Observable流可以非常轻松地处理诸如“显示等待图标,直到返回数据或显示错误”之类的交互模式。 对于实际应用而言,这是非常基本的。 现实检查 在创建高级Observable之前,我们需要处理以下事实:通过不可靠的连接与远程数据库进行同步接口,并使用Python接口进行引导。 具体来说,我们需要确保Dyno正在控制AWS连接上的活动,而不是将其留给Boto3的30秒同步,程序终止超时。 那么,如何在不自行控制Boto3代码的情况下使Boto3异步和多线程呢? 我们将使用DispatchSemaphores […]

RxSwift和可变参数DisposeBag的秘密

使用RxSwift的最新功能之一来显着清理代码 我的公司已经将RxSwift用于所有新的iOS项目已有一段时间了,我们开始欣赏它的强大功能,灵活性和简洁性。 就是说,我们可以说RxSwift在一个区域不那么简洁。 实际上,这是完全多余的。 所以今天,让我们谈谈Disposables和DisposeBags。 一次性用品和DisposeBags? 如您所知,Disposables和DisposeBags是RxSwift对Swift的ARC内存管理的让步。 当您订阅或绑定到RxSwift Observable或从RxSwift Observable驱动时,该订阅将返回Disposable。 一次性使用基本上是对该订阅以及该订阅的整个Observable链的引用。 在处置该一次性物品之前,订阅链一直存在(除非订阅收到完成事件或错误事件,但这是另外一回事了)。 所以。 最重要的是,订阅会返回我们需要维护的一次性物品,以便正确控制订阅的生命周期。 为了方便起见,这些一次性物品通常插入已创建的DisposeBag中,并附加到UIViewController(或在某些情况下附加到View Model或其他对象)。 一个DisposeBag就是它所说的,一袋(或一组)一次性用品。 那对我们有什么帮助呢? 好了,当视图控制器被释放时,其变量(包括bag)将被释放。 释放disposeBag时,其deinit函数将对其包含的所有一次性用品调用dispose。 那些可抛弃型对象继而释放它们可能要参考的任何可观测对象的引用,也可能继而释放其对观测对象的引用,依此类推,等等,直至完成。 一切都已正确释放,没有泄漏,每个人都很高兴。 除了一个小问题。 冗余 因此,假设您使用的是RxSwift,而您使用的是MVVM(模型-视图-视图模型)体系结构。 在此特定屏幕上,我们的视图模型将公开一组可观察对象,而我们的视图控制器会将这些可观察对象绑定到一组标签。 很基本的东西。 代码看起来像这样。 一切都非常简单,但是也许您在上面的示例中注意到了一些多余的样板代码? 那就对了。 每个订阅(绑定)都返回一个一次性对象,必须将其添加到disposeBag中。 每个人返回它。 并且每个人都必须维护。 没有解决的办法。 还是在那里? 解? 可变参数的处理袋 现在检查以下代码。 干净得多! 但是所有一次性用品都发生了什么? 好吧,RxSwift 4.3添加了DisposeBag的insert函数的可变版本。 可变参数可以使用一个或多个参数。 在这种情况下,一个或多个一次性用品。 因为如果您看内部dispose(by:disposeBag),您会发现它只是一行代码:disposeBag.insert(self)。 因此,我们无需获取每个订阅的结果并将其功能性地链接到Dispose(by :),而是绕过中间人并将每个人直接添加到disposeBag中。 我想您会同意代码绝对更加简洁,并且通过消除一些样板代码,我们可以更好地表达该功能的意图。 请享用。 顺便说一句,如果您发现DisposeBag上的可变参数插入很有用,欢迎您。 这是我对RxSwift项目的次要贡献之一。 😉

在Swift(2)中使用UITableView-与RxSwift

正如我们在上一篇文章中介绍了UITableView的基本用法之后,这次我们将将该示例转换为一个使用RxSwift处理UITableView 。 RxSwift是一个更高级的主题。 请注意,这个故事仅演示了基础知识,但是可以肯定的是,如果广泛且正确地使用它,它可以将您和您的应用程序提升到另一个层次。 本教程的源代码可在Github上获得。 我们将从创建另一个安装了Cocoapods和RxSwift Xcode项目开始。 $ pod init 将RxSwift添加到Podfile 。 …#UITableView吊舱“ RxSwift”的吊舱 豆荚“ RxCocoa” … 安装pod并打开UITableView.xcworkspace 。 $ pod安装 初始设置 首先通过在UIViewController导入RxSwift和RxCocoa ,然后我们可以将代码转换为Rx样式。 导入RxSwift 进口RxCocoa 这次,我们还需要在UITableView通过以下JSON显示数据。 // travel.json [ { “名称”:“香港”, “ desc”:“我住的地方。”, “ url”:“ https://zh.wikipedia.org/wiki/香港 }, { “名称”:“新加坡”, “ desc”:“一个干净整洁的地方。”, “ url”:“ https://zh.wikipedia.org/wiki/新加坡” }, { “ name”:“ Japan”, “ desc”:“喜欢那些美味的寿司和生鱼片。”, “ url”:“ https://zh.wikipedia.org/wiki/日本” […]