Tag: 软件开发

Usei Clean Architecture num projeto de duas telas e me arrependi …

ATENÇÃO-Nãoirei abordar或XYZ防守者,nãoéo intuito desta publica por球场,mas sim falar sobre umaexperiênciaque tive dan。 重要信息后,vamos ao que interessa。 Muita classe e pouca entrega? 喜剧明星将在美国清洁运动中发挥重要作用,罗南·道格拉斯·门德斯(Ronan e Douglas Mendes),设计风格的设计者 清洁的原则上的原则性影响者 清洁工,软件工程师,软件工程师,软件工程师,软件工程师,软件结构和设计指南,以及优秀的专家arquitetura etambém设计图案napráticae logo de caravocêvêessa imagem, levanta-se evêque possuiinúmerascamadas quevocênãoestáacostumado,nãoé? Esse semper foi um ponto que discuti muito com Ronan e Douglas,Pois me dava aimpressãoque que que que fazer […]

最佳SoftwareHut的iOS实践-SoftwareHut

尽管2017年Android应用程序的下载频率是iOS应用程序的两倍,但后者也受到广泛欢迎。 但是,Apple设备的普及率在增长,对iOS开发人员的需求也在增长。 如果您是或想成为其中的一员,那么本文适合您,因为我将向您展示最佳的iOS做法。 他们将帮助您开发更好的应用程序。 准备? 我将上述做法分为以下几节: 通用技术概念 代码质量 性能 构架 建筑 其他有用的提示和技巧 在本节中,我只为您提供三个词: SOLID —单职责原则,开放/封闭原则,Liskov替代原则,接口隔离原则,依赖反转原则 吻 —保持简单,愚蠢 干 -不要重复自己 首先,您应该遵循为Swift和Objective-C准备的代码样式指南。 这很重要,尤其是当只有几个程序员在开发同一应用程序时。 这就像成立一个音乐乐队一样-如果每个人都做自己的事,他们将不会成功,开发团队也是如此。 如果您可以在深夜重复这些指南中的建议,则可以继续进行下一步-自动执行构建。 使用Fastlane将每个项目配置为自动生成,然后将其上传到HockeyApp。 最后,在单个视图控制器中避免大量代码。 您可以使用VIPER或MVVM体系结构来完成此操作。 尽管iOS设备运行速度非常快,并且无论它们有多老,它们都可以正常运行,但是您的应用程序无法降低它们的速度。 您可以通过以下方法提高应用程序的性能和可维护性: 尝试避免使用外部UI库 尽早确定最低iOS版本-记住检查旧系统上新的iOS API是否得到正确处理 集成崩溃报告工具 使用这些框架可以使您的工作更轻松,更快和更好。 联网 AF网络 Alamofire 楷模 对象映射器 披风 依赖注入 弹射 台风 专卖店 钥匙串访问 领域 通过逻辑结构来开始您的项目。 它的结构应反映您存储库中的目录结构。 关于文件夹名称-它们应该为小写字母,并且空格应替换为“ _”。 使项目的层次结构反映您的体系结构,即: UI:包含对自定义UIView,UIViewController和容器的引用: 视图:自定义UIView,UITableViewCells等 View_controllers:UIViewControllers 应用程序:AppDelegate Supporting_files:info.plist和其他描述应用程序的文件 […]

TDD是“落后”

在向同事教授TDD时,经常会出现相同的问题: 我们从哪里开始开发软件? 这个问题导致了很多讨论和理解TDD的艰辛。 我看到了从哪里开始的不同方法,但是大多数情况下,人们倾向于使用用户界面。 这样做的原因是能够执行交互并查看他们是否实现了正确的行为。 在TDD中执行此操作非常繁琐。 您从一个按钮开始,然后检查它是否为nil。 好的,是这样……按下按钮时,我想查看用户搜索的电影列表。 嗯,我还没有测试,因为我还没有任何数据! 该怎么办? 一种选择是传入伪数据,并在每次添加一些代码时将其逐段替换为实际数据。 这似乎很好,直到您意识到需要大量工作并且开发速度缓慢。 另一种选择是不以用户界面开头。 而是从网络请求开始。 从这里开始,您的测试将确切知道预期的内容并正在测试实时数据,而不是模拟(当然,下一步是对请求进行存根,但我们还没有完成)。 编写完请求后,我们可以添加解析,然后可以添加存储等。通过这一切,我们知道我们拥有的工作代码不基于假设。 自下而上的一个问题是股东。 他们希望看到您软件中的更改,而他们看不到创建网络堆栈。 不要陷入模拟所有数据并仅创建用户界面以使股东满意的陷阱。 在某个时候,您将不得不编写其余的内容,然后他们将抱怨更多,因为开发速度很快,现在没有新内容了。 除了默认的TDD做法,这没什么别的主意: 从您所需的最小代码开始,并为此编写测试。 结论 让这个主意变得不那么容易。 它要求纪律首先编写测试,而不添加不必要的代码。 仍然遵循这一纪律并坚持下去将会产生巨大的成果,上面所写的想法只会帮助您入门。 实践TDD本身将得出这个结论。 如果不是这样,我很想听听! Next:Swift中的高级模拟 上一篇:联网怎么样?

