Tag: swift

Xcode专业提示:再次运行上一个测试

不想埋葬书架,所以这里是: ⌘G 控制选项命令G 这将再次执行您上一次执行的测试操作-这可能正在运行一个或多个测试套件或案例。 如果您要进行迭代更改,并且不想回到测试方法范围或“测试导航器”中,以便每次手动运行特定测试,这将非常方便。 也可以从Xcode的“ 产品”菜单中访问它,如下所示: 还众所周知,我会进入我的计划并切换我想要的测试套件,但是如果您要更改要频繁运行的测试集,这也很艰巨。 但是,如果您想一遍又一遍地运行测试的子集,则上述方法可能会很有用,但这是另一天的工作。

如何使用弱引用和无主引用来中断引用周期?

#第二种情况 当一个属性被允许为nil而另一个属性不能为nil 。 在这种情况下,无主引用最适合打破潜在的强引用周期。 什么是无人参考? 例如,使用未拥有的引用的生存 期比其他实例更长或更长 。 这意味着引用为“无主”的实例将始终具有值,因此始终将其声明为非可选的。 ARC永远不会将无主引用设置为nil,即使其引用的对象已释放。 因此,您应确保不要释放未拥有的引用,否则,如果尝试访问它,则会导致运行时错误。 例: 让我们考虑一个客户和BankAccount的示例。 在这里,Customer和BankAccount之间的关系与Person and Appartment示例略有不同。 客户可能有也可能没有银行帐户,但银行帐户将始终与客户关联。 让我们看看这将如何导致潜在的强参考周期。 客户类别{ 命名:字符串 var account:BankAccount? init(name:String){ self.name =名称 } deinit {print(“ \(name)正在被初始化”)} } Class BankAccount { 让号:UInt64 让客户:客户 init(数字:UInt64,客户:客户){ self.number =数字 self.customer =客户 } deinit { 打印(“正在取消初始化具有帐号\(number)的BankAccount”) } } 如您在上面的代码中所看到的,我们已经在BankAccount类中将客户属性设置为常量或非可选,因为我们知道银行帐户在客户中将始终具有客户和可选帐户属性,因为客户可能拥有或可能没有银行帐户。 var harry:客户? 哈里=客户(名称:“哈里”) harry?.account = BankAccount(号码:1323243214214,客户:哈里!) 哈里=零 如果运行上面的代码,则不会看到任何deinit方法被调用。 […]

2017年以来我所有的副项目

