Tag: 编码

反对第三方依赖

“这不是每天的增加,而是每天的减少。 摆脱不必要的东西。” 李小龙(Jeet Kune Do)的道 介绍 请考虑以下情形:一群开发人员正在从头开始进行短期项目。 客户很着急,因此他们决定不重新发明轮子,而是使用人类尽可能多的外部依赖项。 发展的步伐是荒谬的。 几周后,吉拉(Jira)有许多封闭票。 真好 大家都很开心 几个月后,开发人员可以完全控制很多第三方依赖项,并且只有很少的代码。 几年后,有一个项目很难维护。 不再支持某些依赖项。 语言版本已更改,客户需要支付叉子维护费用。 哦,与此同时,这十七个外部框架之一存在一个小的安全问题…… 三个问题 第三方开源库很棒。 (通常)将它们抛光到可能的极限。 使用它们(通常)是一种乐趣。 (通常)它们是由比我聪明得多的人开发的,我对此非常赞赏。 Chapeau为那些将自己的时间花在使其他开发人员的生活变得更轻松的开发人员上而起。 但是,使用它们总是会带来一些风险-这可能是个问题。 如果不再支持该库怎么办? 您准备好承担维修货叉的费用了吗? 还是迁移到另一个解决方案并进行大规模重构会更便宜? 如果存在安全漏洞会怎样? 这不是一个不现实的场景-足以回顾流行的AFNetworking的情况。 添加第三方代码始终带来增加潜在的未检测到的漏洞的风险。 如果您的要求在几个月后发生变化,会发生什么? 您的项目在变化,第三方框架也在变化。 在某些时候,重叠的路径可能会明显分开。 您可能需要已经集成的第三方不提供的功能,或者以无法接受的方式提供的功能。 那你要怎么办 摘要 我不反对使用第三方库,我反对失去对代码的控制并承担不必要的风险。 在将另一个第三方依赖项添加到您的项目之前,请考虑是否确实必要。 想想如果它不再被支持会发生什么。 迁移到另一个解决方案或分叉维护的成本可能是多少。 不要误会我的意思-第三方代码不是万恶之源。 它很有用,有助于更快地交付产品并提高整体生产率。 所有这些都是在风险与收益之间取得平衡。 如果您决定使用第三方依赖关系,请使用适当的设计和合理的抽象层来保护自己。 就像古代的斯多葛式的一样-始终牢记最坏的情况。

学习Swift和iOS开发第4部分:函数

函数是编程中的核心组件。 它们是构建功能应​​用程序的基础。 函数有助于使我们的代码更易读,更分隔并最终更高效。 我们可以编写一个函数来执行特定任务,然后在整个应用程序中随意重用它。 每天,大多数人都按照一套常规生活。 他们经常做的事情甚至没有考虑或意识到自己正在做。 想一想第一次醒来时的工作。 我自己知道,我滑下床,跌跌撞撞地走过房间,走到我嘈杂的电话旁,使闹钟静音。 仅此事件便包含了我每天以相同顺序执行的几个不同步骤(除非我忘记设置闹钟)。 1.唤醒警报声 2.滑下床,尽量不要意外唤醒我的妻子。 3.错开警报。 4.使我的闹钟静音。 上面的步骤是一个功能。 我一遍又一遍地(每天早晨)完成的一组步骤。 在伪代码中,这可能类似于: var awake = false var inBed = true var walk = false var alarmSilenced =否 func getUp(){ 醒着=真 inBed =假 行走=真 AlarmSilenced =真 } 函数以自上而下的方式在内部运行代码。 换句话说, awake设置为true , inBed设置为false , walking设置为true , alarmSilenced设置为true 。 但是,我的唤醒隐喻并不完美,因为我大概需要10到15秒钟才能完全醒来,走过去并使警报静音。 现代设备可以如此快速地处理函数内部的代码,即使它逐行地运行在每一行代码中,它几乎就像是立即在运行。 简单地说,函数是一种使用给定的集合或参数执行特定动作的方法。 您将在本系列稍后将完成的许多高级项目中使用它们。 但是关于功能的讨论已经足够了……让我们来写一些吧! […]

