Tag: 最佳实践

iOS的uma arquiteturarobusta em seu projeto iOS

Estéartigo pretende trazer ao seu leitor,软件开发者,软件开发者,可移动iOS应用程序的速记4 SOLID和KISS解决方案的重要性软件quando desejamos construir umasoluçãorobustaesustentável。 Arquitetura软件 从本质上说,使用高质量的语音软件可以通信和使用Carinho。 可以使用部分软件,也可以使用ganhar novas funcionalidades软件。 一种由软件组成的软件,它可以解决软件开发中的任何问题。 Neste linkháum materialtambémescrito por mim quepoderáte explicar mais sobre o problema。 通用软件安装软件鲁棒软件,依赖软件。 界面和接口的实现以及实现的接口。 EstePadrãonos ajudatambém是princípiodainversãodadependência (SOLI D )的代表。 蟒蛇 Como boaspráticas, POO的公用事业概念,通用的公用事业RXSwift公用程序。 Estaspráticas,pro deto的长期运作,nos ajudaram和SOLI D restantes的回应。 没有iOS的重要事项 Este artigoabordaráo或us e dedeçênciautilizando使用了一个故事板 ,并推荐了一个UI。 使用casovocênão,使用nãopoderáusar ométodo 准备(用于segue :) pois作为seguessão类,特别用于故事板 。 […]

使用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值。 […]

使用动画和不使用故事板的iOS登录/注销的最佳实践

众所周知,移动应用程序的范围正在日益扩大。 即使这样,登录页面/模块也不是一件容易的事。 因此,完成可测试,可重用和用户友好的登录编剧非常重要。 这篇文章旨在展示iOS登录/登出时的最佳做法,而无需情节提要,而是带有动画。 TL; DR 如果您只是对项目感兴趣,而不对故事感兴趣,那么这里是github存储库: ogulcan / iOS登录示例 iOS登录示例–一个示例iOS应用程序展示了如何在没有故事板 github.com的情况下处理登录/注销 分步指南 0.简介 考虑一下登录方案。 对于大多数应用程序,登录不是应用程序的真实部分。 通常,登录是要采取的步骤。 并且在必要时需要重新应用这一步骤。 例如,如果令牌已过期或用户更改了密码等。 因此,当应用程序启动时: 1.需要知道用户是否已登录或令牌未过期或用户未被禁止等。这意味着应用程序应检查相关服务。 2.如果用户正常,则意味着已登录,首页应显示为下一页。 如果用户不满意,则意味着应再次登录,登录页面应显示为下一页。 3.设置一些假登录,如果我们使用一些动画会更好。 这些是我要采取的步骤。 让我们开始。 1.检查用户 您可能希望在UserDefaults上保存用户。 否则令牌可能永远不会过期。 即使不推荐,事实并非如此。 因此,您可能不需要检查用户是否仍在登录。尽管我仍然建议您遵循以下步骤。 通常建议使用以下方法: 在didFinishLaunchingWithOptions内部的AppDelegate.swift中,检索用户数据并确定应显示哪个视图控制器。 并如建议的那样,让我们​​创建一个名为AppStoryboard的文件来定义每个故事板文件。 还有UIViewController扩展。 我们准备以更简单的方式启动每个视图控制器。 3.登录/注销操作并进行动画处理! 现在,如果我们运行该应用程序,我们将面临登录屏幕,因为我们没有任何令牌。 让我们实现登录和注销IBAction。 首先,我们需要一个更新RootViewController的方法/扩展。 每个IBAction使用钥匙串删除或保存令牌并设置视图控制器。 最后,如果我们运行该应用程序,则每个按钮都可以正常工作。 如果仅点击登录并重新启动应用程序,我们将面对主视图控制器。 精细。 为了更好,让我们添加一些动画。 首先,我们需要更新UIApplication扩展。 这是新版本: 准备使用。

代码最佳实践:为您的未来自我编写代码

