Tag: xcode

具有Fastlane和Ansible的iOS连续交付-第2部分

这是我在Photobox Group处理iOS应用程序持续部署的经验的第二部分。 在上一篇文章中,我们看到了我们如何使用Fastlane从持续集成服务器中连续部署iOS应用。 连续交付过程中最棘手的障碍之一是“在机器上工作”现象。 几乎每个工程师都至少遇到一次此问题。 我们还遇到了“在我的机器上工作”一文中提到的相同问题。 挑战性 在维护连续集成服务器的同时,我们遇到了以下挑战。 使用所有与iOS相关的软件手动设置CI服务器计算机需要花费几天的工程师。 在CI服务器上产生的结果在本地开发人员机器上无法再现。 我们的构建配置步骤与TeamCity持续集成服务器中的GUI配置紧密结合。 开发人员机器和CI服务器上的软件版本不同 我们失去了对CI服务器的信任,最终花费大量时间寻找问题的根本原因。 在此阶段,我们确实需要一些配置管理工具,该工具可让我们使用相同的配置来设置所有计算机,并应能够从头开始进行配置。 我们需要我们的iOS基础架构由代码(也称为基础架构)驱动。 我们正在为达尔文寻找类似Docker的产品。 有很多选择,例如Chef,Puppet等,但我们碰到了Ansible,因为它是用于基础结构自动化的简单但功能强大的工具,而无需了解其他任何语言(如Ruby)。 在这篇文章中,我们将看到如何使用Ansible来配置CI服务器。 使用Ansible设置iOS CI 以前,我们曾经使用交付iOS应用程序所需的所有软件来手动设置CI或持续集成服务器。 工程师必须手动下载并安装带有其他组件的Xcode,安装所需的自制软件包,设置RVM和rubygems。 它还涉及将构建服务器设置为TeamCity Build Agent。 要花费大约一两天的时间才能使构建机器处于工作状态。 这种方法既费时,又很难管理构建服务器上安装的软件版本。 我们使用Ansible设法使上述几乎所有内容自动化。 能够在需要时重置,重新构建iOS Continuous Integration Server环境非常重要。 Apple不断发布Xcode的新版本或Beta版本以及其他开发人员工具,因此我们应该能够快速设置和使用这些功能。 可编程基础结构或作为代码的基础结构是持续交付的关键,因此我们需要一个脚本来自动设置这些内容,而无需人工干预。 Ansible允许我们编写代码以管理部署以及基础架构的自动配置。 Ansible任务和剧本是简单的YAML文件,因此无需学习其他编程语言(如Ruby)来编写iOS基础结构脚本。 iOS持续集成服务器的配置涉及以下任务 预配置Xcode和Xcode命令行工具的安装 调配iOS开发所需的自制程序包 使用RVM设置红宝石环境 设置macOS默认值 为TeamCity服务器配置TeamCity代理 以上每个步骤都有Ansible任务,让我们更深入地研究这些任务 Ansible Xcode任务 包括Xcode在内的大多数Apple软件都是专有软件。 您需要Apple开发人员帐户才能下载安装这些软件。 设置Xcode的安装是一项重大挑战。 我们已决定下载特定Xcode版本的Xcode .xip文件,并将其托管在公司托管的SAMBA服务器上。 我们可以将Xcode .xip挂载到任何构建服务器机器上以安装Xcode。 然后,我们可以提供其他Xcode相关任务,例如接受协议,安装命令行工具,使用Ansible任务安装其他组件。 示例Ansible任务如下所示: — […]

UIKit:具有卡片样式单元格的TableView

