尽管有这个标题,我在这里不会谈论任何新的范例或任何新的编程模式,而是要谈一种态度,以及我们如何运用这种态度来改进Zattoo中的iOS App。 如果您不知道Danshari的概念,它是由三个汉字组成的日语组成的单词,其顺序为:拒绝,处理和分离。 几年前,我在日本旅行时发现了这个概念。 我真的很喜欢Danshari的概念,因此我会在日常生活中尽可能地遵循它。 简而言之,Danshari可以被定义为避免与物体产生任何情感联系,与占有分离以及摆脱生活中的混乱的想法。 在您生活中的一段时间内,对象可以看作是有用的工具,然后被扔掉。 一旦不再需要它们,那就结束了。 您不必再保留这些工具,不占用大量空间,减少移动自由度,或者在某些情况下(如果您拥有昂贵的财产)会增加被盗的恐惧。 可以想象,在生活在资本主义世界中的Danshari的概念确实很难应用,每个人都想拥有市场上最大的汽车,最大的房屋和最新的设备。 当然,如果确实需要这些对象并且它们可以解决您的生活中的问题,那也不错。 Danshari作为开发人员 正如我所说,我会尽可能地遵循Danshari的原则,这也意味着我会尝试将此概念应用到我作为软件开发人员所生活的那一部分。 将Danshari用作开发人员到底意味着什么? 容易,只需从项目中删除任何不需要的组件,即可节省代码和资源。 代码和资源是解决问题的工具。 而且,由于项目的发展,这些工具中的一些最终可能变成多余的。 您现在必须纳闷,这是什么意思,以及您实际上可以从项目中删除什么。 毕竟,添加所有内容都是有原因的,不是吗? 为了更清楚地说明,我将根据我的个人经验提供示例列表,但是请您参考它,不要害羞,我相信一旦开始,您会发现越来越多的情况将Danshari应用于您的代码。 ·在无处注释的代码中,代码段无缘无故地保留着,可能是由于某种重构的结果,没有人敢于仅仅因为谁知道有一天这段代码可能有用而删除了…… ·不再需要未使用的类和方法 ,App Code是一个出色的IDE,可发现您App中所有这些冗余元素。 ·实际上从未使用过的冗余导入 。 应用程式程式码也可以在这里提供协助。 ·添加到Podfile中的未使用的依赖项,不再由应用程序使用。 · 默认实现 ,通常在内部带有注释代码。 添加它们是有原因的,但是一旦其行为恢复为默认状态,就不会将其从项目中删除。 · 预定义的模板,什么都不做。 您是否对以下代码熟悉? · 未使用的字符串,不再使用的字符串也应从Localizable.strings中删除 ·与以前相同, 未使用的图像是否由应用程序的最新版本使用了所有xcasset? · 具有可推断的数据类型或默认修饰符的定义 · 不再需要过去可能在执行某些任务时有用的脚本 ,这些脚本无人可做。 · 巨大的许可证标头,添加到项目的每个文件中。 除了养活自我的标头根本没有增加任何价值。 在某些情况下,您甚至可以找到代码少于许可证的文件。 免责声明:由于法律问题,在某些情况下,例如在公开公共API的框架上工作时,实际上确实需要这些标头。 · 冗余和错误的注释会在代码中添加明显甚至错误的信息 · 旧代码 由于语言的发展,不再需要。 综合属性,私有方法的预定义等… […]
我非常喜欢使用Swift的可重用和干净的架构。 在我的上一个项目中,我实现了MVVM和面向协议的体系结构,这有助于将关注点分开。 我也曾按照MVC方法从事过几个IOS项目。 在开始新项目或适应旧代码的同时选择正确的体系结构很重要。 我必须找到有关iOS体系结构模式的综述,如果您也感兴趣的话,可以介绍常见的体系结构。 iOS架构模式 揭秘MVC,MVP,MVVM和VIPER medium.com 但是有一种更好的方法(以我的拙见)主要是在我的经验中,MVVM在保持轻巧的同时做得很好,并且我确实在Swift中使用MVVM实现了单向数据流(Redux)方法,这产生了巨大的变化。 它使干净的体系结构稍微好一点,健壮且可测试 ,因此很重要 在本文中,我试图解释为什么将Redux与Swift结合使用是更好的主意。 首先,我们需要了解该概念的基础。 因此,让我们开始吧! 什么是Redux和单向数据流? Redux是一种流量实现,但实现略好一些,它使您的应用程序状态更加可预测。 它首先以强大的javascript库React作为JavaScript应用程序的可预测状态容器出现在Javascript世界中。 Redux,仅使应用程序的状态位于单个存储对象中。 因此,从应用程序/视图的生命周期状态触发操作会发生变化,而针对该操作的化简器会生成新状态。 关于Redux的另一种解释,您可以阅读Redux的卡通指南介绍 Redux的卡通简介 导致比Flux更加混乱的一件事是Flux和Redux之间的区别,这种模式以前是… code-cartoons.com 让我们开始; 在本文中,我使用了benjaminencz的ReSwift,后者在Swift上创建了Redux实现。 ReSwift是Swift中单向数据流架构的类似Redux的实现。 ReSwift可帮助您将应用程序组件的三个重要方面分开: 重新浏览参考 ReSwift正在快速发展,超越了核心库,它提供了用于路由和时间旅行的实验性扩展… reswift.github.io 状态:在ReSwift应用中,整个应用状态都明确存储在数据结构中。 这有助于避免复杂的状态管理代码,实现更好的调试,并具有许多其他好处…… 视图:在ReSwift应用程序中,当状态更改时,视图也会更新。 您的视图成为当前应用程序状态的简单可视化。 状态更改:在ReSwift应用中,您只能通过操作执行状态更改。 动作是描述状态变化的小数据。 通过极大地限制状态改变的方式,您的应用程序变得更易于理解,并且可以与许多协作者一起工作。 从ReSwift网站剪辑 用法 在这个简单的示例中,我声明了一个BaseState,因为struct带有两个状态。 BaseReducer已注册其减速器。 LoadingState struct处理显示正在加载微调器视图或隐藏视图的状态 ,是否具有isLoading属性知道当前正在加载? 它是在视图中旋转或在状态中旋转的类型。 然后,声明的LoadingAction具有两个结构, LoadingShowAction将类型传递为有效负载,而LoadingHideAction不包含任何有效负载。 最后,LoadingReducer采取操作( LoadingShowAction或LoadingHideAction )和当前状态,并生成一个新状态。 简单。 因此,此时我们可以调度一个动作,即; store.dispatch(LoadingShowAction(type:.Normal))显示微调器 store.dispatch(LoadingHideAction())隐藏微调框 。 […]
在编写测试时,我们必须以良好的代码和质量来进行测试,使其变得更加干净,简单和快速,对吗? 但是有时候很难做到。 我们开始在测试中看到一些可重复的代码,设置和期望值。 今天,我将向您展示提示/技巧 ,以在没有框架的情况下为您的测试创建可重用,更简洁的设置。 让我们开始展示一个使用swift默认测试库的示例。 XCTest。 初试班 该类将以不同的方式测试UserRepo存储库类中名为findAdminsBy的函数。 上面的测试代码易于理解和重用,对吗? 具有一些帮助程序功能,安装程序在每次测试之前运行并重用变量。 是的,很简单并且可重用。 但是,让我们列出一些“问题”: 我们只测试UserRepo的一个功能,即findAdminsBy : –如果要测试UserRepo的另一个功能将增加一些复杂性; –要测试另一个功能,我们需要更改setUp功能或将其删除并将其放入期望功能中。 什么不好,因为这将是一个冗长的考验; 需要更改默认设置时,作为第一个功能测试。 在期望函数内添加了一个设置; 每个期望函数都在调用可重复代码: result = userRepo.findAdminsBy(email: email) 如有必要,添加新参数,我们需要在所有期望函数中进行更改。 那么,我们如何才能为上面的列表改进并创建一些解决方案? 我们将使用闭包概念用作设置并执行可重用的动作。 为了更好地了解闭包 ,这里是官方文档。 首先,我们需要创建两件事来帮助我们的测试。 #1 —动作结构 该Struct将有助于保持关闭状态直到被调用为止。 在闭包内部,将包含您需要保留的操作。 例如: result = userRepo.findAdminsBy(email: email) 。 用法将在稍后显示。 #2 —执行功能 该功能将有助于通过一些设置配置来运行/执行操作 。 波纹管是Executer.swift文件: 第二级考试-重构 现在,让我们使用这两个助手实现一个新的Test类。 我们可以看到的第一件事是操作和设置特定于findAdminsBy函数。 如果我们需要测试UserRepo的其他功能,只需使用自己的设置添加其他操作。 该代码现在更加灵活,可重用和更简洁。 该测试继续简单易懂。 如果您像我一样参加BDD测试,那么我将向您介绍测试框架Quick。 这将帮助您以BDD样式进行测试。 […]
您有没有想到过,您尝试使用标识符,并且编译器对此有所抱怨! 就像是。 是的,当我尝试为新的NetworkEngine编写默认配置时发生了,事实证明,这些是保留的标识符,不能原样使用,但是我们可以使用相同的标识符,但要稍作改动。 喜欢 就是这样,只需使用反引号即可 。 另一个用例是,当您尝试在块内自动展开自我时 。 我希望该提示对您有所帮助,并且如果您有任何对您的旅行有所帮助的新提示,我很想听听他们的意见! 如前所述,我正在编写一个新的NetworkEngine,可以在我即将进行的项目中重用。 它目前处于过早状态,但是您可以在我的项目中使用它,因为我正在积极进行重构并为其添加新功能。 https://github.com/fahadHyder/Swift_NetworkEngine 请在您的快乐时光里检查一下,并分享您的想法,甚至您可以创建PR! 🙂
“当我们使用容器视图时,视图控制器的层次结构” iOS UI实施如何帮助我们获得简洁的代码。 考虑XCode项目中的容器控件,即使没有任何专业知识,也可以帮助您减少代码中的行数。
软件开发是一项复杂的工作,随着您的应用程序的发展而变得越来越复杂。 限制应用程序的复杂性将带来更好的整体质量。 在本文中,我论证了开发开放源代码软件的重要性,但是,针对高质量软件的开放源代码的相同原理也适用于封闭源代码库。 应用架构 在设计应用程序时,您的设计通常可以归结为至少具有“模型”和“视图”。 网站上的视图是HTTP路由,而在(iOS)应用程序上,这是一个更加直观的视觉概念。 除了这两个以外,您最终可能还会拥有更多类别。 我相信其中的控制器,配置,缓存和DataRepositories还有更多可能性。 当我指通过模块进行开发时,我想到的是面向依赖的体系结构。 您的模型是应用程序的核心基本概念。 用户具有标识符,名称和个人资料图片。 此信息对于所有其他组件的功能至关重要,这意味着所有其他应用程序组件都取决于模型。 您的观点是您将要使用的最高级概念。 这意味着视图(间接)依赖于所有其他模块。 由于视图依赖于这些模块,因此无法与类似模型的概念创建类似意大利面条的关系。 这迫使您的应用程序从下至上在结构上都是合理的。 访问修饰符 通过执行上述操作,可以减少应用程序数据对系统其他部分的偏见。 它有助于保持对数据结构的整洁有组织的监督。 但是,访问修饰符在这里比以往任何时候都更为重要。 忽略模块中模型的访问边界非常容易。 您为什么不将这些类型的“私人”更改为“公共”? 实际上,预防非常简单。 您的代码就像一堵砖墙。 砖块可能彼此并排,而不是直接相关。 一块砖将依赖于其他砖,而其他砖将依赖于该砖。 但是,从来没有两块砖头互相靠在一起。 这个基本概念对于创建稳定的软件至关重要。 编译时间 除了软件的结构质量外,您还将收获很多。 少了两个错误,更容易维护,这是我想到的两个问题,但是编译时间也肯定会增加,这并不是很明显。 软件通常是逐模块编译的。 这意味着在较小的模块中分离代码可以减少进行更改时需要重新编译的代码量。
VIPER推广了适用于iOS的Clean Architecture。 与Bob叔叔的原作相比,这是一个很小却根本的区别! 在过去的一年中,我非常高兴与业务中的朋友讨论可以在iOS *中使用的各种架构模式。 讨论通常会回到“清洁建筑”一文中的想法。 我们尝试在iOS应用程序的上下文中了解它,以及它如何与平台的其他惯用模式(如模型视图控制器和情节提要)相适应。 一个反复出现的主题是理解“ Presenter ”的“ 正确 ”角色-最具体的示例在使用VIPER架构iOS应用程序中进行了详细介绍。 VIPER作为第一个可行的示例很受欢迎,并且很好地解释了Bob叔叔的适用于iOS的Clean Architecture方法** 与原始资料进行更仔细的比较后,发现在Presenter上,Clean Architecture和VIPER之间存在无法解释的不一致,这似乎是很根本的。 VIPER建筑 通过以下简单说明,我们介绍了Presenter在VIPER中的角色: 演示者:包含视图逻辑,用于准备要显示的内容(从Interactor接收) 和对用户输入做出反应 (通过从Interactor请求新数据) 清洁建筑 在我们将其与原始“清洁架构”文章中的图表进行比较之前,这似乎是合理的。 你看见了吗? 这条无痛的粉红色小线几乎是在事后想写的! 继续说明: 这些模型可能只是从控制器传递到用例 ,然后从用例传递到演示者和视图的数据结构。 注意控制流程。 它从控制器开始,遍历用例 ,然后在演示者中结束执行。 另请注意源代码依赖性。 他们每个人都指向用例。 当您看到所有参与者的更详细的时序图时,这可能会变得更加清晰(也许)。 一个方向 VIPER采用传统的堆栈体系结构方法,其中通信是双向的,例如向下流经各层,然后再次进行备份。 在“干净的体系结构 ”中,控制流只能沿一个方向传播。 视图->交互器->演示者->视图 演示者不是View和Interactor之间流程的中央协调者,它的唯一职责是作为接口适配器,将来自Interactor的输入转换为方便的东西,例如View Model跨越边界。 就这样-很小但很重要的变化。 突然,体系结构变得越来越简单。 单一方向上的控制流非常可爱,其好处似乎有几个: 关于架构的更容易推理 改善关注点分离 删除Presenter Interactor之间不必要的样板 消除诱惑以拦截通过Presenter的输入 更加遵守依赖性规则 如果您使用VIPER,那么您可能已经在项目中看到了Clean Architecture的大部分好处。 更改为“更清洁的体系结构”可能不值得在您的团队中展开辩论。 也就是说,在实现下一个功能时可能值得尝试。
单元测试是测试单个单元/组件的软件测试级别。 目的是通过测试组成程序的最小单元来测试程序的业务逻辑。 在面向对象中,这些最小单位是方法。 因此,我们通过提供输入来测试所有这些方法,并通过比较方法的输出并将其与我们的预期输出进行比较来测试逻辑。 简而言之,这是适合您的单元测试 。 减少错误。 改善设计。 允许重构。 降低变更成本。 好的文档。 简洁的代码示例胜于文档的许多段落 减少了程序员遇到的最大恐惧之一,那就是对一段代码进行更改,而不知道会破坏什么。 到目前为止,大家可能都在想。 如此多的讨论,让我们编写一些单元测试。 从此处下载启动项目。 这是一个简单的应用程序,它通过分别以米为单位的身高和以kg为单位的体重来计算一个人的BMI。 它包含一个名为BMICalculator的类,其中包含我们应用程序的业务逻辑,即用于计算一个人的BMI的逻辑,是的,您猜对了! 在本教程中,我们将测试该类。 运行项目,您将看到此屏幕。 玩应用程序,增加身高和体重,然后看一下您的BMI。 PS:请忽略应用程序的UI,因为我的设计技能不太好。 🙁 有两种方法可以在项目中添加单元测试。 1.从新项目开始 您可以在创建新项目时通过选中底部的“ 包括单元测试”复选框来添加单元测试 。 由于我们已经在项目中添加了单元测试,因此我们跳过此步骤。 2.在已经创建的项目中添加单元测试包 您也可以在已经创建的项目中添加单元测试。 转到文件>新建>目标 选择iOS单元测试套件 点击下一步 打开项目并转到底部的BMI CalculatorTests ,然后选择BMI_CalculatorTests.swift。 您会看到类似这样的内容。 当我们通过上述两种方法中的任何一种将单元测试添加到项目中时,这是Xcode创建的自定义单元测试文件。 让我们快速看一下单元测试的一些重要组成部分。 在最顶部,有一个导入,即导入XCTest。 XCTest库旨在提供一个通用框架,用于在Swift中为Swift软件包和应用程序编写单元测试。 在它下面,您将看到@testable import BMI_Calculator 。 这是Apple帮助您将应用程序代码导入到单元测试目标中的方式,以便您可以运行测试。 使用@testable时 ,无需将应用程序成员身份中的任何文件提供给测试目标。 Apple为您做到这一点,创建了一个很好的干净的分隔。 要创建单元测试,您必须继承XCTestCase 。 通过继承它,您将覆盖它的两种方法,即setup和teardown 。 正如其名称所表明的,它们用于在开始测试之前设置您的测试,并在完成测试之后将您的测试分解。 […]
优秀开发人员的特性之一是预测项目中的更改并编写准备好应对这些更改的代码。 每个开发人员都知道依赖项注入和组合模式。 但是程序员经常不使用这些工具。 我的意思是,您经常会看到与网络一起使用的职责是一个单独的类,而另一个类则与数据库一起使用。 但是,较小的职责不会在单独的类中承担,而是属于某个模块的逻辑。 我认为这是不正确的,我将尝试解释如何进行更改。 如果您的困难模块看起来像是大正方形除以较小的正方形,那真的很好。 让我们尝试编写一些代码,然后以良好的方式对其进行重构。 我们的程序将包含一个图像和一个按钮,单击按钮后,该图像将带有alpha效果。 让我们编写代码。 首先,我们创建这个viewcontroller。 代码很简单,一切都很好。 现在,我想告诉您为什么此代码带有异味。 正如我之前所写的,将代码分成小块很重要,无论它是具有困难逻辑的大型服务还是仅用于呈现图像的助手。 在单独的类中,您需要分配所有单独的逻辑。 这是一个很好的例子,在单独的课程中,您可以处理图像。 下一步是重构。 🙂 最后一步是工厂。 这些控制器至少有两个配置。 Factory可以帮助您以一种更简单的方式生成新的控制器,并且通过这种模式,您可以随时为所有控制器装配零件。 有两种类型的图像渲染助手的工厂 上面,我试图向您展示,如果您在单独的类中组成甚至很小的逻辑块,也会更好。 我希望它是有趣和有用的。 如果您在代码中使用我的建议,那将是我的荣幸。
iOS项目分析1 使用sonarqube服务器docker映像和sonarqube扫描仪 前言: 今天的文章主要是分享,如何使用SonarQube来扫描iOS App Project, 来看看专案是否有隐藏的臭虫或怪味道(代码气味)。 主要使用到的技术与架构有: 采用docker的方式,来部署SonarQube Server在本机上(MAC OSX), 由于SonarQube需要使用一个资料库来储存扫描后的结果, 我们采用postgres资料库来做搭配,接者安装SonarQube Scanner。 最后就是扫描我们现有的iOS App Project,并查看扫描的结果。 实作过程: 首先要在MAC上安装Docker(安装参考连结),笔者使用的版本是Community Edition(CE)。 2.因为同时要使用两个docker image来做部署Sonarqube Server,所以笔者采用docker-compose的方式来做设置,将下面的程序代码存储到MAC上, 并命名为docker-compose.yml。 4.接者我们打开浏览器,连接网址『http:// localhost:9000』,已经可以连接到SonarQube Server,并使用记录帐密『admin / admin』来做登录。 5.首次登录,会出现教学模式,首先需要建立一个令牌,我们输入swift,并点击Generate。 6.这边要特别注意,这个令牌要自行保存,之后不会再次显示,如果忘记,只能删除再重新设置了。 7.接者选择后面要扫描的语言,这边我们选择其他=> macOS =>输入项目密钥=>完成 8.接者会出现后续扫描专案用的指令,也可以直接点选COPY到剪贴簿,画面有个下载按钮,点下后会连结到官方说明文件。 9.到此我们先点击跳过此教程,我们已经完成了SonarQube Server的安装。 总结: 今天介绍了采用Dokcer的方式,来部署设定SonarQube Server和Postgres DB,完成了之后要扫描iOS App Project的首要准备动作, 之后的文章里,将会实际介绍如何扫描一个专案的程式码, 并查看相关的报表,感谢您的阅读。 参考: Mac版docker Mac版Docker入门 欢迎使用Mac版Docker! Docker是用于创建容器化应用程序的完整开发平台,而Docker for Mac是… docs.docker.com 2. docker […]