100天学习编码。 100天制作一个应用程序。 我可以做吗?

这是我刚刚寄给自己的一段小旅程的回顾性观察。 它来自一个疯狂的梦想,渴望改变我的生活。 我希望这可以启发人们,也可以帮助人们自我思考并认为“我可以做到!” 就像我一样! 因此,快速了解我……我是两个可爱女孩的妈妈,我有一份工作(我喜欢,有点类似),但梦想在家中工作,以便我可以花更多的时间陪伴女儿。 当我开始这个旅程时,我正休产假,一个学龄的孩子,另一个睡了很多。 那给了我空闲的白日梦,这就是为什么我陷入这种疯狂的境地。 我的工作还可以,但是我真的很想避免回到9–5。 我认为我很典型,我在Facebook上花了太多时间,在Candy Crush上花了太多时间。出于某种原因,我想制作自己的应用程序不是想快速致富,而是我不确定如何找到新职业,学习新知识,但这似乎是个好主意,我可能会喜欢。 每个人都需要动力,我在这方面感到很忙。 我接下来要设定一个截止日期-那是100天的想法,这是一个不错的整数,并且足够长(我希望)能使您牢牢掌握事情并能够真正做出一些像样的事情。 我发现我在截止日期前工作得更好,而且我认为大多数人都会这样做,但这绝对需要自我激励和奉献精神,否则整个事情很容易分崩离析。 就是这样,场景已经设定好了,尽管我仍然不知道我要做什么—但是我知道随着我开始学习该编码业务,时间会随之而来。 我在家中有一台MacBook和一台iPhone 4S,于是鲁re地放弃了– Google成为了我的近亲,我走上了学习编码的好路。 我对这种外国景观一无所知,这就像在我以前一样在Microsoft Office中闲逛一样!! 当然,不久之后我就完全困惑了。 在下载了许多千兆字节并安装了Xcode之后,我感到自己已经不知所措。 我对这种外国景观一无所知,这就像在我以前一样在Microsoft Office中闲逛一样!! 按下随机的按钮看上去并不有趣,而且Apple Developer网站似乎是为知道自己在做什么的人而设计的。所以我跳下那艘船,前往YouTube。 值得庆幸的是,一个大概6岁的孩子的声音帮助我了解了Xcode的基本知识,并让我在手机上运行了一些东西。尽管它是白色的屏幕,但它至少做了视频中说的和感觉到的就像事情开始朝着正确的方向发展。 正是在这一点上,我开始了解Swift和ObjectiveC。是的,它们是不同的东西,一个与另一个不一样! 在我看来,Objective C是更好的选择,因为它存在的时间更长,因此我猜想存在更多的教程。 我想我永远不会知道这个选择是否是一个好的选择,但是我选择了它,过了一会儿它实际上变得可读了……好吧…… 数小时或数天的沮丧,希望之后会带来很多满足感… 人们曾说过学习编码就像学习外语一样。 我不同意! 学习编码涉及更多的皱眉和诅咒。 学习编码带来更多的情感。 数小时或数天的沮丧,希望之后会带来很多满足感……所有这些都被撕毁并一次又一次地反复遍历(编码术语!)。 坚持不懈是一项关键技能,逻辑可以帮助,最重要的是-在Google不能正常工作或毫无意义时能够对Google进行正确的选择! 在学习了一个基础知识并思考了我的潜力一周之后,很明显,我并不想写下一部《 Candy Crush》或什至是游戏。 我不得不保留自己的想法,并思考一些基本但有趣的东西。 也许可爱。 我和我的女儿一直在与着色应用程序Colorify一起玩,我真的很喜欢它的简洁设计和简单自然。 它轻松,简单,最后产生了“物理”效果,您可以为此感到自豪。 我开始尝试想像像我这样的新手可以实现的类似东西。 我将永远记得我那才华横溢的灵感。 那是使您感到超级兴奋和动力的一种感觉。 我从学校逃课回来,和往常一样,穿过我的长女书包,看看那天她工作的成果。 她做了一些漂亮的图画,这当然值得冰箱门用,所以我走过去,清理了粘贴在上面的所有其他杰作之间的空间,发现了一些自由的磁铁,并自豪地粘贴在上面。 当我站起来欣赏这个新的杰作时,这个想法和构想直接浮现在我的脑海里! 像许多家庭和冰箱一样,我们拥有典型的AZ磁铁,还有诗歌词,因此您可以制作有趣的句子和诗歌。 就是这样! 一个带有单词的虚拟冰箱,您可以随意拖拉以制作诗歌和有趣的句子。 幸运的是,对于这个想法是突破性的,新颖的,或者是在1000年前完成的,我并没有太在意。 感觉是一个好主意,我可以实现,或者至少在脑海中设想了它的外观和工作方式。 […]

