最终测试标准考试和天体测试考试。 Nous allons维护者nous attarder sur la classegénéréeafin de vous expliquer la base。 导入XCTest 类AstronauteTests:XCTestCase { 覆盖func setUp(){ super.setUp() } 覆盖func tearDown(){ super.tearDown() } func testExample(){ } func testPerformanceExample(){ 自我衡量{ } } } 总理选择了重要的XCTest。 Comme vous vous en doutez,高级框架XCTest。 随员的套房: setUp() 。 Cétéméthodeestappeléeavant chaque invocation de chaqueméthodede testécritdans la classe。 将字体倒入测试字体,并替换字体; tearDown() 。 测试的最佳方法之一是等级考试; testExample() 。 […]
最初在 这里 发布在XCBlog上 在将iOS应用发布到Apple App Store之前,通常有一个针对内部受众的构建,即质量检查工程师,仅在特定配置的设备上运行的产品所有者。 在此过程中,您可能会听到诸如DEBUG或RELEASE配置之类的信息。 当我们使用Xcode创建新的iOS项目时,Apple为我们提供了两个项目级别的构建配置,即调试和发布。 调试配置通常用于开发和内部项目设置,例如将应用程序指向测试环境,然后使用发行版将应用程序提交到App Store。 但是,在许多情况下,可能会触发对更多内部设置或其他构建配置的需求。 作为一名优秀的iOS开发人员,您必须使用XCTest框架编写单元和UI测试。 通常,开发人员使用调试构建配置或运行单元和UI测试,但是为XCTest创建单独的构建配置会使测试更加独立,可靠和确定性。 在本文中,我们将看到如何为XCTest创建单独的构建配置。 构建配置 在进入创建新的构建配置之前,让我们看看什么是iOS中的构建配置以及为什么使用正确的配置构建应用很重要。 想象一下,我们已经在Xcode中创建了全新的iOS应用。 它将有两个构建配置,分别在iOS项目的“构建设置”中进行调试和发布。 在编译和构建iOS应用程序时,幕后发生了很多事情,例如编译,链接,复制包资源,运行构建脚本等。我们始终可以在xcodebuild日志中看到这些事情。 构建配置定义了我们希望如何在特定设置下构建应用程序,例如,当我们使用模拟器开发应用程序时,“调试信息格式”构建设置不需要生成dSYM文件,因此我们可以使用DWARF进行调试构建。 但是,我们需要发布版本的信息,以便我们可以将DWARF与dSYM文件设置一起使用。 如上图所示,您可以在Xcode的所有构建设置中看到这一点。 简而言之,构建配置定义了一种机制,该机制应如何使用不同的条件或设置构建应用。 在运行使用XCTest框架编写的单元或UI测试时,仍然可以使用调试配置,但是,添加其他配置可以使我们对测试过程进行大量控制。 XCTest的构建配置 现在,我们将添加另一个仅可用于XCTest单元或UITests的构建配置。 通常,单元测试需要较少的配置,因为我们可以直接在应用程序内部访问数据和API。 但是,UITests或XCUITests完全是黑盒子,因此我们需要在那里进行更多配置,以便通过UI测试的特定设置。 让我们从Xcode为示例iOS应用添加另一个构建配置开始。 在Xcode项目级别设置中,选择“信息”选项卡,我们将看到可用配置的列表以及添加更多配置的选项 注意,我们必须进行项目级别的配置才能获得此选项,而不是目标级别的配置。 单击配置中的+按钮。 我们可以通过复制调试或发布配置来添加其他配置。 通常,为了测试目的,我们需要重复调试配置,因此我们将其称为xctest在“ 配置”部分下,按+按钮。 选择“ 重复调试配置” 。 命名您的新配置xctest 现在,我们有了全新的构建配置,可用于单元测试或UI测试。 我们可以将用户定义的设置分配给新配置,以便我们可以设置测试特定的配置。 在项目构建设置中,向下滚动到构建设置的最底部,有一个名为User-Defined的部分。 这是将添加和设置配置变量的位置。 预处理器宏 现在,我们添加了新的构建配置,是时候更改预处理器宏了,以便我们可以设置源代码有条件地执行一些代码 现在,我们可以使用调用测试代码的主应用程序中的代码来唤醒此配置。 #if XCTEST //仅测试代码版本代码 #其他 //仅应用程式程式码 #万一 同样,我们可以使用相同的方法来更改不同的环境,例如阶段,测试,但是某些文章已经介绍了该方法。 一些受欢迎的文章是 Xcode项目中的多个构建配置 […]
留下笔记的做法很重要。 对项目进行注释可以帮助您和您的同事跟踪已完成的工作以及尚需完成的工作。 Xcode中内置了三个关键字(TODO,FIXME和MARK),以帮助跟踪项目中需要完成的许多工作。 此外,在脚本编写的帮助下,您可以扩展这些关键字的功能,以确保您的笔记不会被忽略。 在家玩,看看它是如何工作的! 关键词 在Xcode中,打开一个.swift文件。 在代码编辑器上方,您会看到一个状态栏,其中显示了swift文件的位置以及当前在文件中的位置。 单击最后一项将显示一个下拉菜单,列出属性,方法或文件中发生的任何其他情况。 这有助于使用许多代码行和许多功能读取和浏览文件。 Xcode还允许您将自己的项目放置在此列表中,以便其他人,甚至是漫长的一周后甚至您自己,也可以对文件进行快速诊断,以查看是否需要完成或需要修复。 例如: // TODO:添加方法来查找大海捞针 …将产生此结果,并带有项目符号列表图标: 这个: // FIXME:删除对jiltedExLover的所有引用 …将产生此消息,并带有绷带图标: 另一个技巧是,在任何音符上的冒号后面加一个破折号(-),将在下拉列表中创建一个换行符。 所以这: // MARK:—不同的部分 …将产生此消息,并在其上换行: 得到它了? 大! 带注释生成警告和错误 现在也许您在想,这有什么意义? 我是否还不必仔细研究程序,逐个文件,单击下拉菜单,尝试找到该TODO标签? 如果项目有数十个文件怎么办? 我的TODO和FIXME标签不会陷入混乱并被遗忘吗? 如果只有TODO标签没有答案,那么只有一种方法可以使Xcode发出警告! 你猜怎么了? 有! 通过使用一些bash,Xcode会针对任何给定的注释标签自动向您抛出警告或错误。 转到Xcode项目文件上的构建阶段。 单击trop右边的小加号,然后选择Run New Script Phase 。 这里的想法是,当Xcode构建项目时,您将在构建过程中增加另一步。 如果解开运行脚本项的箭头,则会看到一个黑框,其中包含Xcode将在每个版本上运行的脚本。 现在,将其复制并粘贴到该框中:
AlertViews是在iOS中向用户显示消息的常用方法。 该视图使用户可以了解关键信息(电池电量低)或做出有关操作过程的决定(确定要删除此项目吗?) 对于这种用例,默认的UIAlertController(记住,不推荐使用UIAlertView!)是完美的,但是如果我需要一个更复杂的UI(包括滑块,Switched Segmented Control或从头开始设计的UI)怎么办? 我发现实现此目标的唯一方法是创建自定义UIAlertView。 如果您处在这种情况下,您可能会想:让我们对UIAlertController类进行子类化,并添加新功能和自定义内容! 然后,检查API参考并找到以下内容: 子类化 UIAlertController类旨在按UIAlertController使用,不支持子类化。 此类的视图层次结构是私有的,不能修改。 那我们现在怎么办? 🤔答案是:子类化UIViewController并将其行为更改为类似于UIAlertView的外观! 让我们看看如何。 我创建了一个简单的应用程序,以显示标准UIAlertView和自定义应用程序之间的区别。 用户界面 首先,设计AlertView的UI。 就我而言,我使用的是Storyboard,它看起来像这样。 我还添加了约束以使其响应。 控制器 然后,我们创建一个将继承UIViewController的类。 此类将处理所有AlertView的逻辑和用户操作:点按一个按钮,在UITextField上编写,为视图设置动画,将其关闭等等。 实现很简单,但是让我详细解释一些部分: alertTextField.becomeFirstResponder() 此方法默认请求文本字段焦点并打开键盘。 alertTextField.resignFirstResponder() 另一方面,此按钮关闭键盘并删除文本字段焦点。 view.layoutIfNeeded() 使用此方法可以在绘制之前强制子视图的布局。 如果您需要绘制按钮边框(在这种情况下),这很有用,因为它可以防止UI毛刺(如绘制两个边框):更改约束前后。 提示 :在按钮上画边框我发现Github上Isuru Nanayakkara的一个精要思想是使用Swift扩展,不要忘了🌟! 链接 self.view.backgroundColor = UIColor.black.withAlphaComponent(0.4) 将背景颜色设置为透明的黑色,以便使打开CustomAlertView的ViewController在背景上可见。 代表 如您所见,委托模式用于将我们的CustomAlertView与显示它的类进行通信。 实现方式是使用协议。 实例化 最后一件事是实例化并显示我们的CustomAlertView。 用委托协议扩展ViewController,以对CustomAlertView操作(在此示例中为取消和确定按钮)做出反应,实例化CustomAlertView,设置委托并呈现,完成! 其余代码用于正确设置CustomAlertView的动画,并像UIAlertController一样工作。 那是所有人! 它是一个非常简单的自定义AlertView,但是考虑到很少的事情,您可以根据需要/需要对其进行自定义。 与往常一样,欢迎您提供反馈,感谢您的阅读和❤️(如果您觉得有用)! 码 https://github.com/DrankoLQ/CustomAlertView 参考文献 [1] https://developer.apple.com/reference/uikit/uialertview [2] https://developer.apple.com/library/content/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html […]
苹果公司的大多数框架都具有面向对象的体系结构。 在开始研究iOS / MacOS开发之前,您应该首先了解面向对象的编程和设计模式。 在本文中,我们将介绍基本概念和设计模式,以帮助您开始进行应用程序开发。 总览 面向对象编程(OOP)是一种编程范式,代表了具有数据字段(描述对象的属性)和相关方法(称为方法)的“对象”的概念。 对象通常是类的实例,用于彼此交互以设计应用程序和计算机程序。 面向对象编程包含3个关键方面: 封装意味着对象将其状态信息保密。 其他对象不是直接处理对象的数据,而是以消息的形式向对象发送请求,对象可能通过更改其内部状态来响应其中的一些请求。 多态性意味着不同类别的对象可以互换使用。 这一点特别重要,因为它允许您以后以不必要的方式挂钩类,而不必事先预料这些类是何时设计的。 继承意味着一类的对象可以从另一类(基类或父类)派生其行为的一部分。 某些面向对象的语言(例如,C ++,但不支持Swift)允许多重继承,其中一类对象可以从多个独立的基类派生其部分或全部行为。 类和对象 在面向对象的编程中,类是用于创建对象,提供状态(成员变量)和行为实现(成员函数,方法)的初始值的可扩展程序代码模板。 换句话说,类就像一个蓝图,它定义了类型的数据和行为。 类按钮{ } 上面的定义创建一个名为Button的空类。 它唯一能做的就是创建新的Button对象: var button = Button() 在上面的示例中, button是Button类的实例。 物产 类和实例可以具有名为属性的关联值。 广场广场{ var length :Int = 1 } Square类的length属性的默认值为1 。 为了创建length不同于1正方形,我们需要编写一个自定义初始化程序。 广场广场{ var length :Int = 1 初始化 ( 长度 :整数){ self.length =长度 } } […]
在本教程的第一部分中,我总体上讨论了协调器的方法,并展示了一些与实现有关的常见示例。 为了与本文保持一致,请阅读上一部分。 在这一部分中,我想介绍一些使用协调器的极端情况。 我想最有趣的部分是: AppDelegate配置 管理启动选项 深度链接和协调员推送通知处理 我将逐步说明解决方案并进行解释。 如何使用主应用程序协调器配置AppDelegate? 由于所有导航逻辑都移至AppCoordinator,因此AppDelegate变得非常简单。 因此,您需要做的是创建一个协调器,注入rootController并调用start()。 我们希望通过展示一个教程,展示一个身份验证流程,向他们介绍新功能或仅显示主屏幕来向用户介绍我们的应用程序。 我们应该谨慎处理这种行为。 假设我们有3种不同的情况: 用户应查看入门教程(我们将显示入门屏幕) 用户应登录(我们显示登录屏幕) 用户已完成之前的两个步骤,仅看到主屏幕 为了轻松处理所有这些情况,我们创建了一个枚举作为协调者的助手。 该枚举应检查所有标志,并返回协调器应遵循的正确方案。 我将其命名为实体讲师,因为它指示协调员接下来要做什么。 怎么处理呢? 正如您在上一部分中所记得的,我告诉您有关BaseCoordinator的信息 ,其中包含子协调器数组。 所有协调员都继承它。 这意味着我们可以循环所有孩子并执行动作。 为此,我们只需添加一种方法即可处理DeepLink逻辑本身,也可以循环处理子代以找到可以处理它的方法。 它将像一棵树。 我们可以创建特定的协议来实现此目标。 让我们更新协调器协议: 现在,我们将两个带有空主体的方法添加到BaseCoordinator中,以使其保持可选状态。 孩子们可以继承这些方法之一,也可以两种都继承。 在某些情况下,可以使用不带选项的start来运行默认行为,但是如果继续进行深层链接方案,则应添加有关演示案例的信息。 如何实现呢? 更好的方法是在项目中添加一些实体,其中包含所有深层链接快捷方式,并创建可以使用start()方法发送的对象。 你想念枚举吗? 让我们添加一个新的! 它将是DeepLinkOption: 好处是,协调器中所有的DeepLink方法都将像切换为枚举一样。 是的,与上一个示例中的Instructor相同,您是正确的。 我们可以根据需要添加一些其他的build方法(带有…): 在此迭代之后,如果我们返回AppDelegate并对其进行一些更新,它将看起来像这样: 好了,看起来不错吗?🤔然后您将收到一个推送通知或深层链接,您只需构建您的DeepLink并通过AppCoordinator进行此操作即可。 结论 在我们尝试在代码中实现的每个新解决方案中,我们都面临着很多极端的情况,并且还面临着一些不太漂亮的解决方案。 它不应该像炒作那样驱动开发,我们只需要逐步改进所有棘手的部分即可。 如果您有任何疑问或新的特定问题,请随时给我写信。 并检查整个实现的Github回购。
MVC是一种将代码分为三个不同部分的体系结构模式。 模型视图控制器。 这是一种流行的体系结构,因为它将用户界面代码与逻辑代码分开。 因此,可以更轻松地在错误发生时进行更新,扩展和查找错误。 三个不同部分的简要概述。 模型 -模型是处理大多数逻辑和数据过程的地方。 视图 -您的UI元素将位于此类内。 由于它不包含任何逻辑,因此也称为伪类。 控制器 -这是模型和视图之间进行交互的地方。 控制器管理这些交集。 在iOS开发中,将所有代码编写在ViewController可能是诱人的; 实际上,如果您是一个自学成才的开发人员,您可能会实践过。 在本文中,我将演示如何在应用程序的简单注册功能上执行此操作。 我喜欢以编程方式执行此操作。 因此,如果您关注以下内容,请删除Storyboard文件,并确保在项目设置中将“ Main Interface选择保留为空白,并在AppDelegate.swift初始化rootViewController 设定 我将创建三个文件: Register RegisterView和MainController 。 我们的Register类将充当我们的模型,其中将包含我们的所有逻辑。 RegisterView将充当我们的View,并将包含我们的所有用户界面元素,并且MainController将托管RegisterView 。 注册—模型 在本课程中,我们将使用用户名和密码。 我们想对密码的格式化方式添加一些限制。 首先,我希望密码长度至少为6个字符,并且在继续操作之前,密码和确认密码必须相同。 我们没有使用数据库来保存任何信息。 首先,让我们设置初始化程序,该初始化程序将使用用户名,密码和确认密码。 在那之后,我想要三个功能。 validatePasswordLength() validatePasswordAndConfirmPassword() completeRegistration() validatePasswordLength()少于5个字符时将引发错误。 如果validatePasswordAndConfirmPassword()不相等,也会抛出错误。 completeRegistration()函数将在try块中同时调用validatePasswordLength()和validatePasswordAndConfirmPassword()函数。 因为我们正在使用try块进行错误处理,所以我们需要一个enum不同的错误。 枚举验证:错误{ 案例密码太短 案例密码 } 完成后 您的代码应如下所示: RegisterView —查看 如前所述,此类将包含我们的UI元素。 对于此注册页面,我们想向用户询问用户名和密码。 我们还希望另一个密码字段来确认密码。 因此,我们总共需要三个UITextField。 我们还需要一个按钮来执行注册操作。 […]
在iOS上使用机器人图案 我最近在iOSDevUK上发表演讲,概述了我们如何在Capital One测试我们的旗舰iOS应用程序。 我被问到的最常见的跟进问题是关于使用机器人图案 。 我在幻灯片中简要介绍了机器人模式,但显然这是其他人有兴趣了解的更多信息 机器人图案是由Square的Jake Wharton设计的,用于在Kotlin进行测试。 结果,许多可用信息都集中在Kotlin和Espresso测试上。 在线使用iOS的机器人模式的知识很少。 但是,Capital One UK Mobile团队选择使用机器人图案,因为这意味着我们的Android和iOS测试之间采用一致的方法。 这是iOS应用程式的运作方式。 为什么要使用机器人图案 编写XCUI测试时,使用机器人模式的三个主要原因。 易于理解 我们来自Calabash的XCUITests,我们的测试是用Cucumber编写的。 黄瓜接近自然语言。 这意味着您可以快速,轻松地阅读和理解所测试的内容,而无需确切了解测试的工作方式。 用本机代码编写测试,知道要测试的内容和没有测试的内容已经有了一条学习曲线。 重用代码 通过将我们的测试分为多个步骤,每个实现步骤都可以根据需要重复使用多次。 如果您的应用在执行任何操作之前具有登录屏幕,则每个测试的设置很多。 取而代之的是,您只需每次调用login(),然后继续进行测试的更具体区域。 如果确实需要做一些不同的事情,可以将参数传递给函数。 隔离实施细节 无论您的应用程序使用哪种架构,您的目标都是单一责任原则。 坚持这样做可以使您以新的实现将对象切换为新对象,同时仍保持对象的核心功能。 这使得代码更易于维护,测试和改进。 那么,为什么您的测试应该有所不同? 杰克·沃顿(Jake Wharton)将其描述为将“内容”与“方法”分开。 您的测试仅应关注“什么”,这意味着,如果您的视图改变了事物在屏幕上的显示或发生方式,则无需更改整个测试套件。 编写一个XCUITest 假设我们正在为Apple的内置Messages应用程序编写UI测试。 如果您从暂停状态加载应用程序,则会在屏幕顶部看到一个大标题“消息”和一个用于创建新消息的按钮。 假设我们正在测试点击此按钮,然后使用iMessage向用户发送新消息。 我们的XCUITest可能看起来像这样: func test_sendNewiMessage(){ 让app = XCUIApplication() app.launch() app.buttons [“ new_message”]。tap() 让newMessage = app.staticTexts [“新消息”] let谓词= NSPredicate(格式:“存在== […]
名字叫什么? 如果编程语言带有命名功能,则可以肯定地以某种方式命名了它。 可以肯定的是,语言设计师的命名目的是有目的的,因此,如果您能找到一个至关重要的“他们为什么要这样命名?”的问题,那么您可能就更了解该功能或概念了。 为什么要“关闭”? 现在的挑战是:真正找出“为什么?”问题的答案。 Swift是在公开场合开发的,通常它使人们好奇地洞悉诸如命名决策之类的事物。 但是,Swift中的闭包比Swift开源的时间更长。 既然如此,在关于为何将闭包命名为“闭包”的对话中,我真的找不到很多。 闭包语言还存在其他语言,因此也许Swift只是借用了这个名字。 但这并不能帮助我们回答将闭包命名为“闭包”的底线原因。 打开“封盖”的包装(感谢thesaurus.com!) 所以……我开始冒险一词,以帮助阐明“封闭”一词的含义。 知道“闭包是可以包含并在您的代码中使用的自包含功能块”,这是一回事。(Apple Developer Docs)但要认真地讲-为什么不直接将它们称为“函数”? 如果可以的话,让我们打开这个词。 我将“ closure”放入thesaurus.com,我认为在编程语言中最能阐明“ closure”一词的同义词包括: 从这个意义上说,“封闭”似乎传达了将某物保持在…… 封闭状态的想法。 好吧,封闭的内容是什么? 好问题! 简短的答案? 变量 。 不可避免地,如果仔细研究互联网的含义,就会遇到与上面引用的Apple类似的定义。 在我发现的各种定义中,通常会出现“捕获变量 ”或“结束变量 ”之类的短语。 这些短语似乎总是使水变得浑浊(无论如何对我而言)。 尚不清楚“捕获变量”或“结束变量”是什么意思。 直到我看到同义词,“ plug”,“ seal”,“ cork”。 然后它点击了… 想象力的例子 我希望您在Swift中使用某个功能,并且希望您将其想象为一个空游泳池。 进入您的脑海了吗? 游泳池。 空(暂时)。 在运行时,您的Swift程序会愉快地执行。 然后,在程序中有片刻会调用函数。 它开始执行,突然,水涌入池中。 一打跳水硬币也被扔入水中! 硬币代表函数创建以执行其工作的局部变量和常量。 您的函数一直执行到return关键字,并在函数返回的确切时刻开始排水。在几毫秒内 ,用巨大的力将所有水从池中吸出。 您认为池中的所有硬币会发生什么? 对于此示例,我们只说答案是“他们会费尽心机”。 这将与函数返回时在函数中声明的变量和常量通常发生的情况很好地关联。 每当函数返回时,都会从内存中清除在函数内部创建的所有变量和常量……如果可以的话,请尽一切努力。 Unleeeees… 如果在某个时候池中仍然有水,您能够潜入水中,拿走几枚硬币并将其装瓶怎么办? […]
什么是远程推送通知? 好吧,如果您问苹果公司的人,他们可能会将您定向到他们网站上的以下页面,该页面描述了以下通知: Apple Push Notification服务 (APN)是远程通知功能的核心。 对于应用程序开发人员而言,它是一项强大,安全且高效的服务,可以将信息传播到iOS(以及间接地通过watchOS),tvOS和macOS设备。 我只是说“这是在提醒用户有关其在手机上安装了您的应用程序的事实”,这听起来有些怪异。 我在那里也看到:“更好地利用这个强大的功能,伙计/女士!”。 这正是我们在本指南中要做的! 推送通知可以做什么? 我将把“推送通知”称为“推送通知”,“ PN”,“ APN”,“通知”,“远程推送通知”,“远程通知”,我将始终牢记相同的概念。 这几天您可以使用APN进行以下操作: 显示讯息 播放声音 在您的应用上设置徽章图标 提供用户在打开或不打开应用程序时可以执行的操作 显示图像或其他类型的媒体 保持沉默,但要求应用程序在后台执行一些操作 方式可能太多,但全部有用。 尽管如此,随着文章标题的发展,我将专注于显示消息,媒体和动作 。 没人喜欢知道吗,对吧? 但是,在看到任何APN魔术发生之前,需要完成一些配置! 这将帮助我们保护珍贵的远程通知免遭可能的入侵者的侵害-定义确实“ 健壮,安全且高效 ” ,现在听起来确实很吓人,但您不用担心! APNS配置开始之前需要准备的东西 真正的iOS设备。 模拟器无法接收通知。 我将在装有iOS 11的iPhone 8 Plus上进行测试。 Apple开发人员计划成员资格 -是的,您需要最终支付自己一直避免的费用。 将通知有效负载发送到设备的一种方法是一种简便的安装和使用Pusher应用程序的好方法。 APNS配置和初步分步实施 步骤1,项目设置:与这些天您可能正在学习的有关iOS应用程序的其他任何事情一样,这一切都始于创建项目。 是的,我的名字叫独角兽。 这个想法很简单-当同一个独角兽用户看到独角兽并拍照时,每个用户都会在通知中收到该图片。 第2步,启用APN:在Xcode中,转到“ 目标” ,在应用名称下,选择“ 功能”,然后在列表中找到“ 推送通知 ” ,然后切换 到ON : 步骤3,获取APNs证书:转到您的Apple Dev […]