担任iOS工程师30个月。 给新人的提示。

30个月 7个应用 2个大应用 兼职自由职业者 全职iOS工程师 长期玩家 这是我给新手的iOS开发提示。 以斯威夫特 Swift vs Obj-C我应该首先学习哪个? 我的答案直接针对Swift。 使用Swift学习,播放和开始新项目。 除非您有理由使用Obj-C。 例如,维护旧应用程序。 警告-不打算在Obj-C中启动您的项目,以后再迁移到Swift。 迁移比您想象的要难。 知道生态系统 什么是流行的JSON库? 我的应用程序应使用哪个云数据库? 目前发生了什么事? 您应该了解应用程序的工具/库/框架/堆栈。 不要成为一个孤独的程序员,自己编写一切。 有人已经贡献了这些作品,使您的生活更轻松。 选择并使用它们可以提高生产率。 对于开源库。 搜索` awesome-xxx`。 例如,` awesome-swift` ,` awesome-ios` 。 使它工作,使其正确,使其快速 我一直相信这个概念。 软件开发不是一次性的工作。 好的软件是经过多次迭代制作而成的。 当您第一次做某事时,可能并不如您所想的那样好。 但是,请放心,花些时间重新访问它,并使它变得更好。 只要记住你在做什么。 经验会为您提供帮助。 下一次转到最后一步比您想象的要容易。 学习建筑 看看其他成功的应用程序。 看看它们是如何制成的。 不仅是应用程序方面,还是整个系统。 建筑角度将提高您的工艺水平。 有很多开源的iOS应用。 电报,Firefox,维基百科,WordPress,VLC,电线。 github / open-source-ios-apps是一个很好的资源。 实验 开发应用程序时。 您可能会想出很多主意。 […]

快速提醒Swift中的SOLID原则

如果您开始从屋顶盖房子会怎样? 墙壁易碎,倾斜角度,基础不稳定。 这样的房子寿命不长。 该应用程序具有相同的趋势,并取决于开发人员的资格。 在我们的领域中,砖是一种编程原理,对系统有不同的影响。 我认为SOLID是基本级别。 本文的目的是在Swift中提供快速指南或知识更新。 让我们用好与坏的情况来解释该缩写: 1. 单一责任 -每个对象应仅对一种责任作出响应。 换句话说,概念模块/类/结构必须响应一个动作。 单一责任-流程不畅 单一责任-流动性好 在这里,我们仅处理OrderType数据,并且可以在没有任何其他条件的情况下对其进行更改。 2. 开闭式 -实体必须开放以进行扩展,但必须封闭以进行修改。 打开关闭 –   流量不好 在我职业生涯的初期,我将更改内部功能,并且可能在数据库处理以及将现有数据相互之间导出时遇到问题。 开闭式-流动性好 更好的方法是在OrderStorage下创建子类并重写方法或准备协议,然后在OrderStorage实现正确的数据处理。 换句话说,我们无需内部修改即可扩展存储功能。 3. Liskov替换 -任何对象都可以由其子对象替换,而无需更改应用程序设置。 简单地说,如果我们将基类更改为其子应用程序,则该子应用程序将保持稳定,并且新问题不会对其他部分产生影响。 Liskov替代-流动不畅 在那里,我们违反了LS原理。 我们通过添加以下条件来更改保存功能: order.products必须具有计数验证。 基本RealmOrderStorage不会这样。 有两种解决方案: 向基类添加新参数(也更改协议) 更改NewOrderStorage类的保存接口。 Liskov替代-流动性好 在这里,我们不违反基类接口的契约,并且可以在任何地方使用新的子类代替它。 Swift的一项强大功能是面向协议的程序设计,我们可以在不进行子类化的情况下进行工作,但可以通过合同支持设计。 4. 接口隔离 -许多专用接口比一个更好。 它们既大又通用。 它有助于在使用的项目中划分功能的不同部分,并且不会在那里实现不必要的方法。 转到我们的示例: 接口隔离-流量不良 在这里,我们有几种与产品相关的其他方法。 那些没有折扣或尺寸设置的产品该怎么办? 我们可以陷入陷阱。 接口隔离-良好的流动 在这里,我们可以使用基本接口ProductType进行操作,并根据需要设计其他实例。 5. 依赖倒置 […]

