Tag: Rxswift

RxSwift的基础

Xcode入门 创建一个新的Single-View Application项目,然后打开ViewController.swift 。 我们将在viewDidLoad中添加一个属性和一些代码。 使用CocoaPods或其他软件包管理器将框架添加到项目中后,请确保导入RxSwift 。 数据存在的地方 变数 在这里,我们创建了一个属性,该属性将为我们的开关保留一个布尔值 。 我们使用一个变量 ,其通用值Bool分配为true作为默认值。 要访问或更改布尔值,我们必须使用viewDidLoad中所示的变量的value属性。 可观察的 从名为switchState的变量中 ,我们可以创建一个可观察的对象。 一个Observable侦听状态以更改为新值或相同值(或事件)。 让我们看看接下来可以使用Observable做什么: 过滤 当我们使用。 对我们的可观察对象进行过滤 ,我们给它传递一个闭包,如果闭包返回false,则可观察对象将忽略此事件。 地图 使用 。 map将允许我们将Bool转换为所需的任何类型。 在这种情况下,我们将Bool映射到一个更好地表示我们状态的字符串 。 也许现在我们可以在标签上向用户显示此字符串 。 到目前为止我们所拥有的 在viewDidLoad中 ,我们创建一个observable,并应用一个filter , distingtUntilChanged和map操作来获取titledObservable的最终observable。 由于我们只需要一个可观察的对象,因此我们可以将代码重构为如下所示: 链接每个操作可以使我们更加简洁。 聆听数据更改 订阅可观察的 在我们的viewDidLoad中 ,添加以下内容。 这是我们侦听可观察事件以发送事件的方式。 在我们的案例中,我们正在监听switchObservable的更改,因此我们可以将labelToday.text更新为newValue 。 订阅可观察对象时,您可以收听不同的事件。 但是,这里我们正在监听onNext事件。 处理袋 处理袋用于将类似ARC的行为返回给RX。 当DisposeBag被释放时,它将在每个添加的一次性物品上调用dispose。 每当您订阅可观察对象时,此订阅方法都会返回Disposable对象。 这对内存管理很重要。 那么,您如何处理一次性用品? 查看以下代码: 在我们的ViewController中 […]

iOS开发:The Woost Way™

在Woost,我们的承诺是在一个月内生产出最低可行的产品。 我们相信(几乎)每个新概念的核心都可以在该时间范围内构建。 我们帮助我们的客户找到核心,定义目标和假设,并缩小范围,直到一个月之内即可完成开发。 我们为网络(响应式)和移动(本地Android,本地iOS)构建。 为了能够加快速度并快速交付,我们拥有用于大多数项目的标准工具集和标准项目设置。 在本文中,我将向您介绍我们用于iOS项目的内容。 当然,随着每天都会出现新的最佳实践和新框架,这可能会发生变化。 警告:技术性越来越强😉 可可豆 其他人已经做了很多工作。 如果您知道如何珍惜他人*的工作,则可以节省大量时间,并避免通过使用轮子来重新发明轮子。 *: 这个很重要! 您应用的性能和稳定性至关重要。 CocoaPods是Swift和Obj-C项目的程序包/依赖性管理器。 您可以将CocoaPods集成到项目中,以轻松添加,删除或更新外部软件包。 我们主要使用CocoaPods,有时使用Carthage,但发现前者更易于使用。 我们或多或少的标准Podfile看起来像这样,已经使您了解了我们使用的工具: 吊舱“ RxSwift” 豆荚“ RxCocoa” pod’SwiftyJSON’ 吊舱“翠鸟” pod’PureLayout’ 吊舱“ R.swift” 豆荚“面料” pod’Crashlytics’ pod’Firebase / Analytics’#或’GoogleAnalytics’ 在设置Pod时,请确保还检查gitignore.io来创建一个漂亮的.gitignore模板! 我们通常从这一点开始。 接收 RxSwift是ReactiveX for Swift的一个版本(RxCocoa通过Reactive magic扩展了Cocoa API)。 ReactiveX简化了异步调用(避免了回调地狱 ),使代码更具功能性,可读性且不易出错。 我们主要将其用于API调用和用户界面绑定。 有关为什么使用Rx的更多信息,请查看RxSwift不错的页面。 Ray Wenderlich有一个很好的Rx入门教程。 SwiftyJSON 尽管Swift对JSON有一些基本的了解,但是使用SwiftyJSON可以使代码更整洁,类型更强,代码更短,更好理解。 翠鸟 有很多用于缓存图像的库,但是我们发现Kingfisher是最简单,最方便的使用方法。 PureLayout AutoLayout在情节提要板上可以很好地工作,但是如果您想在代码中添加布局约束,则原始API相当冗长且难以阅读。 PureLayout是一个很好的API,可以解决此问题。 凭借其方便的类型推断,尤其是使用Swift的短点语法,PureLayout的工作非常简洁。 SnapKit是一个不错的选择,我们尚未尝试。 […]

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

