Tag: 毒蛇

在VIPER中组装

在我正在进行的项目中,我选择了建筑模式-VIPER。 这是音乐制作应用程序,它允许您播放,录制和混合第三方乐器。 主模块的框架(以简化形式): 最初,该应用程序是为iPad设计的,后来该应用程序是为iPhone开发的,并且更改了主要模块。 某些组件可用于两种设备(通用),有些则不能: 我们希望保持课程尽可能整洁。 每次创建/更改课程时,您都应该问自己: 该课程有多少职责? ( 单一责任原则 )。 我认为,创建模块和DI(返回对象图)的责任应该属于一个特殊的类。 它不应制作AppDelegate,Router或VC。 这可以使您的程序集 : 其余代码非常简单: 然后我提出要为Mac创建应用程序,为什么不…

威伯·斯威夫特

NavigationController对View,View to Presenter,Presenter to Interactor和Router都有很强的引用。 因此,我们让NavigationController包含所有模块。 结果,此解决方案使我们可以在将ViewController从NavigationController中删除后销毁所有模块。 TableViewDelegate和TableViewDataSource 我们建议使用的方法不是唯一可能的方法。 创建它是为了没有更好的东西。 让我们用一个例子来展示它。 这里有一系列的人类对象,它们是通过一些API异步接收的。 人类具有以下特性: –名称:字符串; –年龄:整数; –照片:UIImage; 为了显示信息,UITableView正在使用。 人的名字,年龄和照片被加载到一个单元格中。 VIPER原则之一说View是被动的,但是Presenter不能向View返回任何内容。 视图应具有设置器,Presenter用来显示信息。 问题在于它仅适用于已创建的对象,而不适用于动态创建的对象。 这意味着您不能为每个单元格写一个setter。 这是为什么? 首先,编写应用程序时,单元数是未知的。 其次,为相同的对象编写setter是愚蠢的。 解: 让我们为View内部Human的每个属性创建一个变量,然后为每个新变量添加一个setter。 接下来,在Presenter中创建一个方法,该方法从Interactor获取数据并将其设置为View中的“ currentHuman”变量: 这样,每个单元格都填充有正确的数据。 它破坏了原理,该原理说View除了对UIViews和Presenter的引用外不应有任何其他内容。 但是它遵循另一个规则,并且代码仍然可以测试。 PS:本文由BytePace移动开发人员撰写。 您可以在这里查看他的作品和其他文章:http://bytepace.com/

跨平台VIPER

