Tag: 编程

Swift解决方案:网桥

我想请您注意抽象汉堡包及其作为餐食的具体实现。 假设我们要添加一个新汉堡,您需要创建多少个其他类? 如果回答三个,那将是正确的: 两个层次 这是不直观的,但是避免这种混乱的解决方案是创建两个单独的层次结构。 这是定义在声明时的含义: 桥接模式将抽象与其实现分离开来…… “抽象”是指基类或协议。 在我们的示例中,它涉及各种汉堡类。 这些汉堡包不会被实例化,因为餐厅不会单独出售它们。 必须使用实现将它们分类为一顿完整的饭菜才能使用。 “实施”是指我们在将汉堡包加入餐边后制作的餐食类。 因此,我们将汉堡包(抽象)与餐食/面食(实现)分离,并剩下两个类层次结构。 层次结构之间的桥梁 然后定义继续说: 桥接模式将抽象与其实现分离, 以便两者可以独立变化。 现在我们有了两个单独的层次结构,我们需要一种连接两者的方法。 为此,我们为每个Burger赋予Side类型的属性。 这种“具有”关系是连接两个层次结构的“桥梁”。 我们这样做是为了使两者可以独立变化。 换句话说,我们不再需要为汉堡和面包的每个组合创建一个类。 由于它们的层次结构是分开的,因此每个新汉堡或一面只需要一个新类。 这一切似乎有点抽象,所以让我们回到代码中进行演示。 编码解决方案 我们需要针对设备和音频类型的单独层次结构。 让我们从音频类型开始: protocol AudioHandling { func handle(audio: Audio) -> Audio } class AudioEncryptor: AudioHandling { func handle(audio: Audio) -> Audio { // Encrypt and return Audio } } class PlainAudioHandler: […]

掩盖用户的敏感数据-它是私有的。

作为应用程序开发人员,我使用Apple的iTunes Connect检查销售情况。 当您为应用程序提供背景信息时,它会模糊所有销售数据(非常酷!) 他们为什么这样做? 好吧,Apple建议您将其作为最佳实践,因为iOS会为您的应用创建快照并将其存储在文件系统的缓存中。 您可以通过下载iExplorer自己查看。 这仅适用于您在App Store以外(例如通过Xcode)安装的应用。 否则它将被隐藏,除非有人越狱了您的手机。 您可能会说,嘿,如果有人拥有我的手机并且知道如何越狱……他们可以访问我的应用程序的最新视觉状态在我要担心的事情上并不重要。 我明白了 但是另一方面,如果某些事情是可以预防的,那么防止它们仍然是一个好主意。 这就像决定是否要吃最后一个曲奇,即使您一次坐着吃完了盒子的其余部分。 您仍然可以选择不吃最后一个cookie,这样会更好。 实际上,安全公司建议在审计过程中从iOS的快照功能中隐藏敏感数据。 您会注意到所有银行应用程序都这样做。 (请参见顶部的gif。)他们的解决方案有些手。 无论您在应用程序中的什么位置,他们都用公司的初始屏幕覆盖了所有内容。 我不怪他们。 他们可能从Apple的示例中复制了该技术,该示例向您展示了如何使用Objective-C用纯黑视图控制器覆盖所有内容。 让我们做得更好。 协议DisplaysSensitiveData { func hideSensitiveData() func showSensitiveData()//我们弄得一团糟,我们将其清理干净 } 将该协议扔到您要保护的任何视图控制器及其容器视图控制器上。 例如,UINavigationController: 扩展UINavigationController:DisplaysSensitiveData { func hideSensitiveData(){ 如果让vc = topViewController为? DisplaysSensitiveData { vc.hideSensitiveData() } } func showSensitiveData(){ 如果让vc = topViewController为? DisplaysSensitiveData { vc.showSensitiveData() } } } 最后,挂接到UIApplicationDelegate以便在应用程序后台运行或返回时进行适当的调用。 func […]

深入核心图像–第一部分

我已经完成了本文的大部分示例项目。 您可以在这里查看: chriswebb09 / CoreCamera 通过在GitHub上创建一个帐户为CoreCamera开发做出贡献。 github.com 这篇文章标志着我将要在Core Image上写的一系列文章的开始。 那么为什么要使用Core Image? 低级处理图形可能会很混乱。 您走得越低,您对UIKit和Cocoa的追求就越远。 对于开发人员而言,幸运的是,Apple提供了用于与较低级图形进程进行交互的抽象/接口。 Core Image是这些抽象之一,它是在Apple生态系统中进行编码时经常会遇到的一个库。 从编辑静态图像到在实时视频内容上使用过滤器,Core Image的用途十分广泛,可以处理各种用例。 在我们开始之前,我只想警告您Core Image严重依赖KVO,这会使探索它有些困惑。 与您能够与之合作和操纵的世界相比,这个障碍显得苍白,所以我希望您坚持下去。 Core Image是一种图像处理和分析技术,旨在为静止图像和视频图像提供近乎实时的处理。 它使用GPU或CPU渲染路径处理来自Core Graphics,Core Video和Image I / O框架的图像数据类型。 -Apple文件 定义 CIImage:是用于在Core Image中处理图像数据的图像数据格式。 这是有关如何处理图像的食谱书/说明。 CIFilters将CIImage用作输入,然后将它们传递回去。 由于CIImages的执行是延迟执行的,因此只有在将它们放入可渲染格式后,配方/指令才会被遵循。 CIContext:是用于使用Quartz 2D,Metal或OpenGL进行Core Image处理的图形处理和分析的评估上下文。 CIContext是线程安全的不可变对象,但与它们一起使用的CIFilter不是。 CIDetector:是图像处理过程,用于注意和分类图像上的区别特征。 对于可能是眼睛,耳朵,鼻子等的脸,或者可能是形状,例如盒子。 核心图像内核:核心图像内核是在每个单个像素上运行的小型算法。 内核使用过滤器的参数并基于该参数执行其算法。 每个过滤器至少包裹一个内核。 内核是在目标图像上的每个单个像素上执行的功能。 内核包含我们运行以生成输出图像的处理算法。 执行量高是GPU按其设计方式进行设计的原因。 每次执行看起来可能并不多,但是与所有像素协同工作,同时进行渲染,很明显,我们需要专门的东西来处理它们。 扭曲内核:扭曲内核专为移动,变形,平移图像而设计。 如果您已经阅读了我在ARKit上撰写的较早的系列文章,我们将使用矩阵转换将节点放置在3D空间中。 扭曲内核对像素执行操作以完成这些操作。 颜色内核:颜色内核是负责仅使用颜色的颜色的内核。 它接收一个作为分量向量的参数。 这些成分是红色,绿色,蓝色和Alpha。 […]

学习Swift和iOS开发第1部分:安装Xcode。

学习Swift和iOS开发第1部分:安装Xcode。 像任何优秀的工匠一样,我们需要交易的工具。 对于iOS开发人员(或macOS,tvOS,watchOS),该工具是Xcode。 画布对艺术家来说就像Xcode对iOS开发者一样。 它充当了我们的工作空间,富有创意的出路,沮丧的源头等等。 这将是一篇非常简短的文章,因为使用Xcode进行启动和运行实际上非常容易! Xcode是一个了不起的应用程序。 它是一套完整的工具和应用程序套件,使开发人员能够通过应用程序创造未来。 正如您将看到的,安装和入门非常简单。 首先,打开macOS App Store,然后在右上角的搜索栏中键入Xcode ,然后按Enter进行搜索。 结果加载后,Xcode将是第一个结果。 接下来,单击GET(因为我已经安装了它,所以我说它处于打开状态),然后输入您的Apple ID信息以开始下载。 请记住,这是一个庞大的应用程序(4.5 GB),安装后将占用近12 GB。 要打开Xcode,您所需要做的就是进入Applications文件夹,然后单击Xco​​de。 就是这么简单。 Xcode打开后,将显示“欢迎使用Xcode”屏幕,其中提供了多个选项供您选择。 这将是本书所有项目的启动板。 您将打开Xcode并从此处创建项目。 了解Xcode界面后,您将看到它在应用程序开发过程中的功能和帮助。 这篇文章简短而且有充分的理由-Apple通过提供如此精简的体验使我们的工作变得如此轻松。 如今,开始开发iOS的障碍非常少,我们只需单击几下就可以开始。 这意味着我们有更多时间专注于制作出色的应用程序。 在下一篇文章中,我们将简要介绍一些Swift基础知识,以供您品尝。

改善Xcode工作流程的提示

Xcode是创建iOS应用的绝佳工具,但有时可能会有些笨拙,并会拖慢您的工作流程。 这里有一些技巧可以改善您的工作流程,希望可以节省您的时间和麻烦。 1.跟踪构建时间 构建时间是Xcode最糟糕的事情。 要改善任何东西,您首先需要某种衡量它的方法。 要以秒为单位在Xcode中测量构建时间,请打开终端并输入以下命令: defaults write com.apple.dt.Xcode ShowBuildOperationDuration -bool YES 之后,您可能需要重新启动Xcode才能看到更改。 您应该看到每次构建后,构建时间就会显示在顶部工具栏中。 现在您知道构建时间有多长,请按照本文进行操作以减少构建时间。 2.跟踪应用启动时间 应用启动速度是创建应用时最重要的因素之一。 用户希望应用程序立即启动。 寻找缓慢发射的来源可能很困难。 除了使用事件探查器(我打算很快写另一篇文章)之外,很难评估应用程序的启动时间以及改进的位置。 一种可以通过在调用applicationDidFinishLaunching之前跟踪所有内容来缩短启动时间的方法。 这是应用程序初始化库,设置ObjC和加载dylib的时候。 使用此方法,Xcode将打印加载时间,并且在每次运行应用程序时,导致加载速度变慢。 打开产品>方案>编辑方案,然后在运行操作下添加以下环境变量DYLD_PRINT_STATISTICS并将其值设置为1 。 现在,在每次构建之后,您应该会看到如下所示的打印输出: 要了解有关如何使用此信息的更多信息,请参阅Use Your Loaf的Slow Startup Times文章。 3.快速重命名 寻找替换变量来重命名总是很麻烦。 不再。 在单击要重命名的变量或函数的同时,按住CMD 。 然后从弹出窗口中选择重命名。 它会在项目中甚至在情节提要中找到并重命名每个副本。 编辑:根据BłażejWdowikowski和James Pamplona的建议,您可以使用键盘快捷键cmd + ctrl + e快速重命名相同范围内的内容。 与上述内容不同,但仍然有用。 4.使用断点 我知道似乎只使用print语句似乎更容易,但是在许多情况下,仅使用断点就容易得多,并且可以节省您的时间。 要设置断点,请在要停止的代码一侧按行号,然后运行项目。 代码在该行上暂停执行后,您只需将鼠标悬停在它们上方,即可查看所有周围的变量值。 或者,您可以使用lldb通过print object命令在控制台中打印它们,例如po yourVariable 。 断点可能看起来更复杂,但是一旦您了解了一些lldb命令和其他Xcode调试器工具,它实际上为您节省了很多时间,因为您可以在断点处停止,而不必完全重新运行应用程序。 一旦完成对值的评估,就可以按恢复按钮并禁用断点以防止其再次停止执行。 […]

Advanced iOS Developer(Swift)的最佳资源

以我的拙见,当然(更新10.12.2017) 很长一段时间以来,我的浏览器中都有一个文件夹,其中包含有关iOS开发和Swift的文章和视频,这对我阅读和重新阅读很有帮助。 我很确定大多数开发人员都有自己的具有最佳功能的库。 所以我决定分享我的信息Information 更新 12月10日:添加了调试部分 良好的iOS应用程序体系结构:MVVM与MVC与VIPER MVVM,MVC,VIPER…这么多缩写,哪种架构是最好的? 让我们来谈一谈永远重要的事情…… 学术领域 驯服极大的复杂性:MVVM,协调器和RxSwift 去年,我们的团队开始在生产应用程序中使用协调器和MVVM。 起初看起来很吓人,但是从那以后我们…… blog.uptech.team 汗楼| 协调员Redux 应用程序委托是任何应用程序的入口点。 它的主要职责是往返于……之间传递消息。 khanlou.com iOS架构模式 揭秘MVC,MVP,MVVM和VIPER medium.com MVVM简介·objc.io objc.io出版有关iOS和OS X开发的高级技术和实践的书籍 www.objc.io 汗楼| 8种模式可帮助您摧毁Massive View Controller 视图控制器之所以变得庞大,是因为它们做了太多的事情。 键盘管理,用户输入,数据… khanlou.com 依赖注入,iOS和您 脆弱的对象图之所以不好,是因为您无法轻松替换应用程序的各个部分。 如果是物体… www.bignerdranch.com 适用于Swift的SOLID原理– Marco Santa Dev 可维护的组件。 可重用。 只是个梦? 也许不吧。 SOLID原则可能就是这样。 SOLID是首字母缩写词… marcosantadev.com 依赖注入·objc.io objc.io出版有关iOS和OS X开发的高级技术和实践的书籍 www.objc.io 使用VIPER构建iOS应用程序·objc.io objc.io出版有关iOS和OS X开发的高级技术和实践的书籍 […]

为什么我停止使用情节提要和Interface Builder

在开始点燃手电筒之前:是的,我以前曾经广泛使用过Interface Builder。 实际上,直到几个月前,如果没有我心爱的情节提要,我无法想象创建一个项目。 我研究了一些代码约束,而仅语法本身就使我不寒而栗。 因此,当您在Samsao的第一天得知我的指南明确禁止使用Interface Builder时,您可以想象到我的惊讶。 当我的同事开始解释这是为什么时,我所能想到的就是:但是使用IB变得如此简单! 然而,放开情节提要几周后,我无法想象自己会再使用一次。 现在,如果您是IB的狂热分子,您可能会将我钉为极端主义者,而无视此刻我所说的一切,那很好。 但是,如果您可能想知道是否有办法让您每天花30分钟等待重载的故事板文件打开,那么这篇文章适合您! 因此,不要浪费您的宝贵时间,让我们开始吧! 他们很慢 如果您有足够的耐心并且喜欢在等待IB文件打开时进行呼吸练习,那么对您来说非常好! 就个人而言,每次我尝试打开一个故事板时,我要做的就是把头撞在墙上。 我知道,我的耐心正在发展中。 在团队合作中与他们共事 如果您是自由职业者/独立开发人员或将来的开发人员,那么这可能还没有影响到您,但是如果您曾经不得不处理NIB文件上的合并冲突,那么您会感觉很糟糕。 使用UI代码,轻而易举! 它们使代码的可重用性复杂化 在代码中,如果有5个看起来几乎相同的屏幕,那么使用协议在它们之间高效地重用UI代码非常容易。 使用情节提要,祝您好运,找出如何分享观点和行动! 他们会变得很乱 一个图像说出一千个单词。 这到底是怎么回事? SnapKit 使编写代码约束变得如此轻松! 好的,您已经阅读了有关Visual Format Language的一两本书,这让您有些哭泣…… customView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat:“ V:| -20- [customView(> = 70 @ 500)]-[customView(== customView)]-30- [customView]-|”) 但是,如果您了解SnapKit及其简单性,您真的没有任何借口! customView.snp.makeConstraints {(make)in make.top.equalToSuperview() make.centerX.equalToSuperview() make.width.equalTo(70) make.height.lessThanOrEqualTo(200) } UI代码没有比这更好的了! 总结一下 是的,对于初学者来说,情节提要更容易进入,对于快速制作原型非常有用。 但是,如果您从事的是大型专业项目,那么我实在找不到一个很好的理由来说明为什么有人会喜欢使用它们而不是用代码编写UI。 如果您对如何使用SnapKit设置没有情节提要的项目感到好奇,请查看有关此内容的新博客文章! 现在,我知道那里的大多数IB / storyboard狂热者仍然认为我很疯狂,如果您是其中的一员,我很想得到您的意见,请给我评论! […]

学习Swift和iOS开发:一系列。 – devslopes

学习Swift和iOS开发:一系列。 欢迎来到编程和iOS开发的世界。 欢迎来到充满创造力,激情和想象力的神奇世界。 在这里,我们将代码转化为可以使人们愉悦,娱乐和改变人们生活的体验。 首先先说一点。 学习编码可能很困难。 这也是我做过的最有意义的事情之一 。 我自学了30岁的代码,所以无论您是大人还是小孩子,您都可以学习编码。 您有时会灰心。 您将告诉自己:“我对此没有头脑”,您将要放弃。 您可能会遇到欺负网络编码人员的恶棍,这些人贬低了您的编码技能,并告诉您,除非拥有计算机科学学位,否则您不是真正的程序员。 但是然后事情就会开始点击。 您将编写一些代码,并且该代码将起作用,并且您自己会想到:“伙计,我很棒。” 我想给您一些建议,以使您在遇到挫折时保持直截了当: 1.不要将自己与其他程序员相比。 与自己竞争。 有人永远比你更熟练。 2.您确实属于编程世界。 不管别人怎么说。 作为程序员,您拥有独特的才能,而其他程序员则没有。 3.如果学习很痛苦并且大脑受伤了,那就知道自己正在成长。 程序员可以过着有意义的生活。 我的编程生涯是在家中度过的。 这意味着与我的家人在一起,这是我的首要任务。 成为一名优秀的程序员,您将有机会过上任何想要的生活方式。 这是一种拥有更多个人时间和自由的生活方式,还是那意味着为顶尖公司工作而赚到丰厚的薪水-或者也许两者都有! 在您学习编码的过程中,我能告诉您的最后一件也是最重要的事情是—每天学习,每天做一些动手编码。 您的知识将会复合,您的进步将成倍增长。 那么,我们将在本系列中介绍什么? 很多。 以下是即将发生的事情: 了解Swift的基础知识。 涵盖变量,函数,数组,循环,字典以及所有这些好东西。 我们将介绍UIStackViews并构建您的第一个iOS应用。 了解有关地图,自动版式和手势识别器的信息。 了解应用程序设计,Sketch基础知识以及UX和UI到底是什么? 我们将学习如何与API交互,使用Firebase以及一些单元测试。 还有更多。 因此,如果您准备好开始,那么我们就开始阅读有关安装Xcode的第一篇文章。 准备。 组。 走。

使用Swift协议提高代码质量

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

如何从NSTokenField删除令牌? [迅速4.2]

在过去的几天中,我花费了大量时间正确地实现了具有某些拖放功能的标准NSTokenField。 知道了这一点,我们可以检查objectValue对象的类型是否等于我们期望的代表对象的类型。 如果确实如此,我们知道我们需要删除整个令牌。 然后,我们通过将stringValue拆分为一个数组并将其与objectValue中的对象数进行比较来检查对象数。 如果让 anyObjectsArray = control.objectValue 作为 ? [ 任何 ], 让 tokenFieldObjects = anyObjectsArray 为 ? [标签] { //现在,我们继续删除令牌… 让 stringObjectComponents = control.stringValue.split(separator:“,”) //检查令牌数是否等于tokenField的stringValue中的对象 如果 tokenFieldObjects.count == stringObjectComponents.count { //接下来,找出要删除的对象 } } 我们确信,我们必须删除令牌。 但是,在此阶段,我们不知道必须删除哪个令牌或多少个令牌。 幸运的是,找到它相对容易(当您知道时)。 如何找出要删除的令牌? 实例方法control(_:textView:doCommandBy :)还提供了NSTextView,如果您想找出光标在令牌字段中的位置,该类非常方便。 NSTextView有一个名为rangeForUserTextChange的方法,该方法返回一个NSRange,该NSRange由位置和长度组成。 var textChangeLocation = textView.rangeForUserTextChange.location 让 textChangeLength = textView.rangeForUserTextChange.length 我们暂时忽略长度 (稍后再讨论),并专注于location 。 我们只需要检查位置是否少于对象数。 如果是的话,我们需要将其减少1以获取对象在数组中的索引,因为数组的索引为零,而NSRange从1开始。 […]