单元测试中的存根网络调用

确保您知道您的回应 几年前,我被要求支持公司的其他分支机构。 他们的iOS开发人员很快就离开了,他正在开发的应用程序即将完成。 我去那儿修复了大约10个错误……它以50多个问题结束,但是我们都知道,这在开发过程中很正常。 尤其是当您有一位对利润非常挑剔的出色设计师时。 无论如何..我到了那里,想测试一些网络代码。 我以为我既年轻又年轻(大约一年前才开始使用Kiwi),所以我可以使用这些方法,然后继续前进。 我的一个同事不太喜欢这个主意。 她建议使用当前存在的依赖项,而不要引入新的依赖项(在此期间,我们使用的是XCTest,而不是Kiwi)。 那么她的解决方案是什么? 她已经在使用KIF,并且针对后端运行UI测试并不好玩。 而是使用OHHTTPStubs。 使用此库,您可以拦截网络请求并返回所需的任何内容。 我的猜测是,它在NSURL上使用方法刷新进行拦截,但是如果有库,为什么要自己做。 如何使用 编写拦截器非常容易。 只需指定要拦截的主机和路径并返回响应即可。 我倾向于在包含我的拦截器的OHHTTPStubs上使用类方法创建扩展。 响应是您的JSON对象。 根据要返回的内容,您可以使用库提供的初始化程序。 我还创建了一个匹配器,以便于检查是否调用了正确的网址。 OHHTTPStubs提供了一些,但是有时您必须编写自己的。 这是通过创建OHHTTPStubsTestBlock来完成的。 这是一个闭包,将在其中传递一个RequestObject并返回一个Bool。 与往常一样,要设置我们的套件,我们可以使用beforeEach或beforeSuite。 只是不要忘记事后清理! 所以请不要忘记: OHHTTPStubs.removeAllStubs() 结论 我喜欢这个图书馆。 这是您进行单元测试所需的全部。 几个月前,我向团队介绍了它,从那时起,我们的网络测试就针对OHHTTPStubs进行了。 使用OHHTTPStubs使我们能够测试整个应用程序,而不必在生产系统中引入任何测试代码。 这样,我们可以确定,只要后端api不变,我们的应用程序就会按照我们期望的方式运行。 下一步:TDD向后 上一篇:测试苹果MVC

我应该使用多少个测试?

我在开始撰写此博客时就对如何提高应用程序质量进行了解释。 在途中,我们遇到了许多不同类型的测试。 但是,我们应该对每种类型的应用程序投资多少? 一如既往,需要平衡。 这次是关于我们可以投资多少与将创造多少价值(不是总是这样)。 因此,让我们详细看一下。 单元测试 我们已经对单元测试进行了很多研究。 如何在Objective-C,Swift中做到这一点以及如何测试Apple的MVC(测试UIElements时不要忘记在UIViewController上调用controller.view)。 单元测试的优势是什么? 快速 可靠(如果操作正确;) 涵盖很多部分 具有所有优势,还有什么要错过的? 他们是孤立的 不要测试零件是否装配在一起 最重要的是他们要快。 不论是10还是1000,都没关系。它们在不到几秒钟的时间内运行。 开发人员没有理由在提交更改之前不运行它们。 这很简单。 我们拥有的越多越好。 这也是我们在TDD中使用它们的原因。 确保独立编写它们。 不要使用数据库或网络。 而是存根吧! UI测试 UI测试也是一个主题。 我们已经看到了多个框架来实现它们,以及如何使它们独立于任何后端。 优点: 测试组件 您可以将它们用于验收测试 它们的行为类似于用户 与往常一样,您可以期望它们有缺点: 慢 脆弱(对应用程序的每次更改都会破坏它们) 慢(我已经提到过吗?) UI测试需要大量维护。 它们可能会随时中断,即使只是由于模拟器无法连接到Xcode也是如此。 因此,它们显示的每一次失败,可能都不是您应用程序中的错误。 您需要对其进行调查。 最重要的是,它们运行非常缓慢。 即使当告诉他们不要在测试开始时重新启动应用程序,使用模拟后端并删除动画(您仍然不应该这样做)时,它们也会永远占用。 目前,我们的50个测试需要15分钟以上的时间才能运行。 每次更改后,没有开发人员会这样做。 因此,您的CI需要。 拥有它们真是太好了。 但是请注意,它们需要大量工作。 由于测试很慢,因此不应有比单元测试多的测试。 验收测试 我们已经研究了无UI的验收测试。 使用这种类型可以实现令人难以置信的目标。 他们甚至可以帮助您与客户合作并以更精确的方式确定需求(如果您想了解与客户合作的方式,请查看BDD)。 那么为什么要使用它们: 快速(与UI测试相比) 测试整合 […]

