Tag: xcode

为什么我停止在iOS项目中使用Storyboard和Xib

故事板可帮助我们简化创建iOS应用程序的UI。 拥有一个仅需几次单击和拖动的模拟应用程序,真的很棒,对吗? 我们甚至可以忘记导航,即每个应用程序使用的功能。 仅通过从一个屏幕到另一个屏幕的链接即可完成所有导航,如果转换很复杂,有时还可以使用自定义代码。 苹果正在继续改进Xcode的Interface Builder,以添加越来越多的功能来帮助开发人员简化其UI存根。 例如,我们现在可以预览不同屏幕尺寸的渲染。 我发现此功能非常有用。 当我们由一个小型团队(或一个人)开发一个小型应用程序时,所有这些好东西仍然是好的。 一旦应用程序扩展,团队就会成长,使用情节提要和.xib可能会成为噩梦。 让我们看看为什么。 如果我们没有足够强大的MacBook(Pro),则当我们不得不打开一个大的故事板时,Xcode可能会冻结您的计算机一段时间。 即使使用简单的情节提要板,我也花了大约10秒钟的时间在Xcode中打开它。 对于必须使用旧的MacMini或旧的MacBook开发的人来说,这可能会降低他们的工作性能。 当我们创建具有多个屏幕的大型应用程序时,情节提要文件可能会非常庞大​​。 概述和遵循应用程序流程并非易事。 如果有新的开发人员加入该项目,他将很难理解屏幕之间的逻辑和转换。 当然,我们仍然可以采用一种解决方法来创建使用情节提要面板场景,以将其分隔为多个情节提要面板,并避免使用大型情节提要。 但是,从中创建View / ViewController的实例时,开发人员应该照顾故事板名称或Xib名称。 使用情节提要/ xib时最不方便的是与.storyboard或.xib文件存在某些合并冲突。 当团队的开发人员在不同的存储库分支中同时编辑同一.xib或.storyboard,然后合并到主分支中时,就会发生这种情况。 情节提要和xib文件均为XML格式。 但是这些XML不是用户友好的。 Xml节点是自动生成的,这使我们很难知道xml中带有节点的UIView的引用。 每个节点还具有很多属性(用于指定高度,宽度,位置,颜色等)。 发生合并冲突时,如果合并不正确,将导致错误的结果,有时我们会破坏xml格式,因此无法打开.xib或.storyboard文件。 基本上,我们不会通过Storyboard / xib创建ViewController和View,而是将它们全部写入* ViewController.m / .swift或* View.m / swift。 在这篇文章中,我只会以Swift来编写代码,因为我更喜欢Swift而不是Objective-C,而且我相信你们也喜欢Swift。 假设我们要创建一个包含登录名和电子邮件文本字段以及用于处理登录的按钮的登录屏幕,如下所示: 我们将必须创建两个类: LoginView.swift和LoginViewController.swift 。 LoginView.swift继承了 UIView的子类,并且包含用于构建要在所有自动布局约束条件下显示的视图的代码。 LoginViewController.swift继承了 UIViewController的子类,并包含我们需要应用于这些元素的控件处理程序。 首先,让我们看看我们在LoginViewController.swift文件中要做的事情。 它不是那么复杂,对吗? 我们要做的就是重写loadView函数,以告知LoginViewController它需要加载并使用LoginView类中的自定义视图。 然后,ViewController应该控制此View内部的功能元素,以控制用户单击登录按钮或关闭按钮时的操作 。 在ViewController类中,我们不实现任何视图布局或视图的自动布局。 所有视图布局必须在View类内部完成。 这样,ViewController将变得更轻,更清洁。 […]

KatılımcıRöportajları

“ÖğrenmeninYaşıYok”(canlıyayın)

Como安装和使用CocoaPods