我们的健康编码惯例以及它们如何为您提供帮助

在Mobile First,我们以成为快乐的编码员而感到自豪。 在鼓励实验的同时,我们也认识到有时最好遵循我们自己的久经考验的指南以获得最佳结果。 为了保持平台独立性,我们寻求遵循的通用规则,并且不允许自己陷入诸如制表符缩进或语言功能之类的细节中。 我们是快乐的编码员,对我们来说,这意味着…… 复制代码行时,可能是在复制错误(错误),非最佳方法或外部依赖项。 如果有问题的代码分散在您的整个应用程序中,您将无法轻松进行改进。 查看高度重复的代码也将给您带来真正的déjàvu! 始终使代码起作用并注入依赖项/参数。 在创建,理解,测试和错误修复代码时,在一堆中做太多事情是无法管理或维护的。 这就是为什么我们使用单一责任原则。 从功能到对象,甚至到整个应用程序(例如Facebook Messenger),都可以转换为各个级别。 始终将任务分解为更小的简单组件,这些组件只能访问其所需的信息。 不要让人们在您的实现内部获取肮脏的手套! 仅公开已设计并经过测试的要更改的内容。 确保您的实现已通过单元测试针对这些更改进行了测试。 从外部角度查看对象,它的协议有意义吗? 始终使用访问级别的保护,将所有内容设为私有,并在需要时进行升级。 寻找定义明确的协议。 具有全局范围的变量和函数的全局文件(称为“常量”,“助手”或“ utils”)倾向于链接系统的不相关部分,从而使代码难以重用。 单例有相同的问题。 大量使用单例使理解对象依赖性变得很困难-因为您将必须检查实现以查看其使用方式。 由于难以模拟单例依赖关系,因此很难进行单元测试。 始终倾向于依赖注入而不是全局范围和单例。 常量应保存在其所属类的范围内。 这样可以更清楚地了解哪些对象需要运行,从而使代码更易于进行单元测试。 考虑一下对象的生命周期,不要在不需要时不挂对象。 幻数和文字使我们更难理解它们对代码的影响。 它们是非描述性的,并且经常在一个以上的位置需要相同的值,因此,当您要调整该值时,需要在多个位置进行调整……而总是忘记一个位置! 参数化常量/文字,并为元素赋予有意义的名称。 我们编写的所有代码都意识到会被同行评审。 清楚地布置代码,以使其易于阅读,理解和使用描述性名称,以便您的同事可以解密所有内容。 当您在那里时,请先查看自己的拉取请求,然后再添加对等项。 使用源代码管理时不遵循某个过程可能会导致提交未经测试的代码。 它还可能导致提交遗失,进而破坏同级的构建。 遵循 git Flow :使用功能分支,重新设置基础并使用拉取请求。 创建发布分支,仅允许错误修复,并禁止从dev分支进行合并。 一遍又一遍地执行相同的代码会变得很老,因此我们在代码中寻找有用的模式。 如果有人注意到我们面前的一种模式,为什么还要重新发明轮子呢? 将通用代码拆分为可重用的可测试框架。 寻找现有框架,进行审查并做出贡献。 在事后看来,通常会有更好的方法来做某事,我们对此表示欢迎。 我们认为重做组件化代码的各个部分应该是常见的做法。 识别何时该重构。 如果一段代码偏离了其原始意图,那么重构比将其击败来提交要好! 可能只是适当地重命名的情况,但是如果有更好的方法可以将其标记为重构。 重构是件好事,这就是世界的运作方式。 相当于生活圈的编码! …因此,我们认为自己是快乐的编码员。 我们鼓励您尝试一下并创建自己的准则。 […]