去年,我为朋友和家人进行了许多附带项目和小型自由演出,以期在各种不同平台上磨练我的软件开发技能。 2017年5月,我被Raizlabs聘为软件工程实习生,当时我认为这将是iOS开发,但最终以Android为主。 我在Raizlabs的夏天很棒。 我必须出去玩,向一些非常聪明的人学习,作为办公室里唯一的实习生,当我遇到任何一种障碍物时,每个人都渴望帮助我。 我有机会与RZ团队一起开发了一些出色的应用程序,但我想清楚一点,以下所列项目均与Raizlabs没有任何关系,它们完全是我自己的。 我目前是缅因州不伦瑞克市Bowdoin学院的一名大四学生,在那里我为棒球队打DH / LF。 成为Bowdoin棒球队的一员不仅意味着要穿球衣并在网站上列出,还意味着更多。 加入团队意味着您是一群紧绷的人的一部分,这些人不仅存在于花名册中,而且延伸到一大批校友中。 去年秋天,两位刚毕业的棒球运动员联系了我,他们的想法是建立一个网站,让Bowdoin棒球队的校友相互交流。 存在类似的网站,但他们希望此网站仅适合我们团队的当前球员和校友。 我在Ruby on Rails中构建了该网站的第一个版本,并将Firebase用于数据存储和身份验证。 RoR Bowdoin棒球校友网站的第一版 那年秋天,我参加了Eric Chown教授的移动计算课程,该课程本质上是16周的iOS编程训练营。 对于我们的最终项目,我们的任务是提出一个应用程序创意并生成一个可行的原型。 我选择构建Bowdoin棒球校友网络的移动版本。 不幸的是,校友网络周围的嗡嗡声消失了,因为负责运行该校友的两个校友都忙于继续他们的营销工作,所以我从未将应用程序放在商店中,而是保留了代码库,并准备在校友获得时进行部署再次感兴趣! Raizlabs的文化基础是Hack Days。 RZ遵循Google的80/20规则(可能不再存在,在线上有许多相互矛盾的报告)采用,它鼓励公司的每个人在每两周冲刺结束时参加一次“黑客日”。 Hack Days提供了进行个人项目,研究新想法或测试您感兴趣的技术的机会。 这篇博客文章中的几个项目都来自Hack Days。 CFGLive是我在RZ的第一个Hack Day项目。 在我的第一次正式冲刺结束后,我从导师那里收到了一则消息,内容是:“不要碰积压! 今天是您的Hack Day!” CFGLive的想法是将FanDuel / Draft Kings日常幻想模型应用于计划于8月第一周(此黑客日为2017年6月16日)的Crossfit Games。 该应用程序的工作方式如下:用户将创建一个帐户,然后提示他们选择前十名的男性完成者,并为其选择命名,即“ Sawyer’s Super Picks”。提交前十名的男性后,系统将提示他们选择十名女性,然后是5支队伍。 有关Crossfit游戏如何工作的详细信息,请阅读此内容。 到一天结束时(我大概在晚上7:30才离开办公室,因为我被超级带走了),我完成了所有三个级别的选择工作,并且将用户选择发布到了应用程序的公共排行榜中。 进入周末时,我只剩下两个任务:编写评分算法并实现推送通知。 得分算法比我想象的要复杂一些。 这项运动会为期四天,包括13到15个项目。 我的Firebase服务器占据了三个排行榜:男性,女性和团队。 在每个事件结束时,我将进入Firebase并更新排行榜,此时,用户提交的排行榜还将根据每个事件后的人员选择的准确性进行更新。 我知道您在想什么-“真的吗? 手动更新?”我并不为此感到自豪,但我花了数小时试图编写一个脚本,该脚本会刮除排行榜更新的网页,但官方游戏网站的排行榜隐藏在javascript文件的面纱下,而所有第三个派对排行榜网站无法足够快速地进行更新。 快速旁注:锐步(Crossfit Games的冠名赞助商)发布了一个用于实时排行榜和得分更新等的应用程序,但是它在打开时会崩溃,因此我获得了一次绝佳的下载机会,因为我的排行榜更新速度比竞赛。 回到评分算法。 […]

iOS Project分析1use sonarqube服务器docker图像和sonarqube扫描器

iOS项目分析1 使用sonarqube服务器docker映像和sonarqube扫描仪 前言: 今天的文章主要是分享,如何使用SonarQube来扫描iOS App Project, 来看看专案是否有隐藏的臭虫或怪味道(代码气味)。 主要使用到的技术与架构有: 采用docker的方式,来部署SonarQube Server在本机上(MAC OSX), 由于SonarQube需要使用一个资料库来储存扫描后的结果, 我们采用postgres资料库来做搭配,接者安装SonarQube Scanner。 最后就是扫描我们现有的iOS App Project,并查看扫描的结果。 实作过程: 首先要在MAC上安装Docker(安装参考连结),笔者使用的版本是Community Edition(CE)。 2.因为同时要使用两个docker image来做部署Sonarqube Server,所以笔者采用docker-compose的方式来做设置,将下面的程序代码存储到MAC上, 并命名为docker-compose.yml。 4.接者我们打开浏览器,连接网址『http:// localhost:9000』,已经可以连接到SonarQube Server,并使用记录帐密『admin / admin』来做登录。 5.首次登录,会出现教学模式,首先需要建立一个令牌,我们输入swift,并点击Generate。 6.这边要特别注意,这个令牌要自行保存,之后不会再次显示,如果忘记,只能删除再重新设置了。 7.接者选择后面要扫描的语言,这边我们选择其他=> macOS =>输入项目密钥=>完成 8.接者会出现后续扫描专案用的指令,也可以直接点选COPY到剪贴簿,画面有个下载按钮,点下后会连结到官方说明文件。 9.到此我们先点击跳过此教程,我们已经完成了SonarQube Server的安装。 总结: 今天介绍了采用Dokcer的方式,来部署设定SonarQube Server和Postgres DB,完成了之后要扫描iOS App Project的首要准备动作, 之后的文章里,将会实际介绍如何扫描一个专案的程式码, 并查看相关的报表,感谢您的阅读。 参考: Mac版docker Mac版Docker入门 欢迎使用Mac版Docker! Docker是用于创建容器化应用程序的完整开发平台,而Docker for Mac是… docs.docker.com 2. docker […]