曾几何时,我写过与得克萨斯州一样大的视图控制器,以为我已经很聪明地将表视图数据源移出了它们。 但是随着时间的流逝,我的大脑和心脏有些刺痛,说:“首席,必须有一种更好的编写软件的方法。 您需要提高您的游戏水平。” 那时是2014年的决定性日子,Mutual Mobile发表了一篇名为VIPER的文章。 我浏览了这篇文章,然后迅速而固执地向前迈进,而实际上并没有把VIPER弄得一团糟。 多年来,我开始发展自己的体系结构选择。 许多人说,虽然没有灵丹妙药,但我现在经常发现VIPER最适合我对具有清晰方向和长远眼光的应用程序的需求。 我非常喜欢模块化以及它如何消除iOS中单元测试的烦恼(大部分情况)。 在前往VIPER’ing的过程中,我并没有真正遇到过跨平台应用程序中完整而干净的实现示例。 因此,我最近决定编写Listy,这是一个适用于iOS,tvOS,watchOS和macOS的待办事项列表应用程序,也是我对开源软件whole的第一份全应用程序贡献。 我很想与您分享我的构建方式,并希望对您自己的软件开发冒险有所帮助。 如果您说的是:“看,太好了,但是我只想检查代码”,就可以开始了。 Listy的成立来自面试带回家的测试。 目的是编写一个简单的待办事项列表应用程序,该应用程序仅创建和删除列表和任务,但是花费大量的开发时间来构建一个项目基础,该基础将最适合在将来的开发中扩展该应用程序-本质上奠定了坚实的基础一棵小树的根直到一天都会长成一棵高大美丽的树枝。 不幸的是,我们最终并没有成为对手,但我还是决定继续自己开发Listy,并发表自己的发现,以创建在VIPER下运行的跨平台应用程序。 由于功能有限,我无法与Listy一起管理日常工作,但我认为它可以为其他项目的开发提供漂亮的样板房/参考指南! 与我从头开始或重构的大多数iOS应用一样,我通常要做的第一件事是创建一个基本的Cocoa Touch框架,以容纳主要的纯Swift和Foundation框架API交互-自定义数据结构,Swift数据结构的扩展,模型和数据持久性-我们应该能够在应用扩展和其他任何地方使用和访问的东西。 然后,我创建第二个Cocoa Touch框架来处理所有常见的UI(Kit)交互-常见的视图(即视图控制器),表视图数据源/代理,UI数据结构便利性扩展-我们可以在许多不同的用例中使用的东西。 VIPER在哪里适合? 通常,我的VIPER模块全部都位于iOS主应用和扩展程序中。 随着跨平台的发展,将蛇分开的意义何在何处? VIPER的演示者和交互者甚至不应该考虑触摸UIKit。 演示者应该知道何时(通过视图和路由器)呈现和更新UI,并且交互者应处理业务逻辑和CRUD’ing实体¹。 鉴于列表和任务管理的演示者和交互者行为有多么相似,我将它们全部放入基本框架ListyKit中。² 在所有Listy应用程序的基础上都有演示者和交互者,在任何应用程序中,我都可以做以下整洁的事情: 获取列表和任务数据,通过它们可以更新列表和任务视图。 告诉列表和任务视图进行自我更新,删除表视图行以及显示错误警报。 让路由器准备显示编辑列表和编辑任务视图。 我还将所有路由器输入和输出协议都放置在ListyKit中,但没有放置任何实际的路由器。 我曾考虑过包括路由器,但由于路由与平台之间的差异很大,因此可能会有些过时。 例如,当用户指示要添加任务时,在iOS上,我们会显示一个完整的单独视图,而在macOS上,我们会将带有文本字段的表视图行添​​加到任务列表中。 您可以使用预处理程序条件来加载不同的平台特定代码(并且我确实在应用程序的其他地方使用了一些代码),但是感觉到这样做可能会使路由器变得有些毛茸茸。 (而且,太多的东西使东西闻起来很臭。) 在三种不同的设备之间,iPhone,iPad和Apple TV在UI API方面有很多共同点。 因此,我让ListyUI坐在ListyKit的顶部,并提供以下内容: 设置,配置和更新所有列表和编辑视图。 在所有列表和任务视图中重用表视图数据源和单元配置。 共享视图路由输出实现(例如,呈现/推动/关闭视图)。 出现错误警报 在每个视图的updateView(…)函数中,我执行单元配置,选择和删除的基于块的设置。 这使我可以将表视图数据源和委托与视图分开,同时在用户采取操作时仍能够根据需要调用演示者。 好吧,它们特别特别,因为它们具有WKInterfaceControllers和NSViewControllers之类的奇特功能,而我们的朋友iOS和tvOS则没有。 从理论上讲,虽然我们可以在所有平台上创建一些疯狂的主视图抽象,但我认为最好只为watchOS和macOS分别处理UI交互。 毕竟,我们仍然可以从ListyKit获得VIPER中的“ IPE”,它可以解决许多其他繁重的工作。 最初,我认为我可以使ListyKit和ListyUI跨平台工作,但是没有。 我很快发现跨平台框架在公园里走不动。 幸运的是,我发现了这个非常不错的指南,该指南帮助我了解了如何通过特定于平台的框架触摸共享的Info.plist文件来共享代码(设置细节不在本文讨论范围之内,但是我建议您将该文章阅读一下以了解学到更多)。 我最终建立了以下特定于平台的框架: ListyKit […]

MVP,MVC,MVVM和VIPER。 什么对iOS开发更好?