今天,我们将学习如何将每个单元格作为Card(圆角和阴影)制作一个UITableView。 这是最终结果: 好吧,让我们用一个原型单元设置一个表格视图。 为了获得类似于卡片的单元格,我们需要在单元格的“ 内容视图”中使用一个以上的视图,以充当所有单元格内容的容器,并在其中应用圆角和阴影。 因此,视图层次结构应如下所示: 如您所见,我在原型单元cardCell的Content View下添加了一个名为Container View的视图 。 然后,我创建UITableViewCell的子类,其中包含单元格内容的出口,在其中执行以下操作: @IBOutlet 弱var containerView:UIView! { didSet { //使其像卡片一样 containerView.layer.cornerRadius = 10 containerView.layer.shadowOpacity = 1 containerView.layer.shadowRadius = 2 containerView.layer.shadowColor = UIColor(named:“ Orange”)?. cgColor containerView.layer.shadowOffset = CGSize(宽度:3,高度:3) containerView.backgroundColor = UIColor(名称:“红色”) } } 好了,谁看过我以前的文章UIKit:Rounded Views和UIKit:View Shadow,这些代码应该很熟悉,无论如何,此代码所做的就是将容器视图的角四舍五入并设置其阴影。 哇,这很简单吗?! 让我们运行代码并查看结果…… 最佳意大利队队长布冯的卡片,即尤文图斯😛,具有与卡片颜色相同的图像视图(队长带),并且不会被裁剪,从而使卡片的右上角看起来像不四舍五入。 让我们使用containerView.layer.masksToBounds = true使图像视图固定在卡片范围内。 再次运行代码,看看是否能解决问题: Mo! 图像被剪裁,阴影也被剪裁。 好了,通过Internet浏览,似乎唯一可行的解​​决方案是在单元格视图层次结构中拥有另一个视图,在该视图上将阴影应用于裁剪其内容的容器视图下,如下所示: 所以这是问题所在:将图层的属性masksToBounds为true时,其所有子图层以及拥有该图层的视图的所有子视图(我认为都是相同的,因为该视图只是图层的代表)会被裁剪,因此解决方案是将阴影放在最上面的视图上 , […]

了解DispatchQueues

最初发布于 swiftrocks.com 。 这些“ DispatchQueues”到底是什么? 为什么必须使用它将UI代码发送到主线程? 如果我什么也不做,它显然仍然有效。 这些“服务质量”队列有什么意义? 我将.main用于所有内容,并且从未遇到问题。 如果调用DispatchQueue.main.sync,为什么会崩溃? 有什么意义呢? 到底这是什么主线程? 如果您要开发iOS应用程序超过几个星期,那么您之前可能已经处理过并发代码。 如果您没有操作系统的知识,那么您可能已经问过自己其中一个问题。 一般而言,多线程是很难完全理解的事情,但是了解CPU如何处理并发性是编写可以完成您期望的工作的优质快速代码的关键。 否则,您可能正在滥用用户的CPU,但认为一切都很好,因为它们太快了,您无法注意到问题所在。 在我们能够回答这些问题之前,我们需要退后一步,了解事情在幕后的运作方式。 流程的定义非常简单:它是一个正在运行的程序。 您的应用是一个过程,Slack是一个过程,Safari是一个过程,依此类推。 它包含指令列表(您的汇编格式代码),并位于磁盘上,直到用户希望运行它为止。 然后,操作系统将把该进程加载到内存中,启动一个指令指针 ,告诉我们当前正在执行该程序的哪条指令,然后让CPU顺序执行其指令,直到结束为止,从而终止该进程。 单线程进程的地址空间 |————————-|- | 说明| |——————————– | 全球数据 |——————————– | 分配的数据(引用类型)| |——————————– | 什么都没有(堆栈和malloc的数据向此处增长)| |——————————– | 堆栈(值类型(如果可能),参数,返回)| |——————————– 每个进程都有自己专用的物理内存部分。 他们不与其他进程共享这些地址。 不行 您正在经历的是一种幻想,它是由CPU所具有的荒谬速度造成的。 一个CPU不能同时做两件事。 对于具有多个内核的CPU,情况略有不同,但是为简单起见,我们假设只有一个CPU:发生的事情是它在Safari中执行某项,然后在Spotify中执行某项,然后在iOS中执行某项,然后在Safari中再次执行某项,依此类推上。 操作系统将把CPU为特定进程所做的任何事情保存在内存中(以寄存器和指针的形式),决定下一个要运行的进程,检索该进程正在做什么,让CPU运行该进程。一会儿,然后重复。 这称为上下文切换 ,它非常非常快地发生,给人的印象是它实际上可以一次运行多个操作。 (在具有多个内核的CPU中,可以将工作划分到各个内核之间,实际上一次执行多个操作。但是,在使用所有内核时,同样的原理也适用。) 操作系统决定下一步应该运行什么的确切方法相当复杂(如果您有兴趣,请阅读文章结尾的书),但是您应该知道,可以手动决定什么是“优先级” ”在我们的应用中。 (iOS的“服务质量”现在是否开始有意义?) 多线程程序具有一个以上的执行点,而不是从main()函数开始并在下面几行结束的某个exit()处结束的单线程进程的经典概念,执行)。 也许另一种思考方式是,每个线程都非常像一个单独的进程,只是有一个区别:它们共享相同的地址空间,因此可以访问相同的数据。 多线程进程的地址空间 […]

模拟器的快速通道

询问任何经验丰富的iOS开发人员,他们会告诉您应用签名是散发大多数屁味的部分。 它不会杀死您,您可以度过难关,但是却充满了不便,愤怒和一点神秘感。 因此,Apple一直在努力实现流程自动化,因此对于产品开发人员而言,只需勾选一个复选框即可。 当无法选中该框时,还有其他工具可以帮助减轻痛苦。 因为这只是最糟糕的情况,所以我们懒惰的工程师已经制作了足够的工具,可以容忍完整的应用程序签名。 但是中间的步骤呢? 仅仅因为我们可以从纽约飞往洛杉矶,就不能更轻松地开车前往费城。 模拟器 人们不时喜欢在发送代码之前对其进行测试。 这可能是最佳做法,我不知道,我是工程师,所以提起诉讼。 有些人甚至喜欢自动化他们的测试。 如果您想在iOS上自动化测试,则意味着您将在模拟器中进行测试。 现在,您将如何在要分发到实际设备的构建中执行此操作? 您知道吗,我们早先谈论过的那些花哨的建筑? 这些将不适用于模拟器。 不,现在您需要一个新的过程。 这可能看起来很神秘,但实际上只是在做您之前所做的事情,但是大约停止了四分之一。 实际上,每次您运行针对模拟器设备的应用程序的调试版本时,Xcode都会创建有效的模拟器版本。 运行针对模拟器的构建后,您可以在派生数据文件夹中找到模拟器构建本身。 外观类似于: ~/Library/Developer/Xcode/DerivedData/{App GUID}/Build/Products/Debug-iphonesimulator 。 但这不好。 什么,您将在每次测试时调试您的应用程序,拔出模拟器应用程序进行像非利士汀一样的测试吗? 不,你比那更好。 您应该得到比这更好的东西。 您应该得到自动化的东西。 也许还有一个饼干。 Fastlane自动构建仿真器 我会说TLDR,但为时已晚。 这是使用Fastlane创建模拟器版本的方法。 xcodebuild(workspace:“#{workspace}”, 方案:“#{scheme}”, xcargs:“-configuration#{configuration} -sdk’iphonesimulator11.3′-destination’generic / platform = iOS Simulator’” )zip(路径:“ ./ simulator / Build / Products / Debug-iphonesimulator /#{app-name}”, output_path:“ ./ build /#{build-name} […]

在Mac上的Xcode中创建的SNIPPETS在哪里

这个故事最初发布在 apps-top.com上 Xcode代码段是可以帮助您进行编程例程的代码段或代码模板。 通常,当您更新Xcode时,代码片段没有任何反应。 但是有时候,在购买了新的Mac,重新安装Xcode或更新OS之后,您可能很难找到代码片段。 在迁移到新版本的Xcode或Mac OS Update之前,最好将代码段转移到安全的地方。 在Mac上查找Xcode代码段的3个简单步骤是: 在Mac上打开Finder 按Go>转到文件夹 类型:〜/ Library / Developer / Xcode / UserData / CodeSnippets

Xcode LaunchImage大小

Iphone Xs Max(Portraint IOS 12+)=> 1242px×2688px Iphone XR(Portraint IOS 12+)=> 828px×1792px Iphone Xs Max(Landspace IOS 12+)=> 2688px×1242px Iphone XR(Landspace IOS 12+)=> 1792px×828px Iphone X / Iphone Xs(Portraint IOS 11+)=> 1125px×2436px Iphone X / Iphone Xs(Landspace IOS 11+)=> 2436px×1125px 视网膜高清5.5英寸(Iphone Portraint IOS 8+)=> 1242px×2208px 视网膜高清4.7英寸(Iphone Portraint IOS 8+)=> 750px×1334px Retina HD 5.5”(Landspace Portraint IOS 8+)=> 2208px×1242px […]

创建未签名的Xcarchive(Xcode)

如果您是开发人员,并且没有权限提交到iTunesConnect,但是您的团队代理希望将您的应用程序提交到iTunesConnect,则需要创建一个未签名的Xcarchive文件并发送给您的团队代理。 因此,团队代理可以签署应用程序并提交到iTunesConnect。 让我们创建未签名的Xcarchive; 步骤01:设置“代码签名身份” =“不使用代码签名” ·选择Targets(”)-> Build Settings,然后找到’Signing’部分。 ·设置“代码签名身份” =“没有代码签名” Setp 02: 设置捆绑包标识符=’com.testCompany.prjectname’ 设置版本= 1.0 设置构建= 5 删除“自动管理唱歌”标志。 第三步: 打开终端,然后转到项目根文件夹。 然后运行以下命令。 步骤4: 成功完成上述命令后,它将在“ buildArchive”文件夹中创建一个新的“ .xcarchive”文件(在您的项目文件夹中创建“ buildArchive”文件夹) 压缩“ .xcarchive”文件并将其发送给您的团队代理。

加快Xcode中Swift编译和编译时间的8条技巧

Swift是一种高效的语言,但是如果您不小心的话,可能会遇到难以理解的构建和编译时间 Swift构建和编译时间可能要花费大量时间,这有很多不同的原因。 最突出和常见的原因是由于类型推断。 本质上,由于昂贵的类型检查过程,Swift编译器在解析和编译简单的Dictionary&Array文字时特别慢。 不幸的是,有时候不可避免地会出现缓慢的编译时间,但是好消息是,您可以利用某些工具和设置更改来加快Swift的编译和构建时间。 1)在Xcode中显示构建时间 首先,我们需要衡量您的编译时间。 重要的是要进行衡量,以确保本文中建议的更改实际上具有预期的影响。 您可以直接在Xcode的用户界面中启用计时器。 默认情况下,此计时器不可见,但是如果您在命令行中运行以下命令,则每次构建应用程序时都会显示时间。 defaults write com.apple.dt.Xcode ShowBuildOperationDuration -bool YES 启用计时器后,您将在Xcode的构建状态栏中看到编译应用所需的时间。 每次您要测量应用程序的构建时间时,建议您清理项目(包括构建文件夹⌘+⌥+K )并删除应用程序的派生数据。 您可以从命令行使用以下命令进行操作。 rm -rf ~/Library/Developer/Xcode/DerivedData 2)确定编译缓慢的代码 Xcode具有内置功能,可让您识别导致更长编译时间的函数和表达式。 您可以指定编译时间限制,并在代码库中标识超出此限制的区域。 打开项目的构建设置,然后将以下标志添加到“ Other Swift Flags 。 -Xfrontend -warn-long-function-bodies=100 -Xfrontend -warn-long-expression-type-checking=100 100整数表示您在函数和表达式上放置的编译时间限制。 以毫秒为单位。 编译代码时,任何超过100ms的函数或表达式都将被标记为警告。 这为您提供了重构代码并减少编译时间的机会。 3)仅构建活动架构 选择了Debug配置后,您的项目应仅构建活动架构。 此设置默认情况下应处于活动状态,但值得以防万一。 导航到Build Active Architecture Only在项目的构建设置中Build Active Architecture Only 。 确保将Debug设置为Yes并将release设置为No 4)优化dSYM生成 您可以使用dSYM文件来了解崩溃报告。 当您没有连接调试器时,这特别有用。 但是,它们需要花费一些时间来生产,因此只有在没有附加Xcode调试器的情况下才生产它们才有意义。 […]