ARKit —几何,材质,节点,手势哦,我的天哪!

本章是我的《 iOS开发者的ARKit》一书的一部分。 立即获取该书,并开始构建出色的增强现实应用程序。 在上一章中,您了解了创建默认ARKit应用程序所涉及的组件。 您还亲眼目睹了一只漂浮在您面前的太空船。 希望您已将其失踪的太空船告知了NASA! 在本章中,您将学习如何创建具有不同几何形状的虚拟对象,使用材质进行装饰,最后将它们作为SceneKit节点对象添加到现实世界中。 您还将学习如何使用手势和命中测试与虚拟对象进行交互。 让我们学习一些毕达哥拉斯定理。 几何: 几何表示与形状相对应的对象的线框。 SceneKit框架开箱即用地支持许多几何,此处显示了其中的一些。 SCNPlane :指定宽度和高度的矩形单边几何 SCNSphere :球形(或球形或球形)几何 SCNBox :六面多面体几何,其面均为矩形,可以选择带有圆角和圆角 SCNPyramid :直角金字塔几何 SCNTube :管的几何形状。 右圆柱体,其中心轴上有一个圆孔 每个类别代表一个特定的几何形状,可以一起使用以创建更复杂的形状。 材料: 默认情况下,几何图形只是线框。 您可以将几何体视为人类的骨骼。 材质就是您用肉装饰骨架的方式。 素材可以是颜色,图像甚至视频。 在阅读本节内容时,请确保您没有靠近食人族,否则他们可能会有错误的主意。 节点: 节点代表可以添加到场景中的对象。 只要未明确隐藏,添加到场景中的任何内容都可以被用户看到。 您可以将节点视为屏幕上的单个元素。 如果您要构建赛车游戏,那么一个节点可以代表一辆汽车。 如果要构建太空飞船游戏,则该节点可以是太空飞船,而一个单独的节点可以代表导弹。 节点也可以是复合节点,这意味着它们可以包含其他节点。 您可以想到一个代表大型卡车的节点,以及一个代表拖车,轮胎,货物等的子节点。 为真实世界添​​加形状: 首先,我们向增强现实世界添加一些形状。 在Xcode 9中创建一个新的Augmented Reality项目,并将清单1中的代码添加到viewDidLoad函数。 覆盖func viewDidLoad(){ super.viewDidLoad() //设置视图的委托 sceneView.delegate =自我 //创建一个新场景 让场景= SCNScene() let box = […]

iOS | 我如何使用Shell脚本处理图像/情节提要的硬编码字符串

硬编码字符串很麻烦,编译器无法检测到错字,而且重命名也成为问题。 为了解决此问题,我使用了shell脚本来自动生成文件,这有助于为代码添加约定并确保这些硬编码字符串的安全性。 如果您不清楚添加运行脚本的基本步骤,请阅读此处。 请执行以下步骤: 在项目的“ Target Dependencies”下添加运行脚本,然后输入以下代码行: #所有要执行的运行脚本必须在mainScript.sh中键入,不要在此处写任何内容 $ SRCROOT / shellScriptStringGeneration / Build-phase / mainScript.sh 2.从附加的github项目 —将构建阶段目录复制到您的项目 —使用终端“ chmod u + x mainScript.sh”添加执行权限 —从所有shell脚本中删除“目标成员身份” 3.现在创建空的Constants.swift / Constants.images.swift / Constants.storyboards.swift /添加到您的项目中 4.在每个shell脚本中,更新输入路径,如下图所示

推送通知基础(2之2)

我完成了上一篇文章,总结了如何配置您的应用程序以接收推送通知,但是我没有讨论一旦这些通知到达时您可以怎么做。 所以我们开始。 除非您可以响应这些推送通知,否则向您的设备发送推送通知并没有真正的帮助。 这就是我今天将向您介绍的内容。 具体来说,以下内容: 响应用户对推送通知的操作 在前台处理推送通知 在后台处理推送通知 1和2均由UNUserNotificationCenter处理,其中3由UIApplicationDelegate严格处理。 响应用户对推送通知的操作 UNUserNotificationCenter是一个非常强大的API,它使您可以计划本地通知,配置推送通知动作以及与用户对推送通知的动作进行交互。 iOS在通知方面已经走了很长一段路,而这仅仅是帮助开发人员构建美好体验的另一层。 我们将只专注于响应用户操作。 当推送通知发送到设备时,会显示类似的内容 用户可以选择向右滑动并打开推送通知,或向左滑动并查看一些选项。 无论用户做什么,应用程序都将完全相同地处理它。 UNUserNotificationCenter具有使用方法userNotificationCenter(didReceive: withCompletionHandler:)的协议UNUserNotificationCenterDelegate 。 这是进入应用程序的入口点 。 启用此功能后,我们现在可以在后台响应远程通知。 将通知有效内容中的content-available标志设置为1可使您的应用程序知道有信息要处理,它将触发必要的应用程序委托回调方法。 func application(_ application:UIApplication,didReceiveRemoteNotification userInfo:[AnyHashable:Any],fetchCompletionHandlercompleteHandler:@转义(UIBackgroundFetchResult)->无效) 与我们通过UNUserNotificationCenterDelegate获得的UNNotificationResponse对象不同,我们在UNUserNotificationCenterDelegate获得准系统有效负载[AnyHashable: Any] 。 用户尚未与推送通知进行交互,因此动作标识符将是无关紧要的。 但是,我们得到了completionHandler 。 再次使用此完成处理程序来让系统知道任何处理已完成。 这对系统很重要,因此可以 再次终止应用程序 将应用程序保留在后台,但减少分配给该应用程序的资源量 yada yada yada有助于延长电池寿命,保持系统效率。 此完成处理程序和用户通知完成处理程序之间的区别在于其签名。 这里的完成处理程序采用UIBackgroundFetchResult ,它可以是noData , newData或failed 。 这很清楚,该处理应该是进行任何更新的快速网络调用 ,因为该应用程序没有太多的活动时间(实际上,我相信这是30秒左右)。 后台远程通知的主要动机是,当用户进入“多任务”模式时,他们可以查看每个应用程序的最新状态。 老实说,这提供了相当不错的用户体验;)。 后台远程通知处理不应与后台获取混淆,后台获取是后台工作的一个完全不同的方面。 我将在以后的文章中专门介绍后台获取。 希望您能读一读! 更多款待即将推出!

