Tag: swift

iOS响应链:UIResponder,UIEvent,UIControl和使用

在上一个操作由UIViewController处理的示例中,UIKit首先将操作发送给了UIView第一响应者-但由于它没有实现myCustomMethod因此视图将操作转发给了下一个响应者–恰好具有该方法的UIViewController在执行中。 尽管在大多数情况下,“响应者链”只是子视图的顺序,但您可以对其进行自定义以更改一般流程顺序。 除了能够覆盖next属性以返回其他内容之外,您还可以通过调用becomeFirstResponder()强制UIResponder成为第一响应者,并通过调用becomeFirstResponder()使UIResponder返回其位置。 这通常与UITextField结合使用以显示键盘inputView可以定义一个可选的inputView属性,该属性仅在响应者是第一响应者(在这种情况下为键盘)时显示。 响应者链自定义用途 尽管Responder Chain由UIKit完全处理,但您可以根据自己的喜好使用它来解决通信/代理问题。 在某种程度上,您可以将UIResponder操作视为一次性通知。 考虑一个几乎每个视图都支持“闪烁”动作的应用程序,目的是帮助用户在教程中导航。 触发此操作后,如何确保仅当前“活动”视图闪烁? 可能的解决方案包括使每个视图都继承一个委托或使用除”currentActiveView”之外每个人都需要忽略的简单通知,但是响应程序操作使您可以使用零委托和最少的编码轻松实现此目的: final class BlinkableView: UIView { override var canBecomeFirstResponder: Bool { return true } func select() { becomeFirstResponder() } @objc func performBlinkAction() { //Blinking animation } } UIApplication.shared.sendAction(#selector(BlinkableView.performBlinkAction), to: nil, from: nil, for: nil) //Will precisely blink the last BlinkableView that had select() called. 它的工作原理与常规通知非常相似,不同之处在于,尽管通知将触发注册它们的每个人,但是这会有效地循环响应程序链,并在找到第一个BlinkableView时立即停止。 […]

iOS教程:使用ARKit和Vision框架进行人脸检测

在脑子里集思广益,跳上ARKit潮流并找到了一个快速致富的方案时,我想到了一些事情,其中​​涉及到在使用ARKit时查找iPhone前置摄像头上显示的所有面孔。 经过几天的实验,并看到其他人在网上完成了一些工作,我能够做到这一点,因此我决定编写一个有关它的快速教程。 我将向您展示如何使用ARKit和Vision框架扫描面部并在屏幕上获取其当前CGRect框架。 首先使用Xcode的默认工具包创建一个ARKit项目。 或者,您也可以根据需要在包含运行ARSession的任何AR视图的UIViewController中实现所有逻辑。 就是这样了。 对于您个人项目的需求,您可以保留对已翻译CGRects的引用,而不必使用它们来构建视图。 但是现在您将能够分辨出一张人脸在ARScene视图中的确切位置。 您可以在此处找到演示项目。 感谢您的阅读,并在评论中留下您的想法和想法以进行改进。

在Swift中读取,写入和删除文件

当今大多数普通应用程序都是通过HTTP进行通信的。 虽然我们可以通过这种方式读取和写入数据,但仍然需要将数据保存到设备本地文件中,这仍然非常普遍。 让我们讨论一下如何完成,然后提出一种更简单的方法。 TL; DR 如果您不希望自己学习如何做,请在GitHub上查看我的File项目(但您确实应该知道它是如何完成的,因此请继续阅读!)。 FileManager和URL 刚开始在iOS中进行文件处理时,它会令人望而生畏。 您必须学习FileManager,在您发现需要传递URL之前,它看起来还不错。 然后,您停下来思考:“等等,URL与保存文件有什么关系? 这令人困惑。” Apple选择使用URL作为通用语言来传达文件在文件系统中的位置。 一旦您对这个概念有所了解,它确实非常巧妙。 通过字符串处理文件位置可能会很混乱(我有数十行的旧服务器代码用于遍历目录和文件以证明这一点),但是使用URL会将它们包装在一个非常需要的结构中,该结构相对容易理解和理解。如果您以前使用过URL进行联网,则很熟悉。 即使您以前从未使用过URL,我们所需的基础知识也确实很容易。 实际上,可以将其全部简化为包含三个简单步骤的模式: 1.创建目标目录URL 2.使用目录URL创建文件URL 3.将数据保存到文件URL 让我们看一下这是如何完成的。 注意:如果您以前从未使用过FileManager,请知道它使用Singleton模式,并且不直接实例化FileManager,而是使用FileManager.default来调用FileManager的属性和函数。 如果您不熟悉单例模式,那是确保在应用程序的生命周期中仅实例化类的一个实例的一种方法。 目录网址 首先,我们需要一个用于文档目录的URL。 您不必将所有内容都保存到documents目录,但这是最合乎逻辑的开始,并且一旦您知道如何保存在那里,就很容易保存到其他位置。 我们将使用以下代码来获取文档目录的URL: 让directoryURL = FileManager.default.urls(用于:.documentDirectory,在:.userDomainMask中)[0] 我们在这里要做的是向FileManager索要用户主目录(或在iOS中为应用程序的主目录)中文档目录的URL列表。 这将返回一个数组,其第一个条目将包含documents目录,这就是为什么我们在语句末尾指定[0]的第一个数组索引的原因。 这将返回文档目录的URL对象。 真的就是这么简单。 档案网址 现在我们有了要保存文件的目录的URL,让我们创建文件本身的URL。 为此,我们使用URL(fileURLWithPath:relativeTo:) 。 fileURLWithPath参数中引用的路径是文件名,不包括任何文件扩展名。 例如,如果我们想要一个名为“ myFile.txt”的文件,则fileURLWithPath将为“ myFile”(我稍后将解决“ .txt”扩展名)。 接下来, relativeTo参数是文件将保存到的目录。 该参数带有一个URL ,您猜到了,我们将简单地传入上面的URL : 让fileURL = URL(fileURLWithPath:“ myFile”,relativeTo:directoryURL) 好吧,那文件扩展名呢? 要添加该代码,只需在调用末尾添加appendingPathExtension(:) ,如下所示: let […]

版本控制系统未提供作者信息

建立Xcode专案时,如果之前没有设定过作者信息,将出现以下的错误讯息。 只要点选Fix,输入作者姓名和作者电子邮件,即可修正问题。 不过如果不不小心按到取消,忘了修正问题,我们还可以开发iOS App吗? 因此为了让专案可以顺利提交,此时我们要打开Xcode的Preferences窗口,切换到Source Control分页,在Git页面输入作者姓名和作者电子邮件。

拆开Massive View Controller

在每个项目的某个时刻,设计师都会坐在您的办公桌旁,询问您将屏幕移动到流程中其他位置的难度。 也许您的同事无所适从,问为什么您的Sweet View Controller会知道每个其他View Controller。 或您的经理突然来询问您为什么没有任何测试。 所有合理的问题。 您的脸(如图所示:😬)比您以前说的更多。 这将比他们想象的要多得多 。 一个相当典型的iOS应用程序体系结构涉及创建视图控制器,这些视图控制器决定下一个要呈现的视图控制器以及应如何呈现它们。 他们还负责启动网络请求,解释响应,更新模型并调解子视图或子视图控制器之间的通信。 mega-view-controller做很多事情: 获取有关其呈现方式的上下文。 处理用户交互,启动计算,更新结果。 确定接下来要显示的屏幕。 配置下一个视图控制器。 在某个地方展示下一个视图控制器。 它会进入导航控制器吗? 哪一个? 它是模态的吗? 这样的细节不太可能通过通常狭窄的API表面公开-通常,没有超出UIViewController呈现的东西。 结果,这段代码充满了隐式依赖。 这很难测试,甚至更难重新排列。 这个想法很简单:隔离您的视图控制器- 他们不需要知道哪个屏幕在前或下一屏幕 。 在这种模式下, 视图控制器的工作是控制视图,布局和动画。 流量控制器的工作是代表一个特定的状态机并遍历该状态机。 当需要进行状态转换时(例如,网络请求,流程中的前进或后退等),视图控制器将通过委派或阻止回调将其推迟回流程控制器。 这样,可以在不实例化所有支持基础结构的情况下测试视图控制器。 啊哈! 现在可以测试视图控制器了! 它不再依赖于之前发生的事情,也不知道接下来会发生什么-它与表示样式无关。 现在可以轻松地在流内或流之间移动视图控制器。 如果那是您的事,那么流量控制器本身也很容易测试。 甚至公开一些基本细节,例如当前显示的屏幕以及调用代表动作以模拟在流程中的遍历,都会带您到达那里。 毕竟这只是一台状态机。 在这种模式下,视图控制器应该做的尽可能少。 逻辑应仅限于将数据提供者连接到子视图,管理动画以及响应用户事件。 还有更多应该委托出去。 步骤1使View Controller委派所有操作 接下来是Flow对象。 这充当所有托管视图控制器的委托,并负责呈现和配置它们。 步骤2设计由您的View Controller组成的流程 这就是全部。 这种设计模式使隐式依赖关系的网络反转,有利于委派和显式依赖关系注入。 准备测试时,构造视图控制器,遵守委托协议并练习公共API。 当然,大多数项目要复杂得多-这就是这种模式的真正体现。 现在不仅可以在流之间重复使用视图控制器,还可以轻松地从其他流中构建聚合流。 很疯狂的东西,是吗? 我汇集了一个非常简单的基于这些概念的Master […]

使用Nginx和Supervisor部署基本的Vapor应用程序

本文将指导您完成将简单的蒸气应用程序部署到VPS的过程。 我使用的是数字海洋,但是只要您的实例运行Ubuntu 16.04并且可以通过ssh访问该主机,托管服务提供商就没有关系。 先决条件: 具有ssh访问权限的Ubuntu 16.04实例。 我强烈建议您在继续之前阅读本文。 熟悉终端文本编辑器,例如nano,vi或emacs。 熟悉基本的bash命令。 安装和设置Nginx 通过运行以下命令来安装Nginx: sudo apt-get更新 须藤apt-get install nginx 将规则添加到防火墙以允许端口80上的TCP连接。(仅在启用防火墙的情况下才需要执行) sudo ufw允许’Nginx HTTP’ sudo ufw状态 检查Nginx是否正在运行systemctl status nginx 最后,您可以通过从浏览器向服务器的域或ip发送GET请求来检查nginx是否设置正确。 如果您在下面看到欢迎页面,则说明您已经成功设置了Nginx。 如果您没有看到此页面,请查看此详细教程。 安装和设置蒸气 使用以下命令安装Swift和Vapor。 评估“ $(curl -sL https://apt.vapor.sh)” 须藤apt-get install swift vapor 评估“ $(curl -sL check.vapor.sh)” 如果输出“与蒸气2兼容”,则可以继续进行。 创建一个基本的蒸气项目。 蒸气新你好 注意:如果您有现有的蒸气项目,则可以从github克隆该存储库。 但是请记住,在本教程的其余部分中,请用您的项目名称替换“ hello”。 配置Nginx以将请求转发到Vapor App 更改/etc/nignx/sites-available的default配置文件,使其看起来像以下片段。 服务器{ 监听80 default_server; 听[::]:80 […]

使用Swift协议提高代码质量

因此,您正在与许多团队成员一起从事一个项目,或者您正在编写一个框架。 两者都涉及编写其他开发人员最有可能查看或以某种方式使用的代码,无论是添加新功能还是从外部访问您的功能。 如果您是独立工作,很容易养成一个坏习惯,即直接跳入编写实现并随手进行即兴创作,而只是在同一周晚些时候回来,发现您或您的任何同事都可以什么都没读。 这将导致新功能需要花费更长的时间添加,团队内部混乱,并且在某些情况下可能最终会完全重写整个功能。 请记住,评论不应该只是为自己写。 其他人会阅读您的代码,因此当您编写注释时,请确保对他们和您自己有意义,几周后再返回。 您可以通过遵循一些黄金法则来实现。 不做任何假设 : 不要以为其他开发人员会像您一样了解该项目。 请勿使用其他人似乎看不见的短语。 如果花时间检查外部依赖关系和潜在的副作用,则会浪费大量时间。 如果您发现自己在写小说来解释单个功能,那么您的功能可能做得太多。 也许您应该将功能分解为几个较小的功能。 保持清楚: 删除多余的单词和短语,但不要删除太多,以免短语变得模棱两可。 注释应清楚简洁地说明代码的作用。 不要说它是什么,要说它 做 什么 : 例如,我们都已经看到了注释,这些注释准确地描述了该函数的含义:但是没有解释其作用。 我们知道它会返回一个字符串数组 您可能正在看函数的实现,以查看函数实际执行的操作,但您不必这样做。 这些评论应该告诉您您需要知道的一切。 我们可以使其他开发人员更容易阅读。 使用cmd + option + /, Xcode可以让我们为此功能生成一个不错的注释结构,并且可以对其进行改进。 因此,我们现在有了一个很好的注释功能。 现在,我们想为User对象添加更多功能,因此我们创建了UserService 。 可以将其保留为一个初学者项目的原样,但是当您编写自己的框架或从事商业项目时,这仅仅是不够的。 代码需要是可单元测试的,也许某些实现代码需要具有受限的访问权限。 使用协议将为项目带来很多好处。 我们希望使我们的UserService更具可读性,因此让我们为其创建一个Protocol ,恰当地命名为UserServicing 如果UserService符合UserServicing ,则可以这样使用: 那么,什么使它更好呢? 没有实现代码:没有干扰性的实现代码,加上高质量的注释,您可以更清楚地看到每个功能的职责以及整个Servicing的功能。 依赖注入+测试:通过使用协议,这意味着我们可以更改符合UserServicing的任何内容的实现,而不会产生任何负面影响。 这意味着我们可以使用Cuckoo之类的库对协议实现进行模拟,存根和测试 。 灵活性:如果我们的User数据提供程序发生了更改,或导致UserService内的实现发生更改的其他任何内容,都没有关系! 只要UserService的定义保持不变,就无需更改ViewModel中UserService的实现。 在开始任何实施之前,请先编写注释良好并记录在案的协议。 通过让您事先考虑所有功能要求,它将确保重点,并有助于获得更好的画面。 此外,如果将代码以有组织的方式分解为协议,它还允许项目的新开发人员或使用您的框架的人员快速了解代码的工作方式。 感谢您抽出宝贵的时间阅读。 如果您有任何疑问或有兴趣阅读我的其他文章,请随时在Twitter或LinkedIn上与我联系。

Swift Heroes2018。简短概述

11月9日,iOS开发会议在都灵举行。 该活动聚集了来自欧洲各地的约500名参与者,并在都灵历史中心都灵都灵因孔特拉国会中心举行。 会议组织者-通感和SYX。 在iOS社区中,有相当著名的演讲者发表了演讲。 其中包括Sourcery库的作者,“ Raywenderlich”课程的几位作者,“ Hacking with Swift”的创建者等。 会议分两部分进行,讲座分为主题演讲和专题讨论会。 当然,此类事件最有趣的部分之一就是网络。 与我在Twitter上关注的行业人士进行实时交流很有趣。 我也使用了他们的工具和框架。 他们为我们的iOS社区的成长和发展做出了重要贡献🙂 例如,我设法与Sourcery的作者交谈(我认为每个尊重他的iOS开发人员都知道这是什么),Krzysztof Zablocki,向他询问未来的计划和发布。 您可以在下面查看所有带有演讲的视频。 1. Pixle联合创始人Krzysztof Zablocki-纽约时报的首席开发人员 iOS应用程序架构 设计模式是工具箱的一部分,但您需要务实 MVC与MVVM 在两种模式下,ViewController都是View层的一部分 人们在两种模式下都会犯的最大错误->缺少路由器 有关什么是流量协调器以及如何适合这些模式的详细信息 2. Paul Hudson,Swift黑客的创造者 关注点分离:实时重构视图控制器 我们都知道,大型视图控制器会导致同样大的问题,但是有时候,要想使事情变得更好,要知道从哪里开始并不容易。 在本节中,我将提供一个示例Swift应用程序,逐步解决它存在的许多结构性问题,然后在舞台上对其进行重构,以便您确切地了解它是如何完成的。 最终结果将是一个更智能,更简单的体系结构,该体系结构更具可测试性,可扩展性,并且最重要的是更易于维护。 我们将调查许多目标,例如: 将视图代码重定位到合理的位置 将委托和数据源分拆为新类 使用协调器简化导航 所有这些都将在舞台上进行现场编码,因此您可以继续进行。 3. Tim Condon,BBC软件工程师,断手创始人 服务器端Swift和Vapor入门 随着Vapor 3的发布,服务器端Swift和Vapor已开始成为主流并被采用。 本演讲讨论了在服务器和Vapor上使用Swift的好处和优点。 然后,通过现场演示了解如何在15分钟内构建完整的CRUD API。 4. Elviro Rocca,iOS开发主管presso Facile.it 先进的Swift光学 功能性光学器件(如透镜和棱镜)是令人难以置信的工具,用于以声明性和可组合的方式操纵数据结构。 让我们深入研究Swift中的功能光学。 在本讲座中,我们将探讨不仅仅是Lens和Prism的更多光学类型,并探讨它们在多个层次上进行合成的能力。 […]

使使用UIFont更快,更不易出错

UIFontComplete 使使用UIFont更快,更不易出错 用法 该库只是UIFont一个扩展和一个Font enum ,每个iOS安装的标准Font都有一个案例。 不必再为寻找UIFont类型的名称而UIFont ,如果字体名称输入错误,运行时也不会感到惊讶。 代替UIFont的String基本构造UIFont : let font = UIFont(name:“ Arial-BoldItalicMT”,大小:12.0) 现在,您可以简单地开始输入字体枚举的名称,并让代码完成帮助您: let font = UIFont(font:.arialBoldItalicMT,size:12.0) 安装 迦太基 如果您使用迦太基来管理依赖项,只需将UIFontComplete添加到Cartfile : github “Nirma/UIFontComplete” 如果使用Carthage构建依赖项,请确保已将UIFontComplete.framework添加到目标的“ 链接的框架和库 ”部分,并且在Carthage框架复制构建阶段中包括了UIFontComplete.framework 。 可可豆 如果您使用CocoaPods管理依赖项,只需将UIFontComplete添加到Podfile : pod ‘UIFontComplete’ 要求 Xcode 8.0 迅捷3.0+ 贡献与维护 iOS上可用的字体肯定会更改,并且当它们执行此库中的Font枚举时,也将需要更新。 如果您想帮助维护或改进此库,请随时这样做。 执照 UIFontComplete是免费软件,可以根据LICENSE文件中指定的条款进行重新分发。 资料来源:https://github.com/Nirma/UIFontComplete

以编程方式创建SKNode并为其提供SKPhysicsBody

请注意:我在开发游戏时正在学习Swift,这是我很难从Google搜索中真正找到的东西。 如果代码有任何问题,请告诉我更好的方法👍 问题 在学习了如何在SpriteKit中创建场景的教程之后,我遇到了很多问题,这些问题都出现在媒体上。 放入其中的项将导致Xcode(在撰写本文时为10.1版)崩溃。 这使学习经验和工作流程成为噩梦,因此我决定了解如何以编程方式创建SKNode,SKSpriteNode等,并了解我的工作方式。 SKNodes,SKSpriteNodes和所有节点🤷‍♂️ 了解如何在GameScene中创建节点非常容易: //创建节点变量 var myNode:SKSpriteNode! //使节点为白色矩形,并指定位置和名称 myNode = SKSpriteNode(颜色:UIColor.white,大小:100,高度:5) myNode.zPosition = 0 myNode.position = CGPoint(x:0,y:0) myNode.name =“ my_node” //将节点添加到场景 self.addChild(myNode) 向节点添加物理设置🤬 但是,这部分很可能是由于我缺乏理解和轻微的名字扭曲而导致的,这让我进行了一些搜索和游戏,直到我理解为止。 如果您像我一样在这里苦苦挣扎,它在Xcode中: 我读了一些有关SKPhysicsBody的内容,但是我无法将其与屏幕快照中显示的设置名称相关联。 因此,这是对我有用的东西,如果您遇到与我相同的问题(崩溃🤬),或者如果您希望以编程方式创建场景,则希望对您有所帮助。 myNode.physicsBody = SKPhysicsBody(rectangleOf:myNode.size) 上面与将“物理实体”类型设置为“边界矩形”相同。 myNode.physicsBody = SKPhysicsBody(circleOfRadius:myNode.size) 这个用于“边界圆”,如果创建圆形节点显然很有用。 我遇到一点麻烦的最后一个是“ Alpha Mask”选项。 我通过以下步骤完成了此任务。 //根据需要为SKPhysicsBody创建纹理 让nodeTexture = SKTexture(imageNamed:“ texture”) //将纹理应用于节点 myNode = SKSpriteNode(纹理:nodeTexture) //添加物理体 myNode.physicsBody = […]