通过将功能构建为框架来提高iOS团队的生产力

向现有的大型代码库中添加功能是许多工程师在其编码生涯中将面临的挑战。 如果iOS应用程序已经存在了几年以上,那么它可能已经吸引了许多开发人员为许多功能做出了贡献,从而使其成为了许多版本。 通常,结果可能是非常大的代码库,具有不同程度的模块化,较长的构建时间,而且代码不是很干净。 Scout24上的iOS应用处于不久前还处于这种状态,我想与大家分享我们如何对开发环境进行重大改进以及带来的好处。 问题 如果您曾经在一个大型项目中使用Swift进行开发,那么即使稍作改动,您可能对构建整个应用程序模块所花费的时间太熟悉了。 关于如何改善总体持续时间,有大量资源。 Swift具有许多出色的语言功能,但是这些功能是以更长的编译时间为代价的。 即使进行了少量更改,您也可能要等待几分钟才能看到结果。 这确实让人分心,效率很低! 在编码时,时间和精力是您最宝贵的资源。 如何解决 较长构建时间的答案很简单: 使编译器构建更少的代码! 听起来很合理,但是我们如何实现呢? 答案是通过使用iOS框架将我们的代码划分为更小,更离散的功能块。 在此示例中,我们将从主应用程序模块开始,并添加一个包含一些UI功能的框架,该功能构成了我们将集成到我们的应用程序中的功能。 这有什么好处? 这么小的示例可能看起来并不明显,但是以这种方式进行开发的好处是巨大的。 当您必须将功能内置到具有大量旧组件的大型应用程序中时,它们特别大。 通过将功能构建为高度独立于主应用程序模块的独立模块,您可以将更多精力放在要创建的功能上。 您会发现,您被迫以仅公开应用模块所需内容的方式来组织代码,该代码往往更加清晰和经过深思熟虑,并且不太可能发展成意大利面条式混乱,因为这样做更困难这样做。 与框架一样,构建作为框架的功能的一个基本步骤是创建一个“包装器应用程序”,就像我们在本教程中所做的那样,该程序将您创建的功能最小化地集成到一个微型应用程序中。 该应用程序无需构建主应用程序模块所需的所有其他依赖项,因此构建时间将很快缩短。 创建一个新的应用程序工作区 您将需要为您的应用程序和功能所在的框架创建一个工作区。 首先单击Xco​​de中的File-> New- > Workspace 。 在要保存工作空间的位置创建一个新文件夹。 保存后,我们现在有了一个空白工作区。 现在,单击Xco​​de中的File-> New- > Project ,然后选择“ single view app”。 将项目命名为“ SimpleCounterApp”,并确保选择“ Swift”作为应用程序语言。 之所以这样命名,是因为它将仅包含应用程序模块。 在下一步中,选择保存SimpleCounter.xcworkspace的文件夹。 在“ 添加到”下,选择SimpleCounter工作区。 必须在Xcode中打开SimpleCounter.xcworkspace才能显示此选项。 创建项目并注意,现在我们有了一个看起来很无聊的项目。 让我们开始做一个框架! 我们将在以后的步骤中将功能集成到主应用程序中,因此现在无需执行任何操作。 再次单击文件->新建->项目 ,这一次,选择“ Cocoa […]