iOS和OSX上的CocoaPods,El gestor,mas ado,ados de laroller,Manual masfácilde agregar estas和tu proyecto。 步骤1:安装 Mac上的Pega este comando en el终端。 须藤宝石安装cocoapods 推荐使用可可豆。 参照文献中的控制权和所有权利的证明书。 CocoaPods指南 CocoaPods依赖项管理器的官方文档站点。 guides.cocoapods.org Paso numero 2:Crear tu Podfile Tenemos tres opciones para crear este archivo,您个人设定的建议零售价。 Estando en laraízdel proyecto usa este comando en tu终端。 触摸Podfile Estlam comando creara un archivo en tu Directorio llamado Podfile,坦比亚puedes usarlo para […]

如何成为一名出色的iOS开发人员!

世界就像彩虹🌈,每种颜色都是美丽的。 就像彩虹一样,开发人员的生活也因其惊人的技术而变得丰富多彩。 但是有时,开发人员在大多数时间里总是不知道要学习什么或掌握什么工具。 这就像选择的悖论。 苹果每年都会发布惊人的框架。 我们正在尝试掌握它们,但我们无法一次掌握所有它们。 您不能同时掌握CoreML和ARKit,增强现实和机器学习是两个不同的海洋。 就像在南太平洋和北大西洋之间游泳一样。 好吧,如果可以的话,请称自己为超人或超女。 在这里,我整理了一系列工具和说明,它们将帮助您成为一名出色的iOS开发人员。 请注意,这不是Internet上所有资源的列表。 我只是挑选了最好的资源来使您的生活更轻松。 我假设您已经设置了MacBook和Xcode。 好吧,如果您打算成为一名出色的iOS开发人员,请考虑购买MacBook,相信我,它将长期为您提供帮助。 开始吧! 设计准则 您现在处于一个新的星球。 在这里,我们作为iOS,macOS,watchOS和tvOS应用程序的开发人员,请确保无论我们生产什么应用程序,都遵循Apple的设计准则。 您应该考虑的第一件事是,改变设计观点。 习惯颜色,彩虹和iPhone应用程序。 下载许多很棒的应用程序,并了解设计,动画,交互是如何完成的以及其吸引力。 您还可以查看Pttrns和Uplabs,以查看令人惊叹的iOS用户界面。 注意,设计确实很重要。 您将要为iPhone和iPad用户构建应用程序,而不能使用Windows 98设计标准或观点来构建这些应用程序。 因此,改变您的设计观点,并改变您的设计标准。 编程语言 无论是Swift还是Objective-C,请确保您了解足够。 有许多公司在日常开发中仍在使用Objective-C。 但是我们都知道Swift是未来。 因此,了解Objective-C的工作原理,也许可以在Objective-C中构建几个应用程序,然后跳入Swift。 这样,当您使用旧的Objective-C项目或第三方库时,就不会卡住。 要了解Swift编程语言的基础知识,您可以阅读Apple为开发人员编写的书。 有一个斯坦福iOS开发视频课程,相当先进。 联网 网络是一个非常重要的概念。 今天或明天,您将向服务器发出数千个网络请求。 最好了解所有网络概念。 从Foundation框架开始,找到通往NSStream,CFNetwork,CFNetServices,NSNetServices和SwiftNIO的方式。 1.大中心派遣 进入网络后,您将逐渐感到并发的重要性。 您必须同时异步请求多个资源。 Grand Centra Dispatch(GCD)有很多帮助程序方法来解决所有多线程方案。 如果您想成为一名优秀的开发人员,掌握GCD非常重要。 查看本课程,以掌握使用Swift的iOS网络。 设计模式 iOS中有很多设计模式。 默认情况下,我们遵循一种基本设计模式,即MVC(模型视图控制器)。 在构建复杂的项目和系统时,我们需要一种不同的方式来处理所有的类,模型和视图。 这就是这些不同的设计模式发挥作用的地方。 在协作环境中工作时,了解这些设计模式将对您有所帮助。 创意性 :单例,生成器,抽象工厂,工厂方法。 […]

Xcode中的3个基本调试工具