Same like every house has a solid basement, every software project, has an software architecture it is built on, and each project has its own app structure. The types of architectural patterns may vary, but there are 4 most commonly-used ones – the ones whole IT world continuously criticizes but keeps using at the same […]

许多面孔的VIPER —第4部分:EventEmitter iOS演示

正如在第3部分中所宣布的,现在该展示我们如何通过使用Event Emitters使VIPER客户端体系结构变得更加复杂和宽容。 我太好了……很抱歉让您失望,但这就是我们漫长的传奇故事的全部代码:😧 3个事件,其中有4个负载项,最后一个事件为2:一个用于PaymentsModule ,另一个用于AnalyticsModule 。 花一些时间,并通过此示例查看存储库。 尝试弄清楚这种方法如何为您的案件提供帮助。 第1部分中解决的问题似乎可以很好地解决。 您可能会问为什么使用此功能,为什么不使用RxSwift或类似的功能? 好吧,一旦您开始使用FRP , FRP就会变得更加艰难,更加坚强,而且非常占主导地位,并且由于这个原因以及许多其他原因,不幸的是,它们在开发人员之间也存在分歧。 本系列文章中介绍的方法(尤其是在最后一部分)非常精简,可以随时根据需要进行更改。 同样, 基于事件的方法比响应 式方法更容易理解,尽管它们是核心。 对于可能发现反应式方法有些吓人的开发人员,这可能是完成其工作的好方法。

我们喜欢软件架构模式

我们作为世界上的移动开发人员,通常会使用许多很酷的软件体系结构模式,通常都包含字母M和V(MVC,MVP,MVVM,VIPER),这会对新编写应用程序的人造成很大的挑战或困扰。 让人们重新关注这种模式应该做什么也很好。 有什么问题? 从头决定如何在大型应用程序中构建每个组件是多余的。 您面向用户的组件都将获取数据,然后根据该数据在屏幕上绘制并接收用户交互。 我们喜欢MVC / MVP和MVVM之类的设计模式或概念框架,因为它们提供了模型,视图和控制器之类的抽象对象来划分职责,并确保组件井井有条。 但是我想做更多的事情! 大多数时候,您将需要分离其他对象来处理获取数据,处理数据以及处理用户交互的后果。 最后,对这些背景对象的引用由与视图相关的组件保留。 当您需要分开职责,想要重用组件并帮助允许访问与视图无关的状态(例如,您有多少消息或是否已登录)时,可以这样做。 网络和数据持久性是经常需要分开的职责的示例。 处理这些组件的状态和状态,尤其是当它们可能在应用程序的多个页面之间共享时,变得很困难。 毒蛇巢 VIPER是一种比MVC更进一步的体系结构,它为更复杂的应用程序指定了各种额外的组件。 由显示内容并接收用户交互的视图 ,分析数据并确定要显示的内容的交互器和演示者 ,代表数据的实体以及路由器组成 ,以处理已显示的页面并进入新的页面。 这是一个很好的框架,请在此处阅读。 冲床 通常情况下,各个组件的状态会耦合在一起,这意味着您必须在不模拟整个应用程序或某些特定用户旅程的情况下,才能测试应用程序某一部分会发生的情况(“该错误仅在我尝试下达一个订单并取消它,然后尝试注销”-希望这永远不是真的)。 您还失去了对应用程序进行安全的结构更改的能力,因为您不知道后果将达到多远。 本质上,在应用程序的整个生命周期中,拥有一个良好的组件设计系统并实施通用样式,可以创建出更快地编写(希望),更易于维护(更易于理解和更改)并保持脱钩(也称为可测试)。 有关 首先编写测试会更好 苹果的MVC不是MVC 协调员,现在听起来很花哨

Viper实施中的IOS内存管理(ARC)