2015年11月,我踏上了一个激动人心的新旅程,构建一个iOS应用,将iPhone上的图像和视频投射到连接Chromecast的电视上。 在Swift中,作为一个单独的开发人员,作为一个辅助项目,所有这些都在其中。 在这篇文章中,我将分享一些考虑因素和实践,这些因素和实践已帮助我在3.5个月内将代码扩展到4000行以上,同时又将技术负担降至最低,并最大程度地提高了可维护性。 快速预览: 就上下文而言,第一个版本的功能已完成约50%,因此我希望代码库最终会翻倍。 与我以前的所有应用程序和客户端项目相比,我估计在编写更多模块化代码而更少编写模块化代码的同时,我可以更快地增加价值- 至少两倍 。 事不宜迟,这就是我的工作方式: 口头禅:为维护性和未来自我而设计 力争绝不重复代码 始终将源文件保持在200行以下 代码本地化获胜。 凝聚 不要分散属于同一类的多个类代码。 使用类内部的扩展对确实属于一起的功能进行分组。 这使得在需要时更容易将事情排除在外。 适当地命名事物 最小化可变状态 仔细考虑对象图中的所有权 , 尤其是对于异步调用 使用ViewModels驱动UI更新 在添加新功能后始终进行重构 添加新功能后,请务必进行广泛的测试-在添加新代码之前先修复AKA错误 默认将所有内容设为私有 在Interface Builder中完成所有UI和布局。 代码不是您的表示层所属的位置! 错误处理对于应用程序设计至关重要 使错误对开发人员和用户友好 程序员错误应立即消除 奖励 :将开发容器用于我计划开源的自包含代码,例如这样。 到目前为止我还没有做 ReactiveSwift :我很想尝试一下,并在应用程序中利用Observables的功能 ,但是还没有机会。 TDD / BDD /单元测试-尽管我已经对依赖注入进行了仔细的考虑,并且上面的约束迫使我保持​​班级小。 集成测试。 由于我总是在添加新功能之前修复错误,因此这并不是一个强烈的要求。 但是,我为接收器应用程序构建了一个伪造/存根 ,以便在没有可用的Chromecast设备时可以测试大多数应用程序。 另外,我可以在运行时在假/真实接收器之间切换。 其他注意事项 对于这样的附带项目,我发现尝试每天取得一些进步是有益的,并且如果不进行任何工作 ,通常连续三天不能超过。 这使我始终专注于产品,并且我可以计划新的工作或考虑如何持续解决问题。 在单独构建此文件时,我可以使用一个Google文档来跟踪进度,错误,待办事项,里程碑和日常任务。 在现阶段,我发现这比拥有专用于每种情况的专用工具要简单,这在大多数组织中都是如此。 最后,我选择将其作为辅助项目进行构建,同时将大部分时间用于客户服务。 好处: […]

如果您的类型名称平庸,则您的代码将构成责任