快速提示:访问控制

在您的应用程序上下文中,将所有可以为应用程序其他部分提供信息或功能的信息都视为API会很有帮助。 访问控制是一个功能强大的抽象工具,它使您可以隐藏实现细节并控制外界如何使用您的API。 例如,如果应用程序的另一部分“不需要知道”某些信息或功能,则可以(并且应该)将其隐藏。 精心设计的API不仅使您感到愉悦,而且还可以防止滥用和程序员错误。 注意:访问控制是围绕模块和源文件的概念构建的。 模块是不同的代码分发单元,例如应用程序或框架。 有五个访问级别: private限制对同一文件中的封闭声明及其扩展名的访问。 fileprivate限制对当前文件的访问。 internal限制访问当前模块。 public允许模块之间的访问,并防止子类化。 open允许模块之间的访问并允许子类化。 您也可以将一个类标记为final以防止其被子类化,并帮助控制该对象的使用方式。 您可以控制对以下内容的访问: 构造,例如类,构造,协议和枚举。 元素,例如属性和方法。 扩展程序。 属性设置器。 让我们来看一些实际的访问控制示例。 使用我们的Swift技巧:组织文章中的组织技巧,我们刚刚在视图控制器上创建了一个扩展以符合UICollectionViewDelegate协议。 我们实现了必要的协议方法,并在此过程中创建了一些辅助方法来减少样板或冗余逻辑。 到目前为止,这是所有标准的日常工作。 现在,让我们问一个问题:模块的其余部分(甚至是该文件)是否需要了解或可以访问这些辅助方法? 如果我们将这些方法标记为private ,则它们将不再在视图控制器及其扩展名的同一文件内访问。 假设我们要在API中创建一个只读属性。 像这样简单地注释属性: fileprivate(set) var someProperty: SomeType 。 在源文件中,您将能够像正常一样获取和设置属性。 但是,在源文件之外,此属性将是只读的。 这也适用于其他访问控制级别。 例如: private(set)将setter限制为同一文件中拥有的类或结构及其扩展名。 internal(set)将setter限制为当前模块,因此导入当前模块的外部模块将无法设置此属性。 创建辅助结构或对象来包装类需要在内部传递的信息单元是很常见的。 将这些帮助程序标记为`fileprivate`会将它们隐藏为不重要的实现细节。 — – 如果您未指定访问级别,则将假设为“内部”。 有一些细微的例外。 Apple的访问控制文档具有所有详细信息,但实际上可以归结为Apple的以下报价:“无法用具有较低(更严格)访问级别的另一个实体来定义实体。”例如,类型定义为“内部”的类型不能设为“公共”类型。 访问控制是一个很好的工具,用于声明代码意图,同时封装不重要的实现细节。 这将有助于使您的API更加易于使用和安全。 与大多数事情一样,使自己熟悉Swift的访问控制功能并了解何时应用它们的最佳方法是通过练习。 下周,我们将深入研究Swift的早期退出方式,看看它们如何帮助减少嵌套并清楚地表明期望和可能的结果。 有关设计和开发的更多见解,请订阅 BPXL Craft 并在 Twitter上 关注Black […]

如何使用UIScrollView触发UITableViewCell中的滑动操作