关于ARC的文章更多,其中有很多很好的例子。 我将保持简单。 该图中显示的示例演示了ARC的工作原理。 持有参考 简单来说,您创建的每个对象都有一个引用。 如果存在您可以访问并指向一个对象的变量或常量,则基本上意味着该变量将保留该引用。 参考类型 有3种参考类型: –强 –弱 –无人 请记住,ARC仅跟踪强引用。 那么ARC到底要跟踪什么? 好吧,我很高兴你问。 如上图所示,当其他变量持有对Car()的引用时,ARC会继续增加引用计数,而当变量设置为nil时,ARC会递减引用计数。 同样,当该引用计数为0时,ARC会为您删除分配的对象。 太好了,实际上,这是一个很棒的解决方案,我决定提供几行以纪念这个惊人的创作。 毒蛇 不,不是这个…… 如果您熟悉其他架构,例如MVC , MVP , MVVM,这将更容易理解。 体系结构的主要思想是将代码逻辑分离到不同的模块中,以便使其他开发人员更容易理解代码,并使代码更具可测试性。 选择使用哪种方法实际上取决于项目规模和团队协议。 涉及大型项目时, MV-X系列的体系结构存在一个常见问题。 而这个问题是大规模的视频监控器,演示者或视图模型。 这基本上意味着一个模块中的代码太多,以后可能会造成混乱。 这就是VIPER出现的原因之一。 VIPER通过进一步拆分代码来解决MV-X问题。 在5个主要模块中:视图,交互器,演示者,实体,路由器。

VIPER:经验教训

我从来都不是VIPER的粉丝。 此外,我一直同意一个广为接受的观点,即VIPER对于任何应用程序中的大多数屏幕都是过大的杀伤力。 互联网上有大量与VIPER相关的出版物,但事实证明,每个团队都以自己的方式烹饪VIPER。 我在这里浏览我最近的食谱。 原因 我认为技术和体系结构决策应与业务需求同步,并取决于项目的特定情况。 期限和截止日期,项目规模,团队规模,预算等。 每个人都在窃窃私语:“让蛇进来” 该项目于2018年年中作为一个初创公司开始,并且将是一个相当大的长期项目。 现在,该应用程序总共有大约一百个屏幕。 我们从一开始就发展迅速。 我们经常对那些很清晰的部分进行工作,这些部分目前可以立即完成,只是为了推动项目的进行。 当应用程序端的服务器API和业务逻辑准备就绪而设计尚未准备就绪时,这通常导致完全颠倒的开发。 我已经作为该项目的唯一iOS开发人员开始了( 实际上并没有任何改变 )。 但是我们有计划在需要时扩大移动iOS团队。 我迫切需要尽可能多的去耦,以处理这些不断的变化,保持应用程序稳定,而不会陷入技术负担。 让蛇进来 继续阅读

适用于iOS的高级Viper架构,无保留周期。