学习Swift和iOS开发第5部分:数组

数组是有序集合类型。 它存储多种类型的数据集合并按数字顺序排序。 我们在第3章中学到的变量非常适合存储单个值。 在现实世界中,我们经常需要跟踪属于同一类别的多个数据。 例如,员工薪水,我们收藏中每本漫画书的价值或商店库存中每件商品的成本。 为上述每个项目创建一个单独的变量很费时,而且老实说这不是一个好代码。 这就是数组的来源。*提示胜利的音乐*! 数组是一个有序的集合,允许我们存储多个值。 在本章中,我们将看到它们的实用性。 搭建游乐场 首先,如果尚未打开Xcode,请点击Create New Playground 。 命名为“ Arrays”,然后单击“ Next 。 选择某个位置以保存此.playground文件,然后单击“ Create以保存它。 您应该会看到类似下面的屏幕。 删除左侧的所有样板代码,但根据需要保留import UIKit 。 创建你的第一个数组 让我们使用以上示例之一:收藏集中每本漫画书的价值。 🤓想象一下,您有一个收藏集,尽管很小,但其中包含5本漫画书。 它们各自具有不同的值。 我们可以为每本漫画书创建一个变量,并像这样存储值: var comicBook1 = 10.0 var comicBook2 = 27.50 var comicBook3 = 1015.0 var comicBook4 = 55.0 var comicBook5 = 2.0 如果有人偷了您的一本漫画书怎么办? 如果您卖了一个怎么办? 您将需要手动删除该行代码,然后重新编号其后的变量,因为每个变量都有特定的编号和顺序。 相反,我们可以创建一个名为comicBooks的数组,并将值放在其中,如下所示: var comicBookValues […]