我创建代码的过程如下所示: 研究目标的细节(学习) 提出实施计划(创建) 代码(单击并键入) 当我意识到我有一个错误的假设时,请返回步骤1(遗憾) 在进行编码工作之前,正确命名类型是计划中的最后一个障碍。 就像,嗯,我知道计算机不在乎我给我命名的类型。 机器解释指令时,所有这些都将被剥夺。 我的功能不会受到影响。 为什么我花了很多时间来确定角色以及事情如何融合在一起? 因为代码不仅仅适用于机器。 适用于必须充分理解它才能正确操作它的开发人员。 该类别中包括“未来”。 要做到这一点,就需要弄清问题集,并有足够的同理心,以使听众可以预期您选择的名字的所有含义。 真名 有一个古老的想法,即如果您知道某事的“真实名称”,那么您将拥有权力。 这是幻想中的常见现象,也是宗教故事的一部分。 以伊西斯和拉的故事为例。 伊希斯(Isis)是一位出色的治疗师,但只有知道她的真实姓名时才能帮助Ra。 他试图用“小写”的名字满足她的要求,但这仅使Ra未能解决核心问题。 一旦他放弃了他的真实姓名,她就可以治愈他。 这听起来像调试我。 如果您不知道所处理事物的真正含义,就无法解决该问题。 懒惰的标签将欺骗人。 您在阅读代码时让人们做的心理锻炼越多,使用它的认知就越消耗精力。 “是的,被称为 Provider 但实际上只是转换数据。” “该 modelId 不适用于该模型,适用于其他通用模型。” 但是,如果您真正知道什么是东西,则可以轻松地对其进行操作。 这很重要,因为将来必须更改代码。 我的理想是功能与代表功能的标签之间的绝对统一。 既然是理想的,我永远都不会到达那里。 想起名字时会出现回报递减的情况,但是值得花一些时间。 在清晰度和可读性之间取得平衡 某物的最精确名称可能是…… 绝对清晰。 把它收拾好。 该名称公然忽略了所有可用的上下文。 显然,这个例子很荒谬,但是添加不必要的限定词可能很诱人。 即使您觉得这个名字不是最好的,也最好在项目内部保持一致,而不要在两个约定之间来回穿梭。 一旦人们适应了您项目的标准,他们就会知道您在说什么。 一致的信息比冲突的信息要好,即使最终效果不佳。 同样,在引入新元素时也不要害怕重命名旧元素,以澄清它们之间的差异。 我们不是用石碑编码。 有些人梦想着将来验证自己的代码并期待未来的变化。 我宁愿使代码清晰地代表当前的情况,并在反映未来的将来进行更改。 这使我省去了很多我无法控制的事情。 我们控制双方 也许您没有花时间准确地命名某件事,因为它正在做很多事情…… 再塞另一种方法 有时正确的答案可能是重构基础实现以启用更好的名称。 我们都可以控制。 […]

测试,测试,1、2、3,测试

我是卫斯理大学(’18)的计算机科学和戏剧双专业,整个暑假都在Flatiron学校(FS)学习。 由于我一生都是学生,所以我习惯于进行测验,学习测验,在测验前拖延,以及受到测验的情绪影响(无论好坏)。 我认为大多数人都可以同意的事实是测试很糟糕。 但是,就编码而言,从长远来看,测试可以节省时间和金钱,并且可以产生更完善,更完美的应用程序。 要进行大量测试,对于一篇博客文章而言,测试太多了,但让我们对其进行分解。 我们都很熟悉XCode向我们提供的红色或绿色小菱形,其中包含支票或’x’。 我们都看着颜色从红色变成绿色,有时又回到红色。 最后,我们全都翻了个白眼,甚至在看到红色的眼睛时甚至撞到了墙上,而在看到绿色的眼睛时就为喜悦而跳了起来。 作为程序员,成功是保持我们编码的动力。 小小的成功是使头脑振奋值得的。 想象一下,如果等到所有编程完成后才知道代码是否按预期进行编译和运行,您会头疼。 这就是为什么测试是一种绝妙的做法。 测试使我们能够构建声音产品并对其功能进行检查。 对于新编码员,养成优雅的习惯很重要。 测试是一种习惯,可能会改变您对编程的看法。 编写测试可能有些繁琐,因此尽早开始很重要。 您越早开始编写和练习进行测试,就会越好。 测试方式 这是几个不同测试选项的简要说明。 Specta和Expecta是不错的选择,因为它们不需要您输入返回类型,并且可读性强。 “总体Specta和Expecta使得语法更加简单,易于编写和阅读。 这直接转化为开发人员的生产力” ( Harry Hornreich )。 XCode提供了一个测试构建框架,使编写测试更加容易。 XCode框架很好,但是IMO最多不过是万不得已,因为它总比没有好。 XCode框架的问题在于,无法知道您正在包括最有意义的测试。 有很多UITesting工具(例如XCode)作为唯一的测试源都不可靠。 有意义的测试 测试有各种形状和大小。 编写测试可能并不像提出测试那样困难。 例如,假设我们在Pig-Latin中编写代码字。 “ in”和“ as”之类的词保持不变。 如果程序员不熟悉该语言,则他们可能会忽略此细节,并让其代码返回“ niay”和“ saay”。 或者,他们可能会记住该规则,却忘记了以元音或以“ sh”或“ ch”开头的单词在其中辅音必须保持在一起的单词的规则。 这种代码中有太多的出错机会,这就是为什么使用测试有益的原因。 如果没有遵循的准则,没有规则,那么如何使程序员避免使程序充满错误? 测试的目的是消除运行时错误(与语法等编译器问题相对)。 测试不是为了弄清楚如何使用内存空间,也不是为了提高速度和效率。 测试以二进制形式进行:您通过或失败,直到通过。 有被迫失败的事情。 强制失败用于指示代码是否朝着不应执行的方向行进。 如果存在某种情况,您担心会发生并且不希望发生,那将是包括强制性失败的充分理由。 右BICEP Right-BICEP是我经过多年编程学习的一种助记符设备。 Right-BICEP是考虑编写代码的绝佳方法。 正确是指检查结果是否正确。 […]