如今,大型团队的开发人员花费大量时间使用和维护其代码库,而该体系结构提供了开发周期的所有基本要素。 作为开发人员,设计我们的代码非常重要,这样每一部分都易于识别,具有特定的明显目的,并以逻辑方式与其他部分组合在一起。 在本文中,我将介绍一种方法,该方法如何在我们的iOS项目中准确使用VIPER架构,而又不会使内存堆积如山。 本文不是VIPER体系结构的初学者,而是对于使用过该体系结构且可能难以确定几个内存问题的人员的。 在继续之前,请在GitHub上克隆项目。 在该项目中,有两个视图控制器,它们将非常容易且清晰地演示主要问题。 Home View Controller是主导航控制器和推入Home VC的帐户视图控制器的根视图控制器。 克隆上述存储库后,签出“ Without_VIPER”分支。 该分支显示了此演示项目的主要目标。 一个导航堆栈上有两个屏幕。 按下“帐户”按钮后,“帐户VC”将被推送到导航控制器。 在控制台上,您将看到两个视图控制器均已加载到内存中。 按下导航栏上的后退按钮后,您将看到帐户视图控制器已取消初始化。 因此,这是我们项目的基础。 弹出视图控制器后,应将其取消初始化,并释放内存。 现在,检出同一存储库的“ Basic_VIPER”分支。 现在,两个视图控制器都以以下方式遵循VIPER架构方法。 运行该应用程序后,您会看到在Home VC上所有通信都已完成。 它只是在模拟VIPER体系结构的基本流程。 按下帐户按钮后,帐户VC将被推送到导航控制器,并且将一个全新的对象块添加到内存中。 现在按下后退按钮,您将看到Account VC尚未从内存中取消初始化。 每次您按下Home VC上的“帐户”按钮时,都会不断将大量对象添加到内存中,这些对象将相互保持引用并被保留。 在只有两个视图控制器的此类项目中,如果未在适当的完整项目中处理此内存管理,则您的应用程序可能会遇到许多悬空指针。 我们的任务是删除上述保留周期。 现在,检出同一存储库的“ Advance_VIPER”分支。 我们的主要重点是从项目中删除上述保留周期。 可以有很多方法来执行此操作,但是我将遵循所描述的方法。 我将从我们的P(演示者)那里获得一个V(视图控制器)的弱引用,同样,我将从我们的I(交互器)那里获得一个我们的P(演示者)的弱参考。 演示者的实现将通过以下方式进行。 当取消帐户演示者的初始化时,我们将对交互者的引用设为nil,并且作为演示者,交互者引用很弱,因此将没有任何保留周期。 同样,将为View和Presenter保留周期。 运行项目并弹出Account VC后,您将看到所有对象现在都已从内存中取消初始化,并且内存已释放。 本文没有提出实现VIPER体系结构的正确方法,只是表明在实施VIPER时,iOS开发人员应以他们认为容易的任何方式来注意保留周期。 如果不处理这些保留周期,则您的应用程序将遇到内存问题,因此最好继续删除它们。 如果您找到其他更有趣的方法来达到相同的效果,请分享。 编码愉快!

VIPER体系结构iOS Swift

好的,这是另一篇解释iOS Swift的VIPER架构的文章。 这是什么意思,为什么我们要关心VIPER?它比Clean Swift作为VIP更好和更容易,它们真的彼此不同吗? 本文结尾处的示例项目。 让我们从两者之间的一个小比较开始: VIP和VIPER具有相同的文件结构,即使省略中也没有提到ER,它的确有一个实体“模型”和一个路由器“线框”,那又是什么呢? VIP是一种单向流,它来自: UI->视图->交互器->演示者->返回视图。 VIPER是多向流,来自: UI->视图->演示者->交互器->演示者->返回视图。 那么,为什么我认为VIPER比VIP或Clean Swift更容易维护? 有人认为实体是模块的主要模型,而我个人认为实体是实际模型的字符串表示形式。 实体在Interactor中进行映射,并传递给Presenter进行格式化,因此,应该在模块周围流动的对象是Entity,并且没有ViewModel或实际Model在周围流动。 Interactor知道该实体,并将其传递给Presenter,该Presenter将处理格式并将实体类型作为视图的形式传递给视图。 VIPER非常容易实现单一责任原则。 具有ViewModel + Entity只是违反了DRY和KISS原则。 实体是VIPER元素,不应与模型混淆。 因此,我和我的同事在一个Generator上工作,它将准备好正确处理流,而无需麻烦地创建ViewModels,或者让View处理与交互器的路由或事件,因为viper的格式应为: 视图了解Presenter。 演示者了解View,Interactor和Router。 Interactor知道Presenter和Entity。 这是一个演示项目,它以简单的方式实现VIPER设计模式,从而可以实现可测试性,可维护性和可扩展性。 有些人更喜欢Presenter应该格式化传递给View的数据,我实际上不同意这个概念,因为众所周知,Interactor 操纵 Entity。 Kaakati / CoolBlue-iOS 人们可以在GitHub上构建软件。 超过2千8百万的人使用GitHub来发现,发掘和贡献超过…… github.com 上面的示例是使用生成器构建的,该生成器会将您的文件作为UI组件,作为ViewController的Viewer,演示者,路由器,交互器和实体分为UI。 Kaakati / VIPER模块生成器 VIPER-Module-Generator –具有预定义功能和BaseViewProtocol的VIPER模块样板生成器。 github.com