在博客文章的第二部分中,我们将应用ReactiveX以便使用RxSwift创建示例iOS应用程序。 在第一部分中,我们探索其背后的理论以了解RxSwift,特别是ReactiveX。 您可以在此处签出第一部分。 我们将要构建的应用程序是电话目录。 该应用程序包含一个表,该表包含用户添加的所有联系人。 它还使用户可以添加新联系人。 我们使用RxSwift更新界面,同时在每个用户输入处验证联系人。 我们还应用了RxSwift来绑定我们的模型(联系人列表),并在表格中显示它们。 您可以在此处检查最终结果: 如您所见,当我们输入输入内容时,标签会更新存在的剩余错误并启用/禁用“保存”按钮。 为了获得此结果,我们为名称文本字段创建了一个可观察值,为数字文本字段创建了一个可观察值。 让名称= nameTextField.rx.text.orEmpty .observeOn(MainScheduler.instance) 让数字= numberTextField.rx.text.orEmpty .observeOn(MainScheduler.instance) 然后,我们将两者结合起来以创建一个Contact Observable。 let contact = Observable.combineLatest(name,number){(name,number)-> Contact in 返回联系人(姓名:姓名,电话号码:号码) } 每次更新此联系人时,我们都会更新用户界面。 contact.subscribe(onNext:{contact in self.updateUI(与:联系人) }) 接触的验证和当前的错误在Observable之外。 您可以在此处查看完整的项目。

使用MVVM和RxSwift构建您的第一个应用程序

简介: 在本文中,我们将分四个部分逐步构建您的第一个Set应用程序。 第一部分将向您介绍MVVM应用程序体系结构。 第二部分将演示SetSDK设置过程。 第三部分将应用MVVM概念来为您的应用程序创建支架。 最后,在第四部分中,我们将使用SetSDK全天实时显示出发地和预计的目的地。 可以从Set Gitlab存储库下载该项目的源代码。 Set SDK允许任何开发人员通过简单的pod install将机器学习和用户行为预测集成到他们自己的应用程序中。 SDK的第一个版本侧重于用户位置,回答了以下问题:他们现在在哪里,下一步要去哪里? 我想提供一个简单的演示应用程序,以演示如何将SDK集成到您自己的项目中以及如何使用SDK的某些功能。 在我讲的时候,我将使用Apple的MVC(模型视图控制器)体系结构,MVVM(模型视图视图模型)和一种启用MVVM的技术(称为RxSwift)来替代它。 第一部分:MVVM概述 关于MVC设计模式为何变得令人头疼的信息很多,尤其是在更复杂的应用程序中。 MVC对视图控制器负有太多责任。 关注点很少。 在下图中,您将看到视图和模型主要只是存在而无需做任何事情,而视图控制器则负责更新和接收来自模型和视图的更新以及所有业务逻辑,数据库访问,联网等。 在复杂的应用程序中,视图控制器可能会增长为成千上万行代码,并且很难维护。 MVVM是对MVC的简单添加,它简化了视图控制器的作用: 对于您应用中的每个屏幕或视图控制器,我们都会引入一个附加文件,即视图模型。 视图模型负责与模型数据进行交互,并将业务逻辑和显示格式应用于该数据。 视图模型还可以利用数据库或网络抽象。 格式化的数据通常通过简单的属性,RxSwift Observable或类似的技术(稍后会详细介绍)提供给应用程序的视图层。 视图控制器的新角色是通常使用RxSwift之类的工具简单地将视图模型公开的数据“绑定”到视图。 视图控制器还处理诸如按钮轻击和手势之类的用户交互,将这些事件通知视图模型。 这样,视图和视图模型紧密耦合,可以视为单个功能单元。 MVVM可以使关注点更加清晰。 它从视图层中删除了业务逻辑和数据格式,并创建了易于通过单元测试进行测试的视图模型。 可以以“无头”方式(没有任何视图)测试许多应用程序,而可以使用更合适的工具(例如Xcode UI测试)来测试视图。 这样就导致了具有更少错误的应用程序,更易于维护。 第二部分 启动SetSDK应用 要启动SetSDK,您将需要应用程序的客户端凭据。 我们目前正在使用一个自助服务开发人员门户网站,您可以在其中创建这些凭据,但是现在发送电子邮件至sander@set.gl,您将通过电子邮件接收凭据。 SetSDK使用Cocoapods分发。 如果您不熟悉它,请访问他们的网站,其中有许多很好的入门指南。 使用File > New > Project… > Single View Application创建一个新的Xcode项目。 我叫我的MVVMSetSDK。 创建项目后,将其关闭并在命令行上导航到项目的根目录。 通过运行pod init初始化Cocoapods。 打开新创建的Podfile进行编辑,并向其中添加SetSDK依赖项: 并提供当我们要求使用他们的位置和运动数据时显示给用户的Info.plist字符串。 […]

