当心! Story ini menggunakan类似物Superhero dari DC Comics。 Sebagai程序员,Pasta sudah terbiasa dengan 面向对象编程 。 Dimana paradigma pemrograman itu banyak memberi solusi untuk membuat arsitektur 可重用 代码 。 Namun OOP sendiri juga memiliki beberapa kekurangan,Yang kemudian pada tahun 2015,Swift memperkenalkan 面向协议的编程 ,yang bisa menangani kekurangan tersebut。 Definisi 协议 sendiri adalah : 协议定义了适合特定任务或功能的方法,属性和其他要求的蓝图。 Setiap 方法,属性,dll,协议,类,类, 要求, 协议 。 […]
如今,视图代码正成为iOS社区内部的新炒作。 这并不是什么新鲜事物,从许多方面来看,这种方法都是对iOS起源的回归,在iOS中,视图是用代码创建的。 如果您还记得Xcode的第一个版本没有接口构建器。 例如故事板诞生得更晚。 在与几个在应用程序中采用视图代码的开发人员交谈后,我对这个主题非常感兴趣,并声称有很多好处。 好处 更好的团队合作,避免使用故事板| xibs冲突。 更好的构建时间。 有了明确的建议,代码往往变得更加模块化,可重用。 更容易测试。 维护和发展代码库更为容易。 今天,我将迁移在一系列帖子中创建的Marvel应用程序( *您可以在此处查看该系列的第一篇文章)以查看代码。 与大家分享我在此过程中获得的经验,观点和教训。 您可以在此处使用查看代码检查项目存储库。 该方法 .. 迁移查看代码不是必须“全部”完成的事情,您可以首先开始迁移代码的一小部分。 我已经开始了迁移细胞的过程。 他们已经生活在故事板的分开的xib中。 因此,让我们进行比较。 使用XIB 第二 完成此步骤后,一切都应正常工作,我将在此处布置另一个控制器,以便我们检查差异。 不使用ViewCode 使用ViewCode 大家可以注意到,控制器的大小几乎相同,但是第二个版本的责任要比第一个少得多。 许多人被转移到更合适的地方。 更不用说了,不再有IBOutlet或IBActions,强制展开等。测试此新ViewController也是容易得多,因为我们不必从情节提要中将其引入。 所以.. 我非常喜欢这种经历。 我一定会探索视图代码并将其带入未来的项目中。 将来,我将发表另一篇有关测试+查看代码的文章,以及我们如何重构旧奇迹的应用程序测试以与我们的新设计一起使用。 也就是说,这是我查看代码的第一种方法。 还有更多的工作要做。 现在,我想听听您关于该主题的经历,痛点,其他设计,模式等的信息。 分享您的想法,作为回应。 我真的认为这可能是个很棒的讨论! 与往常一样,任何想法,疑问或反馈都值得欢迎。 =) 附:如果您喜欢这篇文章,请在Twitter上分享,或在中级推荐,或两者都=)。 这确实有助于我吸引更多人。 非常感谢 ..
您可以在这里找到我以前的文章的链接: 常量,服务管理器和API身份验证。 我的第一个Swift App medium.com 在上一篇文章中,我创建了一个名为“服务管理器”的类,并在其上添加了一些功能以使用API验证应用程序。 今天,我将在此处添加其他功能,以搜索公交专用道并获取所选车道的公交位置。 我将从那里添加一个名为makeHttpGetRequest的函数开始,这次回调将返回JSON和错误字符串。 * JSON类型是SwiftyJSON容器的一部分。 现在,使用searchForBus函数。 在测试此代码之前,只需要对一个问题进行排序。 在巴西葡萄牙语中,这些单词可以具有特殊字符,例如:Pompéia,Petrônio,Carrão; 由于搜索不支持这种字符,也不支持Itaim Bibi等组成的名称,因此,我将创建一个基本的regex函数来替换这些单词。 在此正则表达式上,我将传递用户键入的文本,如果出现这些特殊字符,则将替换它们,并且,该请求不支持空格,该方法在此方法中被+符号替换,因此,如果用户搜索Itaim Bibi ,则该请求看起来像Itaim + Bibi 。 此功能将提供给搜索项的最后一种处理是将单词返回为小写,因此最后它看起来像是itaim + bibi 。 最终请求网址应如下所示: http://api.olhovivo.sptrans.com.br/v0/Linha/Buscar?termosBusca=itaim+bibi 现在,是时候在AppDelegate上测试此代码了。 首先,我要对应用程序进行身份验证,然后调用该函数来搜索公交车,并传递“ Itaim Bibi”一词。 这是此请求结果中的一个对象。 大! 现在我有了代表公交专用道的对象。 现在,我将在服务管理器上创建一个函数,该函数将获取该通道上所有总线的位置,我将使用整数“ CodigoLinha”在请求返回时表示的通道代码。 我将接收到的整数转换为字符串,以使其成为我在此函数上创建的请求URL的一部分。 让我们在AppDelegate上对其进行测试。 这段代码看起来一点也不好 ,但是至少我能够测试所有请求并看到一切正常,得到了预期的结果,现在我可以删除这些代码行了。 这是结果。 再次有关于API的文档。 Áreade Desenvolvedores SPTrans – GTFS 作为需要信息的API的HTTP协议的使用,可以作为一种必要的信息。www.sptrans.com.br 不幸的是,在此特定结果上,文档没有说明这些值是什么。 让我们尝试猜测: “ hr”应该是搜索时间或上次更新时间。 “ vs”应该是公交车位置的数组 “ […]
当我被公司聘用并开始以敏捷的方式工作时,我还必须跟踪自己所做的一切,并在Jira时间表中进行报告。 我理解它们,但这对我来说真的很痛苦,我当时使用钢笔和贴纸来做,我忘了记笔记,松开它们或者它们不完整,所以最终我的报告只是一个猜谜游戏。 再加上我在月底将它们写到时间表中的事实,您可以看到令人沮丧的事情(时间表可能是最糟糕的软件)。 我决定结束这场混乱,开始写吉拉西奇。 我应该在应用程序中记录我完成的任务,他应该根据每个完成的任务的时间戳计算我在每个任务上花费的时间。 这个简单的想法立即消除了我的挫败感。 但这还不够,在2年的开发,使用和测试过程中,它演变成了一种产品。 现在可以: 自动跟踪我的任务,无需手动添加。 使用另一个名为Jit的工具基于git commit进行此操作,该工具也解决了其他一些问题。 跟踪每日Scrum会议。 也浪费时间 跟踪代码审核时间 追踪午餐时间 它基本上跟踪程序员将在工作中自动执行的所有操作。 每当您希望在Jira时间表中编写它们时,都可以转到“报告”选项卡,然后将粘贴好的任务分组复制并为您计算时间。 我正在自动执行此步骤,可能不容易或不可能,但我也会在可能的地方添加其他服务(如果有,请等待您的建议) 还有一个iOS应用程序也可以查看您的任务,专为Scrum会议而设计,您只需要查看它们即可,而无需进行编辑。 这是我的另一个问题,在Scrum会议中停电,我只是不记得自己在做什么。 我从一开始就使用Parse编写了这篇文章,直到Facebook杀死Parse为止,这一切都很轻松。 我花了一段时间没有iOS应用程序,所有内容都写得很差,无法切换后端。 当时,我们正在学习有关工作中的干净架构的知识,然后我立即开始在应用程序中应用这些概念。 现在,它在Mac上使用Sqlite,在iOS上使用CoreData和iCloud对其进行同步。 整个应用程序的体系结构允许我随时更改此位置。 代码在git上供个人使用。 谢谢,让我知道您的想法。 时间跟踪正确完成 Jirassic可以开箱即用地跟踪会议和午餐,但是如果您是程序员,则可以使它更多地自动化,您可以… www.jirassic.com ralcr / Jit Jit –连接到jira并通过仅指定任务号来创建分支的Git命令行工具 github.com Jirassic在Mac App Store上 阅读评论,比较客户评价,查看屏幕截图,并进一步了解Jirassic。 下载Mac OS X…的Jirassic… itunes.apple.com
关于如何在需要时reduce() method earlier if you want退出reduce() method earlier if you want reduce()是Swift标准库中非常有用的方法。 它的工作方式类似于for in loop(实际上是一个in),但是它专门用于从集合中的元素中计算单个值。 仅有一个微妙的区别-我们不能这样做: 电脑和智能手机速度很快,但我们不希望它们浪费时间并且表现得像那只狗。 在我们的案例中,我们真正需要的是3次迭代… 在reduce方法的重载(如原始声明中那样)中,我们可以看到我们在重载中实现的nextPartialResult可以引发异常,所以为什么不利用它–在传递条件时引发异常,如此处理它不会逃避我们扩展的范围并返回结果。 为了实现它,我们需要一个符合Error类型,它将一个Result对象传递给catch闭包: 为了完成它,让我们有一个完整的实现,它使我们不仅可以基于部分结果,还可以基于集合的当前元素来做出“破坏它或做出它”的决定(尽管如果有的话)像element == someThing您应该在reduce之前使用prefix(while:) 。 这里是: 它还有另一个变体,如果您希望在给定条件为真的情况下减少收款,则应使用它: 它给出了不同的结果,因此,当您不想包括以上条件的元素时可以使用它(因为until变体才是这种情况): 就是这样了! 希望您喜欢我的第二篇文章。 随时尝试一下,您可以在这里找到示例游乐场。
如何构建滚动堆栈容器并保持内存的正常使用。 如今,移动用户界面已成为一项复杂的工作。 列表(表,或更常见的是集合)可能包含不同种类的项目,从而在单个滚动交互中显示了大量数据。 以IMDB应用程序为例; 主页包含: 带有突出显示的电影的水平列表 重点新闻 带有照片库的水平列表 与附近电影的水平列表 即将推出的电影的另一个水平列表 新闻垂直列表 …是的,还有更多东西 单个垂直滚动视图中的所有内容! 通常,如果您在编写此类代码时仍然缺乏注意力,则视图控制器可能会成为大量的意大利面条式代码,将多个职责组合在一起,并使您的应用程序更脆弱且更不可测试。 那就是Massive View Controllers的世界,以及诸如Viper,MMVM和其他几种替代体系结构背后的主要原因。 关注点分离(以及“单一责任原则”)是一种将计算机程序分为不同部分的设计原理,这样每个部分都可以解决一个单独的关注点。 天真的方法 将这类布局带回家的最简单方法是使用表或集合,然后将对象放入内部(即,内部布局复杂的富单元格); 尽管它实际上只适用于很少的对象,但具有相当数量的异构对象,但最终的体系结构却是您可以避免的疯狂庇护。 JustEat UK的ScrollingStackViewController类使用UIScrollView内的UIStackView的方法来模拟Android的垂直布局。 正如自述文件所述,它是在构建数量有限或动态且内容丰富的滚动控制器的情况下的一种更合适的方法。 但是,当您的布局变得复杂时,可能导致相关的内存占用或不可持续。 在一个或多个子视图控制器包含垂直表或集合的情况下。 实际上,为了使它们正常工作,您需要扩展这些视图以显示整个内部表/集合的内容,并以内部单元格的巨大分配作为结尾(即使当前不可见):您到表的缓存。 请参阅以下示例: 高效方法 以下工作的灵感来自Ole Begamnn的一篇旧文章“ Scroll Views Inside Scroll Views”,我几年前在CreoLabs上为CreoKIT制作UITableView克隆时曾大量使用它。 主要区别在于它可以与UIViewControllers并可以正确管理,然后这些容器是UIScrollView子类的容器(如UITableView或UICollectionView ); 是的,它适用于Swift 3+。 基本上,这是一个UIViewController ,它期望在其中包含UIScrollView (您可以通过情节提要进行设计并链接插座,因此可以自由保留自己的自定义布局)。 它允许实现以下目的: 将多个UIViewControllers (视图)彼此放在下面,以使它们的滚动行为仍然感觉完全正常。 如果视图是表集合或垂直集合,则内置单元重用功能不会受到影响,并且可以按您期望的方式直接使用。 将一个复杂的UITableViewDataSource/UICollectionViewDataSource转换为几个不同的UIViewControllers ,这些UIViewControllers独立管理其同类(?)数据。 这是第一个版本; 我的主要目标是拥有一个高效的堆栈容器; 没有小饰品或特殊功能(但是,即使有您的帮助,迭代后它也会变得更好)。 例如,它目前仅支持垂直堆叠。 UITableView和UICollectionView都是UIScrollView子类; 它们的行为基本上类似于标准滚动视图,但主要区别在于内部单元进行的回收操作。 […]
Hound CI是用于GitHub拉取请求的代码审查工具。 它对代码语义和样式违规发表了评论,使您和您的团队可以更好地查看和维护干净的代码库。 Hound CI与SwiftLint一起定义了一种样式指南,该指南有助于减少开发人员在编写代码时需要做出的决策,从而帮助他们专注于逻辑,而不是语义和格式。 注意:在本文中,我假设您在项目中配置了SwiftLint。 如果不是这种情况,建议您先阅读以下文章,然后再继续: 兄弟,你甚至连SwiftLint吗? 遵循准则或样式代码约定编写代码应该是您的核心实践之一。 我知道… medium.com 创建猎犬账户 首先转到Hound CI网站并创建一个帐户。 为您的仓库激活猎犬: 注意:Hound可免费用于公共GitHub存储库,如果您想将其用于私有存储库,则需要 付费 。 猎犬默认使用SwiftLint和此配置。 为了使用您的自定义SwiftLint配置文件,您将需要: 在与.swiftlint.yml配置文件相同的级别添加一个.hound.yml文件,该文件位于项目目录中。 .hound.yml添加到您的.hound.yml文件中: 迅速: config_file:.swiftlint.yml 3.然后,将这些更改推送到您的公共GitHub存储库中。 您的回购应如下所示: 现在,Hound CI将根据您的SwiftLint配置检查每个单独的请求,并检查是否有样式冲突。 如果猎犬发现了某些东西,它将在PR中发表评论。 它看起来像这样: 现在,您可以真正地专注于检查逻辑,而不是语义和代码格式。 真理只能在一个地方找到:代码。 ―罗伯特·马丁 希望您喜欢并发现本文有用。 随时留下反馈或建议。 谢谢阅读。 另外,您是否真的想浪费您的时间,请在Twitter上关注我@guerrix
通过模块化代码库满足单一责任原则。 我们通常会在很短的时间内开发一个应用程序,但是非常复杂。 为了达到交付目标,最好使用一些pod依赖项。 SJProgressHUD曾经是模块化的依赖项,用于显示Cocoapods上可用的弹出窗口或加载过程。 替代者是SVProgressHUD,MBProgressHUD,JQProgressHUD。 例如,让我们选择SJProgressHUD。 我们可以在每个地方附加SJProgressHUD.show() ,例如UIViewController类,AppDelegate类,Presenter或Controller(如果使用的是MVP / MVC),也可以附加在Model类中。 一切正常,但我们违反了软件开发原则:请勿重复。 如果我们将其放在模型上,则另一个问题是违反单一责任。 该模型不负责显示进度视图。 如果我们未能在模型类和视图类之间定义边界,那么由于零件之间的紧密耦合,下一个问题将会严重。 您的意大利面条代码必须重构。 有许多解决方案可以对其进行重构。 首先,我们从UIViewController创建一个扩展类。 在扩展文件中,添加一些将用于处理加载视图的函数,例如showLoading() , showError()和showSuccess() 。 导入SJProgressHUD 类UIViewControllerExtension { 扩展UIViewController { func showWaiting(消息:字符串){ SJProgressHUD.showWaiting(消息) } func showError(消息:字符串){ SJProgressHUD.showError(消息) } } } 创建扩展后,只要在UIViewController上,我们都可以从任何地方调用showWating(“getting doctors, please wait…”) 。 让我们看一下问题,实际上并不是UIViewController的所有派生类都需要知道这一点。 例如,我们的AboutVC仅显示应用程序版本。 //无需导入SJProgressHUD 类AboutVC:UIViewController { func viewDidLoad(){ } func viewWillAppear(){ //这里很神奇… wa可以在每个UIViewController的任何位置调用它。 //但是幸运的是AboutVC不需要了解它。 showWaiting(“请稍候…”) […]
从屏幕截图中可以看到,电子邮件字段的ID为“ login_field”。 我们将使用ID来访问元素。 WKWebView有一个validateJavaScript方法,该方法使我们可以访问网页元素和方法。 此时,我们要做的就是调用该登录按钮方法。 与字段不同,登录按钮没有ID。 相反,它具有名称参数。
Firebase工具套件很棒。 在一个屋顶下捆绑了这么多有用的开发服务真是太好了,而且免费上手的能力也很棒! Firebase为多个平台提供SDK,以与其服务(包括iOS)进行通信。 但是,iOS SDK与iOS应用程序生命周期紧密相关,因此无法在服务器端Swift环境中使用。 幸运的是,Firebase提供了REST API,这为我们提供了在Swift中开发服务器时使用其服务的途径。 最近,这篇文章概述了在服务器端Swift环境中开始使用Firebase REST API所需的步骤。 我将把Swift Vapor应用程序连接到Firebase的新Cloud Firestore技术,但是一般过程应适用于任何其他服务器端Swift框架和Firebase服务。 Cloud Firestore Cloud Firestore是Firebase的“新的和改进的” NoSQL云数据库。 与以前的产品Firebase Realtime Database一样,Cloud Firestore在客户端之间实时同步数据,并为脱机模式提供一流的支持。 Cloud Firestore与实时数据库 如果您过去使用过Firebase的实时数据库产品,您可能想知道Cloud Firestore有何不同。 Firebase文档进行了更详细的介绍,但从根本上讲,它可以归结为Firebase,它可以在原始Realtime Database产品成功的基础上进行改进。 较早的实时数据库需要使用非规范化和数据展平技术来防止随着数据库的增长和发展而出现瓶颈。 Cloud Firestore通过提供更丰富,更快的查询和更好的可伸缩性来对此进行改进。 因此,如果Cloud Firestore是Realtime Database的改进版本,那么Realtime Database甚至不再相关吗? 答案是肯定的。 实时数据库的真正优势仍然在于其速度。 如果您需要优化产品以实现高效,低延迟的同步,则可能需要使用实时数据库而不是Cloud Firestore。 这并不是说Cloud Firestore无法完成这项工作。 它仍然可以超级快速地同步事物(以毫秒为单位)。 蒸气2.x 蒸气是市场上许多服务器端Swift库之一。 我觉得他们在使事情变得简单易懂并且使服务器端Swift开发的入门变得非常出色。 他们甚至最近推出了Vapor Cloud,这使将服务器部署到现实世界中非常容易。 小型项目甚至免费! 在此项目中,我使用了Vapor 2.x,因为当我开始时Vapor 3仍处于beta中。 我将使用这些技术来实现简单的概念验证,以便利用服务器端Swift来实现自定义后端逻辑,同时依靠Firebase实时更新客户端应用程序。 对于此演示,服务器将仅每60秒生成一个随机数,然后将该数字及其生成下一个随机数的日期发布到Cloud Firestore数据库。 当一切正常运行后,客户端应用程序将如下所示: […]