IOS中的自动布局

自动布局是基于约束的布局系统。 它允许开发人员创建一个自适应UI,以对屏幕尺寸和设备方向的变化做出适当的响应。 在Interface-Builder中,我们使用Pins,Aligns,Resolvers和Stack…,它们位于屏幕底部的源代码编辑器下方。 堆 对齐 销 解析器 销钉-→选择场景中的一个对象,然后描述离它最近的邻居对象有多远。 您可以在图钉按钮上找到所有图钉约束。在提供约束时,您可以从下拉菜单中更改相对视图。 对齐—→选择两个视图/对象并设置它们之间的关系。 通常对齐到公共边缘或中心 解析器—→如果我们不立即更新框架,则可以在解析器中更新它们。 这两个部分看起来相似,但顶部仅适用于选定的视图,底部适用于所有视图。 堆栈—将视图嵌入堆栈视图。 自Xcode 7以来,堆栈视图是一项新功能。 约束错误 所有约束错误均以警告开头,但在运行时它们将成为致命错误。 我们必须解决这些错误,然后再致死。 3种错误 → 错放的视图 具有正确的约束条件,但在运行时位置不正确。 如果选中该选项,则会显示绿色虚线/矩形,以显示正确的位置。这些线上的数字显示正确位置的距离/距离。要解决此问题,请使用“ Pin&Align”菜单中的“ Update Frames”。 2.缺少约束和 也称为“模糊约束”。 所有视图都需要足够的信息来确定视图的位置和大小。 如果缺少约束,则框架颜色将变为“红色”。要解决此问题,请在特定视图中添加“缺少约束”。 3.冲突约束 这是最困难的:约束太多。 显示为红色。 解决方法:删除约束,直到仅剩一个约束为止。