使用RxSwift在视图控制器之间进行通信

如果您仍然不确定如何开始使用RxSwift,那么本文适合您。 我已经阅读了很多有关RxSwift的文章,但是从了解理论到实际利用该知识是一条很深的弯路。 在本文中,我们将创建一个使用RxSwift的非常简单的iOS应用程序。 我们将使用RxSwift的概念并将其应用到此应用程序中。 我将跳过RxSwift的基础知识,因为有许多精美的文章对其进行了解释。 作为参考,您可以在这里看看。 这是塞巴斯蒂安·博尔特(Sebastian Boldt)a的一篇可爱的文章。 我们将在此应用程序中采用一个非常基本的方案,即使视图控制器使用RxSwift进行通信。 让我们开始吧… 基本设定 在Xcode中创建一个新项目,并为该项目初始化pod,然后在pod文件中添加以下内容。 替换YOUR_TARGET_NAME ,然后在Podfile目录中键入: $ pod安装 快速转发…。 添加一个新的View控制器(我将其命名为N ewViewController ),以便您的主故事板如下所示: 当您点击更改背景按钮时,它将打开新的视图控制器,而当您点击NewViewController上的任何按钮时,它将更改MainViewController的颜色。 通过已建立的可可模式进行交流 如果您使用已建立的可可模式来构建它,那么下一步将是添加委托模式,以便我们的N ewViewController可以与M ainViewController对话。 通过可观察对象进行通信 打开您的N ewViewController,将以下变量添加到您的视图控制器类中: 在这里,我们创建了一个名为selectedColorSubject的Subject 。 这将发出选定的颜色,并发出一个名为selectedColor的Observable,它公开了可观察的主题。 要了解主题和可观察对象,请参阅 上面 提到的 链接 。 我们将添加一个名为changeColor的函数,当按下任意按钮时,它将负责发出新的颜色值,一旦发出该颜色值,我们应导航回到上一屏幕。 我们的函数如下所示: selectedColorSubject.onNext(color)发出新的颜色值,然后我们向后导航。 确保我们的按钮动作事件调用此函数 现在,我们的视图控制器如下所示: 现在转到我们的mainViewController 在按钮操作事件中添加以下代码 当我们点击changeColorButton时,我们导航到NewViewController 。 如我们所见, NewViewController中的selectedColor变量返回一个 类型Observable,因此我们可以订阅该序列。 这样,可观察对象发出的任何值都可以在我们的MainViewController上捕获。 您可以将其视为简单的KVO。 欢呼!! 我们已经完成了第一个RxSwift驱动的应用程序。 Github上的源代码。

RxSwift世界中的ViewModel

牢记这一点,我想将ViewModel视为一个“黑匣子”,它接受一些UI触发器(按钮点击,表视图选择,文本编辑事件等),其他依赖项(NeworkService,DataBaseService,LocationService)并应用一些Rx运算符(确定业务逻辑)。 然后,从视图模型中,您可以获取转换后的可观察对象,并将其绑定回您的UI以应用您的业务逻辑。 作为示例,我想展示如何实现可搜索数据列表,并在带有搜索栏的表格视图中显示它 假设所有实现模型的人员都要做的就是创建ViewModel和ViewController 因此,让我们定义UI触发器: 搜索触发器(用户可以键入以搜索列表中的数据) 滚动触发器(用户可以滚动以从列表中提取新数据) 现在我们可以定义ViewModel接口 现在让我们定义要应用于初始触发器的转换 从搜索查询转换为请求 防止触发空查询请求 防止用户每次输入新字符时发出火灾指令 取消先前的请求以支持新请求 每次用户滚动到滚动视图的底部边缘时都命中请求 用新数据附加先前状态(数组) 实施转换: 过滤空字符串,请记住我们不要触发空查询的请求 防止用户每次输入新字符时触发请求,仅在暂停0.3秒时才触发 将搜索查询转换为请求并取消之前的查询 将英雄转变为 虚拟HeroCellData (例如标题,图像网址) 将HeroCellData数组转换为HeroCellSection (这需要将其绑定到UITableView) 触发下一页请求 现在让我们将转换后的Observable绑定回UI 创建ViewModel 将主表项绑定到UITableView 将搜索项绑定到UISearchController的tableView 摘要: 我们的视图模型是“纯”的,它是不可变的,我们甚至不需要在ViewController中对其进行引用( disposeBag使订阅保持活动状态) 所有逻辑封装在一个地方 可以使用RxTests轻松测试它。 在下一篇文章中🙂 进一步阅读: Rx简介 RxSwift书 Rx.io RxDataSources 原始码 快乐的RxSwift编码! 🙂