iOS上的KEA Place是一款出色的AR应用程序,但其成功还有更多

自2013年以来,宜家就一直在尝试让客户使用App将家具放置在自己家里的方法。自iOS 11和ARKit发布以来,宜家App一直被视为该技术的展示。 宜家的“地方”应用程序很棒,但并非出于您可能认为的原因…… 技术栈 IKEA Place使用ARkit来检测地板的水平平面以放置家具,并利用Core Motion和视觉惯性测距法。 它不是唯一使用这些技术的应用程序。 他们已将其与Unity引擎(支持ARKit)配对。 宜家似乎已经充分利用了自己作为早期技术适配器并将其应用于AR的经验,这似乎仍然是未来的巨大机遇。 但是在2019年,感觉这已经不是曾经的移动设备的创新应用了。 宜家还做了哪些工作才能使Place变得更好? 下载MNC应用 宜家允许从Apple的任何App Store中安装该应用程序,并在安装后更改语言和本地化选项,并包括宜家运营的所有地区。 即使您使用的不是母语,设置页面也易于使用。 更改语言时,界面不会在更新时被锁定。 这意味着我无需更改App Store即可看到SGD(新加坡元)的价格; 精彩! 不仅如此,对语言的更改不需要重新启动,甚至允许用户在语言更改时继续使用该应用程序。 这些功能使下载应用程序的摩擦降低,并使卸载率保持较低。 这不是他们所想的。

使用KeyPath在Swift中进行无缝数据操作

本文是对 KeyPathKit 框架背后思想的详细介绍 。 如果您喜欢您将要阅读的内容,我敦促您看一下图书馆必须提供的所有功能😉 非常感谢 JérômeAlves 向我展示了我将在下面描述的一种方法。 Swift 4引入了一个称为KeyPath的新概念。 它允许开发人员处理特定类型的特定属性。 稍后,他们将能够针对指定类型的对象评估此句柄,以便为其属性获取值: 最重要的是,此过程完全是类型安全的,并且与struct和class都兼容,并且其语法灵活而简洁:您可以使用类型推断(例如\.count将是有效的)并且可以轻松地链接属性(例如\UIView.layer.cornerRadius是有效的KeyPath ) 现在考虑以下示例数据: 用例进行改进 假设我们要过滤掉lastName不是”Webb” 。 使用filter ,我们可以按照以下方式编写: 现在,我们尝试重写此代码,以便使用KeyPath而不是闭包: 呼叫站点看起来已经干净了一些,而且在不关闭的情况下也更易于阅读。 但是最好的还没到。 现在想象一下,我们想要保留其lastName遵循使用正则表达式指定的特定模式的值。 现在,如果我们只想获取名称以”son”结尾的联系人,则可以如下编写: 这种语法看起来确实很干净,并且比闭包可以实现的可读性高。 谓词介绍 让我们回到第一个用例,再次比较两种语法: 第一种语法具有直接使用运算符==的优势,当人们快速浏览代码时,该运算符提供了宝贵的视觉线索。 第二种语法的优点是不需要闭包,这使代码更加简洁。 如果我们将它们的优点结合在第三种语法中怎么办,那将使我们能够编写: 当然,那看起来不错! 👍 那么如何实现呢? 首先要开始的是运算符== 。 在Swift中,我们习惯于在Equatable类型的上下文中定义此运算符。 在这种情况下, ==返回Bool 。 但是完全有可能重写==以使其返回Bool以外的其他值。 为了解决我们的问题,我们将编写一个返回Predicate的重载。 什么是谓词? 您可以将其视为表达对特定类型的值的约束的一种方法。 一旦定义,就可以针对指定类型的特定值评估谓词。 首先,我们定义一个类型来实现KeyPathPredicate : 然后,我们重载==以使其采用KeyPath并且常量具有参数并返回KeyPathPredicate : 最后,我们定义一个与KeyPathPredicate一起使用的filter版本: 而且,瞧,我们现在可以使用目标语法来编写代码🎉 结论 为了使本文的长度合理,我仅考虑了一些基本用例。 但是还有许多其他用例需要讨论。 例如,最好重载运算符~=以便根据正则表达式评估String值。 […]