SwiftLint —实现代码库一致和样式约定的方法

SwiftLint是用于实施Swift样式和约定的开源工具。 它是由Realm开发的。 您可以设置不同的编码样式规则,并在新项目和现有项目的开发过程中强制使用它们。 SwiftLint具有命令行工具,Xcode插件,AppCode和Atom集成。 因此,它始终适合您的开发环境。 如果您违反棉绒规则,它将向您显示警告和/或错误。 步骤1.安装工具 将快速线添加到Pod文件并执行Pod安装。 吊舱“ SwiftLint” 步骤2.在构建中运行脚本 “ $ {PODS_ROOT} / SwiftLint / swiftlint” 现在,无论何时构建目标,Swiftlint都会自动运行。 如果使用现有项目运行,则可能会有警告/错误。 这是因为使用了默认规则。 步骤3.自定义规则 您可以找到所有规则。 默认情况下,启用约70%。 您可以使用项目根文件夹中的.swiftlint.yml文件来自定义规则。 让我们看一下如何创建.swiftlint.yml文件以及配置文件如何工作: #您可以禁用默认情况下已启用的规则 disabled_rules: -标识符名 -force_cast #同样,您可以启用默认情况下已禁用的规则 opt_in_rules: -first_where #排除您不想掉线的目录 排除: -豆荚 – 快车道 #使用“ xcode”,以便在构建时,结果将显示在Xcode中 记者:“ xcode” #其他记者:json,csv,checkstyle,junit,html,表情符号 #默认情况下,“ function_body_length”规则在40时触发警告,在100时触发错误 #这个例子增加了3倍 function_body_length: 警告:120 错误:300 为您的项目创建.Swiftlint.yml 1 —打开终端: CD …到您的项目路径 2-创建文件: […]

您需要了解的有关iOS UITableView的所有信息

尽管已经写了有关如何正确使用UITableView ,但新开发人员甚至是经验丰富的开发人员仍然偶尔会遇到一些问题。 关于如何使与UITableView相关的代码更短,更好和更易读的内容,有很多有趣的文章以及方便的示例和最佳实践,但是以某种方式,我还没有看到所有建议的总览。 因此,我决定在这里列出至少在使用UITableView时要遵循的所有原则,但是如果您有任何添加或分享的方式,请在下面的评论部分与我联系🙂 0.分成几节 假设您有一些要使用UITableView实现的Profile屏幕: 第一个建议很简单:将表分成几个部分,以使用不同类型的单元格。 如果 indexPath.section == ProfileSectionIndex { //对个人资料进行处理 } 如果 indexPath.section == InfoSectionIndex { 整数索引= indexPath.row //用info [index]做点什么 } 如果 indexPath.section == FriendsSectionIndex { 整数索引= indexPath.row //与朋友做某事[index] } 比这更有意义,更容易使用: 如果 indexPath.row == 0 { //个人资料 } 如果 indexPath.row> 0 && indexPath.row <info.count + 1 { int index = indexPath.row-1 //我看到了很多次T_T […]

基础知识:Swift最佳做法

最近,我的伙伴对编程表现出了兴趣,因此自然而然地我推荐Swift作为一种很好的语言。 我花了很多时间亲自研究了Swift的最佳实践,我想确保她确实遵循了整个Swift社区的最佳/常见实践(我认为其中有些是最佳实践),并且没有从一些那里的教程。 即使这些教程为初学者提供了一个很好的起点,我也注意到一些确实困扰我的做法,我建议您反对。 注意 我应该指出, 这要取决于我在编写Swift代码时的最佳做法以及我在社区中的研究中所收集的内容。 我敢肯定会有人不同意,这很好。 我仍然会睡个好觉😉 首先,让我们从合作伙伴搜索初学者教程时遇到的编码实践开始。 我还将介绍与其他开发人员一起进行项目时所经历的一些经验。 1)冒号空间 尽管这看起来很小,因为它只是一个空格,但是它可以大大提高代码的可读性。 推荐的 命名:字符串 不建议 让名字:字符串 命名:字符串 让名字:字符串 简单。 在冒号之后,在类型之前添加一个空格。 2)花括号 当谈到花括号时,通常似乎是一个意见问题。 但是,在浏览互联网上的一些样式指南,Apple文档中的示例以及我个人的看法时,确实有一个赢家。 推荐的 如果isValid && list.count == 0 { …}否则,如果isValid { …}其他{ … } 不建议 如果isValid && list.count == 0 { …} 否则,如果isValid { …} 其他{ … } 要么 如果isValid && list.count == 0 […]