纹理+ RxSwift交互式包装

如何为纹理制作RxSwift交互式包装? 基本上,纹理提供了各种基本组件,如下图所示。 特别是,我专注于ASControlNode来制作反应式包装。 因为,基本上, RxCocoa提供了各种交互式包装器,例如UIButton点击包装器,UIGestureRecognizer事件包装器等。 参考:https://github.com/ReactiveX/RxSwift/blob/master/RxCocoa/iOS/UIGestureRecognizer%2BRx.swift https://github.com/ReactiveX/RxSwift/blob/master/RxCocoa/iOS/UIButton%2BRx.swift 因此,如果我专注于ASControlNode,那么我猜想我可以在ASImageNode(UIImageView),ASNetworkImageNode(UIImageView),ASButtonNode等上进行方便的交互式包装。 我提到了UIGestureRecognizer + Rx脚本,并将其重新制作为ASControlNode包装器。 并按以下代码所示进行扩展。 最后,您可以使用像这样的上层代码! 参考: 使用Texture(AsyncDisplayKit)改善Feed性能 못잡네。 。리돌보다발열이심합니다。 겠죠가최적화다는리소? +이앱이안정적이었는데이이모양이+…+와。 15만지고리20%광탈… medium.com GeekTree0101 / GTTexture-RxExtension GTTexture-RxExtension –基于ASControlNode的Texture RxSwift交互式包装 github.com

RxSwift反向可观察又称为双向绑定

当我们听到反应式编程时,我们通常会考虑可观察序列的侦听器,转换器和组合数据,并对变化做出反应。 所以.. RxSwift是关于将数据从业务逻辑传递到视图的,对吗? 但是双向传递事件如何 TextField 可观察的 TextField 我们将研究以下两个用例: 绑定2个文本字段并订阅彼此的text控件属性(当更改其中一个文本时,另一个将自动更新) 进入下一个级别,并制作姓氏/名字/全名表格,如上图所示进行更新 让我们开始吧! 在开始编码之前,有时我想检查一下我是否没有重新发明热水-我们是否已有一些现有的库或完成与该主题相关的其他工作? 而且…我找到了这个图书馆 RxSwiftCommunity / RxBiBinding 反应性双向绑定。 通过在GitHub上创建一个帐户来为RxSwiftCommunity / RxBiBinding开发做出贡献。 github.com 表现出色。 我只需要像这样连接两个文本字段 这是在名字和姓氏以及全名文本字段之间进行双向绑定的完整代码(例如顶部的动画gif) 当我们在textFirst和textSecond输入文本时,姓氏字段( textFull )将使用串联的姓氏和姓氏文本进行更新。 链接到示例存储库https://github.com/vaderdan/Example2WayBinding

MVVM和协调器模式一起