经验丰富的程序员参加编码训练营的5个原因

DevMountain培训了很多业余或新手编码人员,这些人员以前很少或没有经验,但是我们也有一些学生已经知道如何编写编码。如果您是一位经验丰富的程序员,那么您可能对回校没有太多的考虑。 我们将解释为什么我们的资深学生会在这里,以及如何学习现代技术技能比您想象的要容易。 1.编码训练营更新您的技能 技术世界飞速发展,如果您不时重新访问自己的技能,那么您可能会落在后面。 DevMountain编码新手训练营使您可以从了解您现在需要了解的现实世界的专业人员那里学习最新的语言和软件。 在我们的网站上查看我们的课程选项,发现从编码新手训练营中学到的新技能! 2.加快了编码训练营的速度/快节奏 作为编码员,程序员或企业家,您不能花时间学习新技能。 DevMountain的新手训练营可让您快速获得所需的培训和信息,并提供全职或兼职学习的选项。 它比回到学校更快,比自学更快。 在DevMountain,我们知道您的时间很宝贵,并且您的日程安排可能很忙,因此无论您的情况如何,我们都会尽一切努力使我们的课程尽可能地易于访问。 3.编码训练营可帮助您建立连接 如果您已经有一段时间了,那么您可能已经知道拥有正确连接的重要性。 我们的新手训练营计划为您提供了与编码专家以及新锐编码员并肩工作的机会。 您还将有机会参加我们的许多活动和会议。 4.给您的简历认真的改头换面 恢复看起来有些乏味吗? 在这里,在DevMountain,我们作为该国评分最高的编码学校之一而享有盛誉,这使其成为任何工作申请中令人印象深刻的补充。 同样,与我们的专家团队紧密合作将确保您离开训练营并获得出色的参考。 5.重新发现您对编码的热情 DevMountain是在您选择的职业道路上寻找新灵感的理想场所。 我们营造一种创造力和发现力的环境,您将被志趣相投的志同道合的人所包围。 这样的专用空间帮助许多学生点燃了对职业的热情。 不过,请不要相信我们的话-在我们的推荐页面上听听我们的学生对我们课程的喜爱。 你还在等什么? 我们拥有您升级简历并将职业提升到新水平所需的一切。 您将能够获得在当今市场上所需的技能,快速获取它们,并在使用过程中建立新的联系。 这是您宝贵的机会,可以充分利用您的时间和教育。 索取课程提纲,以了解您将在DevMountain学习的内容。 您甚至可以与我们的团队见面,并查看他们的证书。 我们迫不及待想要帮助您取得更多成就并继续发展您的事业。

使用BrightFutures,Alamofire和Operations排队上传多张图像

在开发我们的iOS应用程序“ Lines”时,我遇到的最大问题之一是创建可靠的图像上传队列。 该应用程序支持离线使用,因此,如果用户保存图像,则照片的本地标识符存储在CoreData中。 连接设备后,将立即获取并上传所有图像。 为了创建有效的上传队列,我必须使用以下框架: Alamofire用于http网络。 为了避免在获取多个图像时出现内存泄漏,我使用了OperationQueue来限制要处理的并发图像的数量。 而且BrightFutures将保证整个过程的顺利进行。