Xcode是一个功能强大的IDE,它提供了各种各样的调试工具。 尽管许多工具很容易发现和使用,但我注意到许多iOS开发人员并不知道Xcode隐藏的高级功能(但必不可少)的调试功能是否存在。 我决定为Xcode编写一份简短的调试技巧清单,它表示大多数情况下用于调试代码的工具。 我与他们分享是希望发现这些隐藏的宝石后能提高您的生产率。 1.查看层次结构调试器 我很惊讶地看到一些经验丰富的iOS工程师不知道此功能的存在。 通常,通过以编程方式更改屏幕上所有视图的背景颜色来调试视图层次结构,以便观察发生的情况。 如果您知道“ Debug View Hierarchy”按钮,该按钮隐藏在Debug Area栏中(“恢复/暂停”调试按钮旁边),则您会觉得效率很低。 此功能使您可以在称为视图层次结构调试器的3D渲染中研究视图对象的关系 。 您可以很好地看到布局树,您可以在其中立即注意到UI是否有问题。 在设置付费工具(例如Reveal App)之前,请尝试使用此功能。 Xcode内置的视图层次结构调试器功能非常强大,通常是调试视图层次结构所需的所有工具。 在为我为iOS App模板创建的通用集合视图控制器上工作时,此工具在调试流畅的布局类方面非常了不起,该类允许集合视图单元具有灵活(不相等)的宽度和高度。 另一个提示-我喜欢使用此工具来查找特定屏幕/组件的代码在哪里,因为您可以识别轻松备份用户界面的类的名称。 在不熟悉的代码库中非常方便。 2.丰富的断点 如果您是iOS的新手,则可能只使用了简单的断点,即可在调试期间闯入所需的任何方法,以观察当前的运行时上下文(变量,状态,对象关系等)。 您可以通过简单地单击特定代码行的左侧栏来设置断点,并且只要该行正在运行,Xcode就会暂停程序的执行。 许多iOS开发人员不知道的是,断点甚至比常规用例还要聪明。 实际上,它们令人印象深刻。 您可以使用以下一些实用技巧: 条件断点 -仅当给定条件为true时,断点才会命中。 这对于调试列表(例如)非常有用,例如,您只在乎第N个单元格中发生的事情,并希望跳过暂停每个上一个列表项的执行。 忽略 —您可以在断点处忽略固定次数的暂停。 这在许多情况下都派上用场,包括上述情况。 动作断点 -遇到断点时 ,您可以告诉Xcode执行特定的动作。 这些动作可以是记录消息,运行调试器命令(例如“ po”)甚至运行Shell脚本。 断点激活时,此处的一个非常有趣的功能是播放声音。 在处理经常调用的方法(例如layoutSubviews )中的断点时,这样可以节省大量调试时间。 要使用所有这些功能,可以在断点上单击鼠标右键,然后选择“ 编辑断点 ”。 3.异常断点 调试异常时,这是救生员。 您可以仅添加此通用Xcode断点,而不是手动查找导致异常的代码,该断点将在引发异常之前暂停执行。 这样,您可以调查引发异常时的确切上下文,几乎可以在几秒钟内准确显示出错误所在。 在调试不熟悉的代码时非常有帮助。 要设置此断点,请转到断点导航器( Command + 8 ),单击底部的“ […]

带有Xcode 10的Xcode服务器