今天让我们来谈谈创建应用程序时的常见问题。 应该选择哪种设计模式? 实际上,在构建iOS应用程序时可以使用许多模式:MVC,MVP,MVVM,VIPER等。这些是iOS中最常用的模式,每种模式彼此之间使用不同的方法,但最后哪种方法最好? 这取决于您从事的工作,项目的规模以及构建应用程序所花费的时间。 如果您想了解有关这些模式的更多信息,可以阅读本文:Bohdan Orlov的iOS体系结构模式。 现在让我们讨论两种不同的模式: MVVM :视图模型负责以易于管理和显示对象的方式公开(转换)来自模型的数据对象。 换句话说,这是模型和view / viewController之间的桥梁。 这是避免Massive视图控制器将逻辑移至View模型的一种绝佳方法。 协调者 :协调者或中介者将负责我们的应用程序路由(导航),然后view / viewControllers不需要知道它们在哪里或是否在导航内,它们只需要将导航操作发送到协调员/调解员。 MVVM运行中 首先让我们看一下MVVM的工作原理,以及为什么这对我们非常重要。 这有点容易理解它是如何工作的: view / viewController将事件或任务发送到viewModel viewModel执行任务(在后端中获取内容,执行操作,获取模型等) viewModel通过以下方式通知viewController:KVO,委托,回调,绑定等。 实际上,如今,如果您听到“ MVVM”,则认为是Reactive编程,反之亦然。 尽管可以通过简单的绑定来构建MVVM,但是RxSwift和RxCocoa将允许您获取大部分MVVM。 这样,我们将使用RxSwift来获取一些数据,并使用RxCocoa将数据绑定到视图来制作示例。 首先我们有viewController: 在这里,我们有好处: 分发 —现在,我们的viewController不再关心模型,它只是将事件发送到视图模型,并执行任务,完成后将响应发送回视图控制器,实际上视图控制器不知道什么真正发生在后台,因为现在这不是它的责任:)。 可测试性 – 视图模型对视图一无所知,这使我们可以轻松对其进行测试。 View也可能已经过测试,但是由于它是UIKit依赖的,因此您可能希望跳过它。 可重用性 -由于我们的viewControllers不执行特定任务,因此很容易重用项目中的大量代码和视图以及视图模型。 可扩展性 —现在,由于角色定义明确并且视图控制器并没有像以前使用MVC(大型视图控制器)那样执行很多任务,因此项目易于更改或更新。 是时候到协调员了 我们的应用程序看起来非常好,但是仍然有一个大问题,如果我要转到另一个屏幕,该任务由谁负责,viewController,viewModel,该怎么办? 答案不是全部,我们需要架构中的新元素来处理应用程序路由。 让我们尝试将协调器添加到我们的应用程序中,但首先我们需要了解应用程序应在何处以及如何运行。 好的,它看起来比以前非常相似,但是现在我们有了一个新的组件协调器,它负责处理应用程序路由。 通常,您的项目中有许多协调员,因为您的应用程序中有不同的导航和模块。 您可以将协调器与UITabBarController,UISplitViewController等容器相关联,或与UINavigationController之类的导航相关联,这些是应用程序中最常用的容器和导航。 每次您需要创建其中一个时,就知道需要一个协调器来处理流程:)。 现在是时候编写一些代码并观看协调员的实际行动了。 首先,让我们更改视图控制器以了解用户何时选择行。 这很简单,我们只调用方法modelSelected(Repository.self) ,然后将存储库绑定到视图模型。 现在更新视图模型。 在这里,我们有一些新东西让我们看看: […]

iOS:RxSwift +干净的架构

在上一篇文章中,我们有机会从概念上定义应用程序的体系结构。 这篇文章的目的是深入了解我们正在使用的该体系结构的关键组件的实现。 在这篇文章中,我们将讨论如何实现: RxSwift +干净的架构 我们的应用程序使用ReactiveX swift版本:RxSwift。 RxSwift是组合异步操作和事件/数据流的强大工具。 这些流使层之间的通信变得容易。 这就是为什么我们认为它完全适合我们的架构需求。 该方案表示RxSwift流经体系结构不同层的方式: 基本上,Presenter执行返回一个Observable的用例。 此Observable在数据层上创建,并由域层传递。 演示者订阅此Observable来从存储库中获取结果。 但是,什么是可观察的? 如果我们阅读RxSwift的入门文档,我们可以理解什么是Observable: 每个Observable序列只是一个序列。 Observable vs Swift的Sequence的主要优点是它还可以异步接收元素。 这是RxSwift的内核。 让我们逐层介绍实现: 实作 UI层 演示者有一个要执行的用例。 方法execute返回一个Observable。 演示者订阅了此Observable: 请注意,在订阅关闭之后,我们将调用disposed(by: disposeBag) 。 此方法将订阅添加到disposeBag中以取消该订阅。 最后,在闭包内部使用[unowned self]或[weak self]并使用dispose(by:)方法可以避免内存泄漏。 😉 域层 用例具有一个execute方法,该方法调用CatalogRepository协议方法并返回由该存储库创建的Observable: 资料层 数据存储库实现在域层中定义的CatalogRepository协议,并具有数据源和数组。 这些数据源又实现了CatalogDataSource协议。 在数据存储库的每个方法内部,它为包含的每个数据源从CatalogDataSource调用一个函数。 为了连接这些调用,我们使用Observable的操作concat ,如下所示: 远程数据源创建一个Observable并使用Alamofire执行请求。 响应结果将通过Observable onNext() , onCompleted()或onError()方法发送给演示者。 就这样! 通过层连接完成! ✅ 这可能是每个人的应用程序中的常见情况,但是RxSwift是一个功能强大的工具,这只是冰山一角。 让我们深入了解我们在项目中使用更多的东西之一: 经营者 RxSwift中有许多运算符:创建,转换,过滤,合并……可以使您的生活更轻松。 […]