最近,我想向UITableViewCells添加快速操作,而不是使用按钮而是使用平移手势,例如可以在许多邮件应用程序中找到的动作。 UIScrollView是最好和最简单的方法。 首先,您将看到如何在UITableViewCell中设置UIScrollView,以显示操作的自定义视图。 然后,您将看到如何通过实现UIScrollViewDelegate通过平移手势执行操作。 1. UITableViewCell设置 首先,创建UITableViewCell的子类。 容器视图将是我们的单元格内容。 动作视图和标签将是滚动显示的视图。 class SwipeCell: UITableViewCell { var scrollView: UIScrollView! var containerView: UIView! var actionView: UIView! var actionLabel: UILabel! } 在初始化程序中调用的方法中,我们实例化此视图并将其添加到视图层次结构中,如下所示: contentView 滚动查看 动作视图 动作标签 containerView 对于scrollView,我们要隐藏滚动指示器。 当用户结束拖动时,我们还希望快速减速。 注意,我们需要设置contentInset以便在scrollView的填充中显示actionView。 func setup() { scrollView = UIScrollView(frame: bounds) scrollView.autoresizingMask = [.flexibleWidth, .flexibleHeight] scrollView.contentSize = bounds.size scrollView.contentInset = UIEdgeInsets( top: 0, left: […]

地理围栏应用程序中的半径选择-iOS

几天前,我的工作是模仿iPhone提醒应用程序的基于位置的提醒功能。 其中最复杂的部分是在苹果地图上实现半径选择。 我在互联网上四处寻找帮助,但没有找到具体的帖子。 因此,由于基于地理围栏的应用程序的兴起,我想写一篇文章。 在这里,我将解释实现相同步骤的步骤。 我们将编写几行代码。 步骤1:将View和MapView添加到情节提要 将UIView视图添加到情节提要,并添加顶部,底部,前导和尾随约束。 将所有4个约束都设置为0。在UIView中添加MapKit视图,并将所有4个侧面的约束都约束为0。 步骤2:为Pin和Radius创建图像(根据您的要求) 在这一步中,我为您提供了一些技巧来创建地图图钉和半径图像,这将非常有帮助。 地图图钉:我们将使用地图图钉来显示地图的当前位置,并且当我们移动地图时,将使用图钉来选择位置。 在这里,我谈论的是Uber应用程序正在使用的功能。 因此,创建一个销钉图像,该图像是销钉高度的两倍。 因此,如果您的图钉高度为10像素,则图像高度应为20像素。 之所以这样做,是因为我们要在地图中间显示点。 半径圆:仅使用边框创建100 x 100的半径圆图像。 我们将使用此图像在地图上选择半径。 步骤3:添加地图图钉和半径圆 在我们的UIView内的情节提要中将地图图钉和半径圆添加为UIImage。 将其约束到屏幕中心。 到目前为止,我们的情节提要文件应如下所示。 步骤4:添加UIView用作触摸区域。 在这里,我们需要另一个UIView。 请检查以下图像以查看我为该视图设置的属性和约束。

Swift Localhost:使XCUITest再次出色

XCUITest的最简单的网络存根 端到端(E2E)UI测试不仅由于多个依赖关系而脆弱,而且执行起来也很慢且昂贵。 在我以前的工作中,我记得我们的组织花大量时间运行E2E测试,却由于本地客户端错误而导致测试失败,这真令人沮丧。 通过进行客户端集成测试,可以避免此类不必要的故障。 除了单元测试之外,鼓励iOS工程师编写UI自动化测试,作为完成功能所需工作的一部分。 这些测试将使用localhost模拟外部依赖关系。 我将使用此博客文章来说明使用cocoapods和XCode为现有的iOS项目设置localhost XCUITest的人多么容易。 通过4个步骤设置iOS XCUITest Localhost 这是4个简单的步骤(LAIM),用于在iOS项目中设置localhost XCUITest。 (L)本地主机 将SwiftLocalhost(https://github.com/depoon/SwiftLocalhost)安装到您的iOS项目中。 对于iOS 9,我们需要在“ Exception Domains”下将“ localhost”添加为项。 对于iOS 10及更高版本,只需添加NSAllowsLocalNetworking并将其设置为YES。 (M)模拟 创建用于准备模拟URLResponse数据的帮助程序类/函数。 在这里,我们可以指定用于测试的模拟响应文件的位置。 记录所有到达本地服务器的出站URLRequest。 对于给定的用例,我们可以使用SwiftLocalhost断言iOS应用正在按特定顺序发送特定的出站请求。 专注于模拟 工程师可以只关注模拟响应的内容,而无需知道如何启动本地Web服务器。 请记住,SwiftLocalhost的目标仅仅是实现客户端UI集成测试,而不是断言端到端的行为。 测试用例中的嘲弄 相同的XCUITest测试功能中描述了模拟响应的设置。 这有助于使测试用例更具可读性,尤其是在同一范围内可以看到测试代码和模拟响应时。 只需使用Swift 您只需要XCode和Cocoapods即可运行SwiftLocalhost。 iOS开发人员可以放心使用Swift作为应用程序开发语言和UI测试编程语言。 Cmd + U 使用SwiftLocalhost的最大优势在于其执行简单。 iOS开发人员只需按Cmd + U即可触发UI自动化测试。 因此,无需使用bash / shell来启动本地Web服务器。 此外,连续集成作业仅需要选择XCUITest方案即可运行测试。 是的,就是这么简单。 展示柜 为了展示在现有的iOS项目中设置SwiftLocalhost是多么容易 ,我分叉了一个我在Github上随机找到的iOS应用程序存储库项目,并应用了本文中突出显示的技术。 [派生] https://github.com/depoon/ios-movies-app [原始] https://github.com/mkamhawi/ios-movies-app […]

如何在Clean-Swift中编写单元测试

在 第1部分中, 我解释了如何改善应用程序的体系结构,使其更好地进行单元测试。 编写测试应该和编写代码一样有趣,对吗? 但是为什么不呢? 这就是我问自己的问题,我注意到每次尝试编写一些测试时,我都不知道从哪里开始或要测试什么。 而且,如果我有一个主意,结果证明我无法测试或不知道如何测试。 一段时间后,我开始意识到,如果您的代码结构清晰,那么您将知道在代码中放置什么内容,并且可以清楚地测试什么。 在第1部分中,您可以阅读如何根据Clean Swift模式构造代码。 在这一部分中,您可以阅读可以测试的内容以及如何进行测试。 通常,好的测试是灵活的,但并不脆弱,这意味着,如果更改一行代码,则不应破坏很多测试。 您的测试应该广泛,涵盖所有边缘情况并快速运行。 因此,您可以经常运行它们并尽快获得反馈。 单元测试的结构 在测试中,您可以区分要测试的主题 , 输入和输出 。 最好确定这三个不同的部分,因为它们可以帮助您弄清楚您需要如何处理它们。 例如,您永远不会存根您的测试主题,但可以存根 。 您将需要尽可能多的输入集测试以测试其结果。 并且在测试的断言中验证输出的值。 单元测试的典型结构是: 给定 什么时候 然后 在“ 给定中,您将创建模拟并准备输入”中,在“执行方法以对主题进行测试时”中, 然后在“使用声明中验证输出”。 不同类型的测试双打 为了为我们的测试创建真正的黑匣子,我们可能希望掩盖实现的某些部分。 我们可以使用所谓的测试双打来做到这一点。 当您必须在测试中传递参数时,但是您知道它永远不会在被测试的方法中使用时,可以传递一个哑元 。 假人返回什么都无所谓。 当您需要一个返回特定值的虚拟对象,因为系统的其余部分依靠它继续运行测试时,该虚拟对象称为stub 。 如果仅想测试是否调用了方法,则可以使用间谍 。 不利的一面是,您监视的内容越多,您将测试与应用程序实现的耦合就越紧密。 模拟是其中包含断言的间谍。 它检查使用什么参数,何时以及多久调用一次函数。 我们最后的味道是假的 。 到目前为止,所有讨论过的测试倍数都不关心您传入的参数。但是假冒的确如此,因为它具有业务逻辑,可以为不同的输入提供不同的输出。 将单元测试文件添加到您的项目 要将单元测试文件添加到Xcode项目中,可以在新项目开始时检查单元测试,也可以稍后将测试目标添加到现有项目中。 在项目浏览器中单击您的项目 ,添加一个新目标并选择一个单元测试包 : 在文件顶部,您需要import XCTest并通过添加@testable import […]