XCode UI测试指南

苹果公司的UITest套件使一些开发人员感到兴奋,而其他人则对失去的功能感到失望。 UITest的工作方式不同于开发人员所依赖的功能测试解决方案,例如KIF。 UITest无需授予您对元素本身的访问权限,而是提供了具有最少交互参数的代理元素的访问权限。 学会将单元测试和基于单元的ui测试与功能测试区分开可能是一件令人沮丧的经历,尤其是在使用仍需要解决的新框架时。 我希望以下指南可以帮助开发人员对使用UITest时所需的方法有所了解。 *本文写于2015年12月中。那时,UITest仍遇到一些错误。 很多次我的测试都失败了,第二天没有任何变化就会通过。 建议您经常清理和删除派生数据,以及不时重新启动XCode。 您可能还必须找到一些创造性的解决方法。 更多信息请参见下面的“ Gotchas”部分。 在查看文档集时,请记住,UITest同时用于iOS和OSX测试,因此可能提到了OSX特定项(例如,单击与点击)。 怎么运行的 UITest的独特之处在于它不使用项目代码进行测试,而是存在于应用程序外部 。 UITest而是查看模拟器中可用的内容,并根据发现的内容返回给我们XCUIElement的实例, XCUIElement和XCUIApplication是用于此的代理。 例如,按钮是XCUIElement类型的XCUIElementTypeButton (或者仅仅是.Button )。 这意味着您将无法访问ObjC或Swift类/对象或它们的关联属性。 您只能访问XCUIElement属性。 这也意味着@testable中没有@testable或其他类似的导入。 UITest包含一项新的“记录”功能,可用于记录操作并帮助加快测试的编写速度。 UITests可以在没有Record功能帮助的情况下编写,因此可以成为测试驱动开发的一部分,但是,在编写要测试的代码后编写测试时,最好先使用Record,然后修改结果。 这是因为在您更加熟悉某个元素之前,有时很难预测该元素将如何暴露于UITest。 它还有助于识别您可能尚未意识到的问题,例如具有相同标识符的多个项目。 XCUIApplication是用于测试的代理。 它将为每个测试启动该应用程序的新实例,从而为您提供运行测试的基础。 与XCTest一样,它具有设置和拆卸方法,您可以封装一些常用功能,例如在测试文件中编写一个函数以清除文本字段,然后可以在所需的每个后续测试中调用该文本字段。 您还可以在XCUIElement进行扩展,以在测试套件的任何部分中重用代码。 XCUIApplication启动和终止应用程序(分别启动和终止)。 您还可以使用launchEnvironment在启动时将参数传递给应用程序,并使用launchEnvironment传递环境。 在头文件/ docset中:“与NSTask不同,在启动应用程序之后修改环境[和启动参数]是合法的。这些更改不会影响当前的启动会话,但是将在下次应用程序生效时生效。发射。” UITest建立在XCTest框架的基础上,并包括对该API的新添加: 没有任何官方文档,但是Joe Masilotti根据框架标头编译了文档。 上面的项目直接链接到那些文档。 如果作者将网站关闭,我们将在Github上分发该文档集的副本(截至2015年12月8日)。 该文档集还包括XCTest框架的其余部分,而不仅仅是UITest。 标识元素-> XCUIElementQuery 元素是使用查询来标识的,最常见的是使用标识符和类型的组合。 元素是唯一的,为了使用元素,查询必须返回一个元素。 Apple提供了一些快捷查询( app.tables返回所有表的XCUIElementQuery ,而app.table[“table identifier”]将返回类型为.Table的XCUIElement ,具有指定的标识符,而长格式为app.containingType(.Table, identifier: “table identifier”) ),并且可以根据喜好和需要使用长格式或短格式。 查询链接在一起,并且变量名可以在整个链中替换: […]