构建iOS单元测试的四个简单规则

您已经知道什么是单元测试,并且您可能已经在自己的iOS应用中编写了其中的一些测试。 那很棒! 现在,我们将进一步了解单元测试的结构。 当以某种方式编写单元测试时,它们是最有效的。 目标是以一种有组织的方式隔离组件和行为,从而使您深入了解应用程序的哪些部分有效,哪些无效。 只需一点技巧,您就可以编写单元测试来帮助您诊断问题,从而节省了比花费更多的时间。 这是创建测试套件时应遵循的最佳实践的简单列表。 隔离组件 好的单元测试不会尝试一次全部测试。 它一次测试一个组件的一种行为。 这是一个简单的经验法则。 每个要测试的组件都应该有一个XCTestCase文件。 该组件的所有测试都在该文件中。 在我的一个项目中,我有一个类来验证用户在文本字段中键入的薪资。 我将其称为PayrateValidator ,并将其命名为PayrateValidator.swift 。 在相应的测试套件中,测试PayrateValidator的XCTestCase子类称为PayrateValidatorTests ,包含该文件的文件称为PayrateValidatorTests.swift 。 这样一来,您也可以轻松地发现应用程序的哪些部分未被单元测试覆盖。 如果没有相应的测试用例文件,则很有可能没有该组件的单元测试 。 您还可以使用Xcode的测试覆盖率工具,我们将在另一篇文章中进行介绍。 关键是要有某种命名约定,以便您知道哪些文件可以测试什么。 等待。 我没有像这样的小组件。 我该怎么办? 对于初学者的iOS开发人员而言,这可能很难。 如果您没有MVC或MVVM等设计模式的经验,则您的应用程序可能没有任何隔离的组件。 您可能拥有一个巨型视图控制器,其中包含所有应用程序功能。 没办法判断。 我们都必须从某个地方开始。 我自己写了很多庞大的视图控制器。 编写好的单元测试的关键是要理解,您需要将应用程序分解成可以测试的较小部分 。 例如,如果视图控制器进行网络连接,请提取该逻辑并创建一个可以测试的单独的网络服务组件。 如果您不知道从哪里开始,请继续阅读一些常见的iOS应用程序设计模式,例如MVC或MVVM。 只需遵循这些步骤,您就会自动获得一个具有单独组件的应用程序,与庞大的视图控制器相比,这些组件更容易进行单元测试。 隔离行为 假设您已经隔离了一个组件。 您有一个与其关联的XCTestCase文件。 凉! 现在您需要测试。 结构良好的单元测试套件将每个组件分解为行为,每个行为都有其自己的功能来测试它们。 假设您正在编写Rick Astley的人工智能版本。 只是奠定基础,您可以像这样模拟他的一些行为。 这必须是Rick Astley的最笨拙的AI版本,但是也许这是您永远需要的所有编程。 在您的测试用例中, 通用约定是在单独的函数中测试不同的行为 。 它应如下所示。 在这里,我们只是断言,Rick […]