Xcode Server是几年前由Apple推出的一项持续集成服务。 在上一篇有关Xcode Server和Xcode 9的帖子中,我们介绍了WWDC 2017上有关“Xcode和Xcode Server签名的新增功能”的会议中宣布的大部分主要增强功能,自此之后,使用Xcode Server变得如此容易且容易使用无痛。 Xcode 9版本中宣布的主要增强功能是 内置Xcode服务器 服务器内的代码签名和设备配置以及自动代码签名 Xcode服务器上运行的无头测试 所有这些功能使Xcode Server成为iOS应用程序连续集成的轻松选择。 但是,在2018年初发生了一些改变游戏规则的事情。苹果收购了另一项持续集成服务BuddyBuild。 这是Xcode Server及其持续开发中的主要工作。 这可能是原因,WWDC2018在持续集成方面是如此令人兴奋。 苹果没有对持续集成和Xcode Server一言不发。 这是非常可疑的事情。 好吧,这是一个完全不同的主题,但是作为本文的一部分,我们将介绍在Xcode 10中使用Xcode Server的外观以及是否有任何更改。 Xcode 10:Xcode服务器 Xcode 10具有深色模式,因此很有趣的是从头开始设置Xcode Server的外观。 我们将在Xcode 10中创建一个包含单元和UI测试目标的空白应用程序,我们将其称为Xcode10-XcodeServer。 启用Xcode服务器 和以前一样,我们可以在Xcode Preference中看到“ Servers&Bots”标签。 我们可以使用本地Mac或其他Mac设置Xcode Server。 我们需要选择Mac和Integration用户。 请参阅下面的GIF,以了解在Xcode 10中启用Xcode Server的过程。 启用Xcode Server之后,我们将收到macOS通知,告知Xcode Server已准备就绪,并且我们将在顶部显示一个图标,其状态为Xcode Server,如下所示。 现在,我们已经设置了等待集成的Xcode Server。 添加Xcode服务器 一旦启用了Xcode服务器,则需要将其添加到本地Xcode中,以便我们可以创建机器人。 和往常一样,可以通过添加新的Xcode Server从Xcode Preference-> Account部分完成。 我们必须提供Xcode […]

iOS应用中的本地化-快速方法

如果您想要一个在多个国家/地区支持多种语言的应用程序,则应决定使用iOS提供给您的本地化功能。 您可以在应用程序中本地化许多内容,例如图像,文本,甚至是自动布局,但最常见的是在视图上显示文本或只是字符串。 您可以在应用程序中处理本地化,但是最常见的方法是使用本地资源。 您需要做的第一件事是将Localizable.strings文件添加到Xcode项目中。 另外,请确保在项目设置中选中了“使用基础国际化”。 然后转到以前创建的Localizable.string文件,并在右侧的Localization菜单中选中所有语言复选框。 之后,您的文件应如下所示: 现在我们可以用一些示例数据填充文件: 和德国版本: 目前,我们已经在代码库中配置了基本的本地化设置。 但是,我们多久使用一次呢? 在许多项目中,您可以找到以下内容: 好的,此代码还可以,但是在键盘上输入错误和打错也不太困难。 之后,我们可以花几分钟寻找问题的答案:“为什么我们的字符串不显示?!” 我们可以考虑如何更快地做得更好? 当然可以,我将描述如何。 第一步是创建能够从Localizable.strings文件读取我们的本地化字符串的服务。 在此示例中,我决定先创建协议,以防稍后在单元测试中模拟我的服务。 这是一个示例,显示如下: 我们还需要提供协议的实现: 您可能想知道这个“ LocalizedStringKey”是什么。 这是所有此实现的核心功能,但它本身很简单-只是枚举包含所有键(作为案例)而不是字符串,从而可以防止我们在接收资源字符串时犯错误。 为了节省时间,您可以编写简单的Python / Ruby脚本,该脚本将基于Localizable.strings文件生成此枚举。 现在是时候使用我们的实现了: 首先,我们需要创建服务的实例,例如,您可以通过一些DI技术将其传递给ViewController。 之后,您可以简单地在标签,字符串等上使用它: 结论: 如您所知,Swift中的枚举为您提供了许多可能性,而这仅仅是另一种。 这是您可以构建的唯一示例,可以在代码中提供高级Swift API。 随时基于此构建更多的本地化服务。 例如,您可以创建图像或自动布局的方法。 希望您会喜欢。

在Swift中选择正确的失败方法