丹沙里面向发展

尽管有这个标题,我在这里不会谈论任何新的范例或任何新的编程模式,而是要谈一种态度,以及我们如何运用这种态度来改进Zattoo中的iOS App。 如果您不知道Danshari的概念,它是由三个汉字组成的日语组成的单词,其顺序为:拒绝,处理和分离。 几年前,我在日本旅行时发现了这个概念。 我真的很喜欢Danshari的概念,因此我会在日常生活中尽可能地遵循它。 简而言之,Danshari可以被定义为避免与物体产生任何情感联系,与占有分离以及摆脱生活中的混乱的想法。 在您生活中的一段时间内,对象可以看作是有用的工具,然后被扔掉。 一旦不再需要它们,那就结束了。 您不必再保留这些工具,不占用大量空间,减少移动自由度,或者在某些情况下(如果您拥有昂贵的财产)会增加被盗的恐惧。 可以想象,在生活在资本主义世界中的Danshari的概念确实很难应用,每个人都想拥有市场上最大的汽车,最大的房屋和最新的设备。 当然,如果确实需要这些对象并且它们可以解决您的生活中的问题,那也不错。 Danshari作为开发人员 正如我所说,我会尽可能地遵循Danshari的原则,这也意味着我会尝试将此概念应用到我作为软件开发人员所生活的那一部分。 将Danshari用作开发人员到底意味着什么? 容易,只需从项目中删除任何不需要的组件,即可节省代码和资源。 代码和资源是解决问题的工具。 而且,由于项目的发展,这些工具中的一些最终可能变成多余的。 您现在必须纳闷,这是什么意思,以及您实际上可以从项目中删除什么。 毕竟,添加所有内容都是有原因的,不是吗? 为了更清楚地说明,我将根据我的个人经验提供示例列表,但是请您参考它,不要害羞,我相信一旦开始,您会发现越来越多的情况将Danshari应用于您的代码。 ·在无处注释的代码中,代码段无缘无故地保留着,可能是由于某种重构的结果,没有人敢于仅仅因为谁知道有一天这段代码可能有用而删除了…… ·不再需要未使用的类和方法 ,App Code是一个出色的IDE,可发现您App中所有这些冗余元素。 ·实际上从未使用过的冗余导入 。 应用程式程式码也可以在这里提供协助。 ·添加到Podfile中的未使用的依赖项,不再由应用程序使用。 · 默认实现 ,通常在内部带有注释代码。 添加它们是有原因的,但是一旦其行为恢复为默认状态,就不会将其从项目中删除。 · 预定义的模板,什么都不做。 您是否对以下代码熟悉? · 未使用的字符串,不再使用的字符串也应从Localizable.strings中删除 ·与以前相同, 未使用的图像是否由应用程序的最新版本使用了所有xcasset? · 具有可推断的数据类型或默认修饰符的定义 · 不再需要过去可能在执行某些任务时有用的脚本 ,这些脚本无人可做。 · 巨大的许可证标头,添加到项目的每个文件中。 除了养活自我的标头根本没有增加任何价值。 在某些情况下,您甚至可以找到代码少于许可证的文件。 免责声明:由于法律问题,在某些情况下,例如在公开公共API的框架上工作时,实际上确实需要这些标头。 · 冗余和错误的注释会在代码中添加明显甚至错误的信息 · 旧代码 由于语言的发展,不再需要。 综合属性,私有方法的预定义等… […]