Swift的一个主要重点是编译时安全性-使我们(作为开发人员)可以轻松地专注于编写可预测性更高,更不易出现运行时错误的代码。 但是,有时事情确实由于各种原因而失败-因此,本周,让我们看一下如何适当地处理此类失败,以及我们可以使用哪些工具来做到这一点。 几周前,我们在“在Swift中处理非可选的可选内容”中介绍了如何处理不是真正可选的可选内容 。 在那篇文章中,我介绍了将preconditionFailure()与guard结合使用的情况,而不是强制展开,并介绍了微框架Require,它提供了方便的API。 从那篇文章开始,许多人问到preconditionFailure()和assert()之间有什么区别,以及它与Swift的throwing功能之间的关系。 因此,在这篇文章中,让我们仔细研究一下所有这些语言功能以及何时使用它们。 让我们从清单开始 据我所知,这是所有可以处理Swift中错误的方法: 返回 nil 或错误枚举值。 错误处理的最简单形式是从遇到错误的函数中简单地返回nil (如果使用Result枚举作为返回类型,则返回.error情况)。 尽管这在许多情况下确实很有用,但将其过度用于所有错误处理会迅速导致使用API​​麻烦,并且还存在隐藏错误逻辑的风险。 引发错误 (使用throw MyError ),这要求调用者使用do, try, catch模式处理潜在的错误。 另外,可以使用try?忽略错误try? 在呼叫站点。 使用 assert() 和 assertionFailure()来验证某个条件为真。 默认情况下,这会在调试版本中导致致命错误,而在发行版本中会被忽略。 因此, 不能保证触发断言后执行就会停止,因此有点像严重的运行时警告。 使用 precondition() 和 preconditionFailure()代替断言。 关键区别在于,即使在发行版中,也总是*对它们进行评估。 这意味着您可以保证,如果不满足条件,执行将永远不会继续。 调用 fatalError() -在子类化符合NSCoding系统类(例如UIViewController fatalError() ,您可能已经在Xcode生成的init(coder:)实现中看到了此NSCoding 。 直接调用它会杀死您的进程。 调用 exit() ,使用代码将其存在于您的进程中。 当您可能想退出全局范围时(例如在main.swift ),这在命令行工具和脚本中非常有用。 *除非您使用 Ounchecked 优化模式 进行编译 。 可恢复与不可恢复 选择正确的失败方法时,要考虑的关键是确定所发生的错误是否可恢复 […]

因此,我测试了Dice并添加了解析器(3之2)

仍然是2017年。 我一直在使用GitHub进行开发,我以前写过一篇关于Dice类的文章(读者注意:请参阅上一篇文章)。 本文跟进了我如何测试Dice和实现解析器的方法。 第三部分将介绍如何将其全部放入GitHub。 我知道。 并不令人兴奋。 但是,希望对某些人有所帮助。 或者,对我的未来版本。 总结:关于目标或一般要求,我想代表 2d4 + 1之类的骰子骰 ,这些骰子已 在GitHub中集成和测试 。 在上一篇文章中,我描述了使用沙盒驱动开发( SDD )来设计出一种似乎涵盖了《地牢大师指南》中的用例的设计。 这是描述类型的简化UML,主要类型是名为Dice的协议(接口): 现在,我将认真对待测试,我从Swift Playground过渡到带有Xcode项目的Xcode工作区,其中有两个iOS目标: 一个名为RolePlayingCore的框架,以及 用于测试该框架的单元测试包。 在框架中加入Dice类之后,就该编写一些测试了。 现在,对于一些严重的滴滴涕 我不是TDD的正式从业者,但这不是因为缺乏需求。 这更多是因为习惯,缺乏接触,年纪大了,成为一名经理, yadda yadda yadda 。 我只是喜欢遵循SDD首先解决问题,这意味着在开始编写第一个测试之前我已经有了“代码”。 我喜欢将其视为开发驱动的测试 ( DDT )。 从好的方面来说,我真的在为我编写的所有代码编写全面的测试,因为我了解到它有助于验证和改进它。 我执行现有代码测试所遵循的心理检查清单是: 从下至上编写测试(核心类型) 测试类和结构生命周期,创建和销毁 测试标称用法和正常输入 测试否定情况,无效输入或抛出错误 以代码覆盖率为指导,测试每个代码路径 测试有趣的事物(特定用例) 测试性能(如果需要) 通过在修改或扩展代码时添加测试和测试点来维护代码覆盖率目标 在进行过多测试之前,我为Test之下的RolePlayingCore方案启用了代码覆盖率“收集覆盖率数据”,以便在编写测试时可以用来指导我: 我要编写测试的第一件事是Die,特别是如何测试滚动Die,以此作为测试Dice组合的起点。 我考虑了一下,决定一起测试Die和RandomNumberGenerator,而不是模拟随机数生成器,或者提出其他一些人为的解决方案。 因此,测试将需要产生平均值,最小值和最大值。 这是我所做的: func testRollDie(){ print(“ Die […]

用嵌套类型命名Swift代码

– ⚠️已弃用 有关本文的最新版本, 请在Sundell的Swift上阅读 ,而您也可以在其中找到100多种有关Swift的文章。 中型版本尚未针对Swift的最新版本进行更新,也未进行其他改进(例如语法突出显示)进行了更新。 – 尽管Swift尚未提供专用的namespace关键字,但它确实支持其他类型的嵌套类型。 让我们看一下如何使用此类嵌套类型可以帮助我们改善代码的结构。 许多Swift开发人员习惯于通过在类型的实际名称中包括结构级别来进行命名PostTextFormatterOption -使用诸如PostTextFormatterOption (用于Text Formatter PostTextFormatterOption的Text Formatter的Option )之类的名称。 这可能是因为,这几乎是在Objective-C和C中进行“穷人命名”的唯一方法,并且像许多其他约定一样,它已经延续到Swift中。 让我们以上述类型为例,看看Post , PostTextFormatter和PostTextFormatterOption : 现在让我们看一下如果我们将它们构造为Post内部的嵌套类型,则上述类型将如何变化: 嵌套类型方法的一大优势是,我们现在可以通过快速查看代码来清楚地看到类型之间的结构和关系。 我们还减少了初始化程序中的冗长性,使其更短Set易于阅读(现在options参数只是Set类型而不是Set )。 现在,我们在呼叫站点也有了清晰的层次感-与Post相关的所有内容现在都在Post.下结构整齐Post. 命名空间。 以下是格式化帖子文本的格式: 但是,使用上述嵌套类型也有很大的弊端。 该代码在垂直方向上是“向后”的,其中父类型的实际内容一直向下推送到底部。 因此,让我们尝试通过翻转结构来解决此问题-将嵌套类型向下移动到底部,而不是将它们放在顶部(为方便MARK ,我们还会添加一些MARK )。 到底是将嵌套类型放在顶部还是底部,这绝对是个人喜好。 我有点喜欢它如何使父类型的实际内容保持在顶部,同时仍为代码提供嵌套类型的层次结构好处。 但是,就像Swift中的许多其他功能一样,事实证明,还有很多其他方法可以实现命名空间和嵌套类型。 扩展中的嵌套类型 一种选择是使用扩展来实现您的嵌套类型。 这使您可以更清楚地区分类型,同时在实现和调用站点中仍保留层次结构。 这是我们的类型的外观: 使用类型别名 您还可以在原始代码(不使用嵌套类型)中添加类型别名,以实现嵌套的类型化行为。 尽管这不能为您提供实现中相同的层次结构,但是它确实有助于减少冗长性,并且在调用站点上也提供与使用嵌套类型时相同的好处。 该选项如下所示: 结论 使用嵌套类型可以帮助您在代码中创建一个非常漂亮的结构和层次结构,以使您更加清楚各种类型之间的关系-在实现中和在调用站点中。 但是,根据您选择实施这些技术的方式,您可能还会面临其他挑战和副作用-因此,我认为根据情况选择技术真的很重要,这样才能最终赢得胜利。 你怎么看? 您更喜欢使用以上哪种技术来命名代码? 还是找到了另一个? 在Twitter @johnsundell上让我知道,以及任何问题或评论。 (哦,顺便说一句,从Swift 3.1开始,嵌套类型也可以在泛型内部使用!🎉…但有关更多信息,请参见即将发表的文章😉) 谢谢阅读! […]