Tag: swift

使迦太基再次伟大!

您好,我是Max,我是iOS开发人员超过7年。 本文是关于依赖项管理的,因为我认为即使使用所有这些工具,它也是iOS开发过程中的薄弱环节。 感觉就像您只需要处理它,但这不是应该的样子。 在我的职业生涯中,我使用了许多依赖管理工具,从简单的拖放源代码到尖端的Swift依赖管理器。 但是仍然是我最喜欢的工具之一,仍然是Carthage:去中心化,易于管理,构建一次就可以忘记。 例如,与Cocoapods相比,它允许将所有依赖项分别并独立地构建为一堆二进制文件,这些二进制文件可直接链接到您的项目而无需复杂的配置。 我认为这是非常灵活和一致的方法。 (顺便说一句,不要忘了Cocoapods需要框架作者的大量动作。还记得pod repo的设置/更新时间吗?) 我不会在这里深入探讨可可足与迦太基。 您可以阅读很多这类文章。 我只是想表达我对迦太基的态度作为该主题的序幕。 然而,这并不完美。 我告诉你为什么以及如何修复它。 为什么迦太基不完美? 首先,如果您曾经使用过Realm,Alamofire,ReactiveCocoa等笨拙的大型框架之一,那么您可能已经注意到,您的CI / CD工作者花费大量的时间来建立依赖关系。 即使依赖项提供了预编译的二进制文件(但通常不提供),它也可能经常不适合您的Xcode / Swift版本。 因此,您花费大约80%的CI / CD时间来准备依赖项。 此外,邀请新成员加入团队或直接将现有项目克隆到另一台计算机,都会导致“让自己入睡”事件。 仅仅将框架添加到依赖项列表并不快。 当您挖掘过去的长期项目时,我什至没有在谈论过时的依赖关系。 最后但并非最不重要的一点:对静态框架的怪异支持。 为什么奇怪 因为Realm不会使用ld.py脚本构建到静态库中(例如,迦太基的推荐方法)。 您必须手动检查每个损坏的依赖关系,并为团队中的每个人将其替换为二进制文件。 金田挣扎。 顺便说一句,如果您错过了静态框架如此重要的原因,我告诉您:它显着降低了应用程序的大小和启动时间。 苹果也建议最多使用不超过6个动态库。 但是我们都为“只是一个框架”而感到内🙂 如何使它更好? 即使迦太基值得使用它。 但是有一种方法可以使它变得更好。 当我与许多团队一起处理大量应用程序时,我制作了一个工具,可将每个迦太基框架分别缓存到Amazon S3中。 因此,“已解决”文件中还有多少其他内容都没有关系,您可以根据需要下载它们中的每一个。 我的意思是,例如,如果有人至少为Swift 4.0.1构建了Realm 3.0.1,那么您可以立即下载它,而无需等待或编译。 Tbh我已经看到了很多用于Carthage的缓存工具,但是其中大多数要么需要拥有个人S3帐户,要么立即保存所有项,等等。 因此,我制作了一个工具来修复这些缺陷。 我想与您分享它,希望它可以使您的iOS编码体验至少好一点。 它称为迦太基缓存,可以在Github上找到。 如何使用它? 步骤1:下载至您的路径: 该工具将从云下载现有框架到Carthage的构建目录。 或者编译它们(如果以前没有人缓存过您的框架),然后将其上传以供公众使用。 但是静态框架呢? 这很简单: 它将下载或构建依赖项的静态版本。 […]

了解闭包中的内存泄漏

啊,内存泄漏……起初,您甚至都不知道它们可以存在,然后您将其忽略,然后在不知道如何正确处理它们的情况下开始到处看到它们。 好的,所以现在也许是时候清楚地了解它们的时间,何时发生以及可以使用哪些工具摆脱它们了。 苹果公司发表了一篇很棒的文章,介绍了强有力的课堂参考周期。 很容易理解什么是内存泄漏以及在这种情况下如何避免内存泄漏。 但是,这是一种非常罕见的情况,并且很容易发现。 我发现有关闭包的部分更加令人困惑。 因此,让我们一劳永逸地阐明这一点。 带封闭的参考循环 首先,您必须了解闭包是什么以及闭包是做什么的。 我喜欢将其描述为一段代码,该代码在声明时会创建自己的临时类,该类包含对其执行自身所需的所有对象的引用。 让我们以一个简单的示例开始:一个具有CustomView的ViewController。 该CustomView有一个闭包,当点击按钮时会调用该闭包。 如您所见,我们有一个周期。 这意味着,如果退出此视图控制器,则无法将其从内存中删除,因为它仍被闭包引用。 这个例子很清楚,我们的viewController有一个属性subview ,它有一个属性onTap来捕获self 。 但是不幸的是,它可能变得更加复杂。 潜在周期的例子 您始终必须问自己的问题是: 谁拥有封闭件? UITableView 如果您曾经构建过iOS应用程序,则必须在某个时候处理UITableView,而且很有可能,您还必须使用自定义按钮来处理自定义单元。 这是快速完成此操作的一种方法,首先,您有一个CustomCell,它具有一个动作闭合,可让您定义点击按钮时发生的情况。 GCD 您当然已经处理过Grand Central Dispatch,可以发现是否有周期吗? 在TableView示例中,如果您unowned在onButtonTap闭包中放weak或unowned ,您将看到类似以下内容: 右侧的感叹号指示泄漏。 但是Xcode有时很难检测到泄漏。 您很可能有泄漏但没有感叹号。 在这种情况下,您只需要注意内存中的内容,如果看到不应该存在的内容,很可能会泄漏。

五个针对iOS XCUITest的真实设备云测试服务

XCBlog上的原始博客在这里 苹果在WWDC15中推出了Xcode UI测试解决方案,从那时起,它已成为iOS开发人员使用同一框架编写单元和UI测试的首选。 以前,QA工程师使用诸如Appium和Calabash之类的框架来自动化iOS应用程序测试。 这些框架允许使用疯狂的语言(如Java,Ruby等)编写用户界面测试,而这些语言与iOS应用程序开发无关。 虽然,Appium和Calabash在质量检查世界中很受欢迎。 它从未引起任何iOS开发人员的注意,这在开发人员和测试人员之间造成了巨大的技术鸿沟。 苹果公司提供的XCUITests允许开发人员在Swift或Objective-C中编写测试,这有助于弥合技术差距并比以往更轻松,更快地创建UI测试。 市场上有太多的云测试服务可用于在Web应用程序的云机中执行测试,例如Sauce Labs,BrowserStack等。最初,很少有服务关注XCUITest,因为许多公司仍在使用Appium和Calabash和他们已经支持这些工具在云中运行测试。 但是,随着Apple不推荐使用诸如Appium和Calabash之类的工具的仪器技术,iOS 10版本改变了一切。 这打破了所有的移动测试自动化框架,必须使用苹果公司的新技术XCUITest。 然后,公司开始直接使用XCUITest,并且开始流行。 云测试供应商还需要增加支持以保持市场竞争力。 在本文中,我们将看到在云中的真实设备上运行XCUITest的选项。 请注意,本文不是关于服务的速度,价格或使用情况的比较。 1.位栏 Bitbar具有专门针对移动测试自动化而设计的设备云,该设备云遍及欧洲的多个数据中心。 作为仅限移动设备的测试服务,Bitbar是在云中支持XCUITests的先驱之一。 很久以来,他们都在其官方博客上撰写有关XCUITest和iOS自动化的文章。 它们与移动DevOps工具集成在一起,并具有远程调试功能。 您可以在一段时间内免费试用Bitbar。 Bitbar有很多客户,包括Microsoft,Skype,EA,Asus,Paypal,T-Mobile等。 2. AWS设备场 Amazon Web Services提供了各种软件开发服务,包括Device Farm,用于针对AWS云中的实际移动设备进行测试。 AWS Device farm包含有关如何使用各种框架(包括XCUITest)执行测试的出色文档。 我们可以将AWS服务与我们的免费套餐帐户一起使用进行试用。 AWS Device Farm已被包括Etsy在内的多个客户端使用。 3. Perfecto Perfecto是对移动Web应用程序进行基于云的连续测试的另一种选择。 Perfecto提供了在真实设备云中执行XCUITests的支持。 他们拥有有关包括XCUITest服务在内的各种服务的文档,视频和代码示例的丰富信息。 您可以在此处阅读有关配置XCUITests for Perfect cloud的更多信息。 Perfecto使用他们的服务有各种各样的客户。 这里列出了超过100个客户。 4. BrowserStack BrowserStack是另一项服务,最近宣布在其真实设备云上支持runningXCUITests。 这里有关于如何在BrowserStack上设置XCUITests的文档,它们还在此处与示例iOS项目共享了配置XCUITests的代码示例。 5.酱汁实验室 Sauce Labs在测试自动化社区中非常活跃,并举办多个活动和会议。 […]

使用Swift向图像添加滤镜-变得简单

使用Apple内置的Core Image功能过滤图像实际上非常简单。 我们需要做的第一件事是创建一个我们想要使用的过滤器类型的枚举: 枚举FilterType:字符串{ 案例Chrome =“ CIPhotoEffectChrome” case Fade =“ CIPhotoEffectFade” case Instant =“ CIPhotoEffectInstant” case Mono =“ CIPhotoEffectMono” 案例Noir =“ CIPhotoEffectNoir” case Process =“ CIPhotoEffectProcess” case Tonal =“ CIPhotoEffectTonal” 案例转移=“ CIPhotoEffectTransfer” } 接下来,我们创建一个扩展函数,该函数需要过滤器类型。 然后,它获取这个filter.rawValue并将其输入CIFilter,然后将其应用于图像。 扩展程序UIImage { func addFilter(filter:FilterType)-> UIImage { 让过滤器= CIFilter(名称:filter.rawValue) //将UIImage转换为CIImage并设置为输入 让ciInput = CIImage(image:self) filter?.setValue(ciInput,forKey:“ inputImage”) //获取输出CIImage,首先渲染为CGImage以保留适当的UIImage比例 让ciOutput = filter?.outputImage 让ciContext = […]

SOLID原则-第5部分

依赖倒置原则指出,较高级别的模块不应依赖于较低级别的模块,它们都应依赖于抽象。 换句话说,所有实体都应基于抽象接口,而不应基于具体类型 。 该原则还强调,抽象不应依赖细节。 细节应取决于抽象。 因此,这里的技术问题是什么是更高级别的模块? 或我们可以定义为较低级别的模块? 高级 模块是包含应用程序的策略决策和业务模型的任何模块。 这可以视为应用程序标识。 更高级别的模块主要由应用程序中的表示层使用。 低级模块是包含执行决策和业务策略所需的详细实现的模块。 依赖倒置原则有时被误认为是依赖注入。 虽然这些术语看起来彼此相似,但它们完全不同。 依赖注入是为对象提供实例属性或变量的过程。 但是,不提及依赖注入就很难谈论依赖倒置原理。 这是因为您需要依赖注入机制来实现依赖倒置。 假设我们要使用“ UserDefaults ”在应用程序中保留,读取和擦除一些用户编码的数据,并带有一些将实际实现逻辑分开的高级抽象。 到目前为止,我们将使用Swift语言作为实际示例的SOLID原理带到了旅程的尽头,之前的原理是关于接口隔离 对于完整的操场,您可以在github仓库中找到它。 请随时与我们联系。 我期待知道您的想法。 我也写过迅捷的associated-type请看一看。 鲍勃·戈德温(@bobgodwinx)| 推特 Bob Godwin(@bobgodwinx)的最新推文。 移动团队首席工程师@dunnhumby Germany GmbH。 @Apple的粉丝… twitter.com

保持游戏最佳状态-iOS新闻,博客/开发人员,关注的公司

作为一名全职iOS开发人员,我每天都会在紧迫的项目截止日期前应对大风。 而且,我很少有时间与有关iOS开发的最新趋势,公告,创新,文章和开源灵感保持联系。 很难保持我的游戏优势。 你可以联系吗? 幸运的是,我已经找到了一些方法来及时了解iOS开发领域中的新情况。 几封惊人的新闻通讯会以电子邮件的形式发送他们的发现和出色的东西。 订阅他们! 公司和热情的开发人员需要时间来发布出色的博客,很棒的开放源代码库并定期发出蓝色乌鸦。 跟随他们。 在这里,我列出了新闻通讯,博客,人员,公司和其他资源,这些资源可以帮助我保持iOS和Swift开发人员的最新状态。 通讯-策划 所有的指针整齐地排列👍。 斯威夫特本周 — https://swiftnews.curated.co Natasha Murashev每周都会为您汇总最佳的Swift资源列表。 您知道她是秘密的机器人吗? 继续阅读。 独立iOS焦点周刊 — https://indieiosfocus.curated.co 寻找除常见新闻之外的最佳iOS开发链接,教程和技巧? 由Chris Beshore策划。 我喜欢关注独立的iOS开发人员。 Swift算法新闻 — http://swiftalgorithms.curated.co 《快速算法新闻》是由韦恩·毕晓普(Wayne Bishop)精心策划的出版物,其中包含有趣且相关的链接。 iOS开发周刊 — http://iosdevweekly.com 您是否已经开始注意到上述新闻通讯看起来很相似? Folks,Dave Verwer-Curated的创始人和iOS Dev Weekly的作者。 他每周都会收集精选的最佳iOS开发链接。 我永远不会错过阅读他对每个问题的评论。 iOS产品-http ://ios-goodies.com Rui Peres和Tiago Almeida策划的另一期iOS每周新闻简报。 文章,应用程序业务,UI / UX,工具,视频等都是好东西。 斯威夫特月刊 — http://swiftmonthly.com 手工挑选的Swift教程,新闻,视频,工作,会议以及更多其他内容直接发送到您的收件箱。 没有烦恼,没有垃圾邮件! 迅捷发展-https […]

Swift:没有人会打扰的常见错误-一流的功能和保持循环

您好,我亲爱的开发人员, 最近,我认识的一家基于洛杉矶的创业公司联系我,要求我进行代码评估。 他们在代码不稳定,随机崩溃和类似问题上遇到了可怕的问题。 我能说什么 代码中充满了我在上一篇文章中提到的错误(尤其是强制拆包和强制转换,我向之致敬,因为它们是导致大量崩溃的原因)。 但是,由于人们了解Swift中的所有功能都是一等的高阶函数,因此在不同的项目中一遍又一遍地出现了一个特别的错误。 您可以放入变量,将其作为参数发送给其他函数,并作为执行某些函数的结果来接收。 因此,让我们看一下一般的简化情况: 免责声明 : 这是概述方法的示例代码,其他代码段也是如此。 请原谅我,我的读者,我的确理解这一点。 令我震惊的是,有多少人没有得到我所有的文章都描述了通用方法,而不是具体用例。 处理器是执行处理并在处理完成后调用回调的某种实体。 在这种情况下, 数据是拥有处理器并对处理完成时调用的回调感兴趣的某个实体。 最简单的用户故事之一是Data是UIViewController子类,而Processor是UIView子类,当用户以某种方式与视图交互时,该类从控制器调用回调。 那么,这段代码有什么问题呢? 我们这里有一个保留循环。 Data和Processor都不会被释放。 检查我的陈述确实是真的很简单。 只需将调试打印放入Processor和Data的 deinit方法中即可。 如您所见,它从未打印任何内容,因为从未调用过deinit 。 那是因为保留循环。 但是为什么在这种情况下实际上会出现保留循环? 为了掌握这一点,您需要了解swift中的任何struct和class实例函数都是闭包。 闭包是捕获和存储外部上下文(例如变量)的一种函数。 一个完美的关闭示例是: autoincrementedIDGenerator返回一个函数,该函数捕获id并对其进行操作。 每次我们调用该函数时,它都会创建一个名为id的新变量,并返回捕获该变量的函数。 当我们测试输出时,我们将收到: user id = 0 user id = 1 user id = 2 image id = 0 image id = 1 image id […]

CoreData持久性代码的灵活轻松的单元测试

现代和高质量的iOS应用程序有望完美运行。 确保完美无瑕,耐回归的代码的重要输入是在开发过程中添加全面的单元和集成测试。 本文逐步介绍了使用CoreData作为其持久层为iOS应用程序构建可重复的自动化数据库单元测试的方法。 目标受众 本文假定您了解在iOS应用程序中使用CoreData的基础知识,并且可能已在自己的工作中使用它。 但是,本文的重点是体系结构,即使您不知道如何使用CoreData进行编码,但如果您了解iOS中的数据持久性和单元测试的基础,此处的概念仍然有意义。 代码样例 本文中的代码和概念是使用Xcode 10(测试版)和Swift 4.2开发的。 本文包括用于说明概念的代码摘录,但并未在本文的正文中嵌入此解决方案的所有代码,而是在本文结尾处提供了指向我的GitHub存储库中的示例应用程序的链接。 CoreData是iOS(和macOS)应用程序的默认本地持久性选择。 核心数据从根本上讲是持久化数据存储上的对象关系映射(ORM)层。 虽然CoreData对象的物理存储是从开发人员抽象出来的,但CoreData几乎总是与SQLite一起使用。 如果您是CoreData的新手,或者只是需要复习,那么这里有很多很棒的资源,例如Apple自己的Core Data编程指南和RayWenderlich.com上的Core Data入门指南。 以下是典型应用程序如何访问CoreData的高度简化图。 我将在下面讨论架构的每个元素。 AppDelegate。 该对象表示iOS应用程序的入口点,并且所有iOS开发人员都应该熟悉。 如果使用 Xcode 10中的“ 使用CoreData”选项创建项目,则Xcode将为您创建基本的CoreData堆栈。 在AppDelegate对象中,您会发现以下属性爆炸了。 本质上,此属性是您的应用程序用来访问CoreData管理的数据的挂钩。 类 AppDelegate:UIResponder,UIApplicationDelegate { 。 。 惰性 varpersistentContainer:NSPersistentContainer = {…} 。 。 } NSPersistentContainer属性中具有一个设置,该设置指定是将其数据保存到SQLite磁盘文件(NSSQLiteStoreType) ,内存(NSInMemoryStoreType)还是其他位置(NSBinaryStoreType) 。 后一种情况很少见,在本文中我将不再讨论。 如果未指定任何设置(默认设置), CoreData将使用NSSQLiteStoreType来配置容器。 .xcdatamodel。 当创建具有CoreData支持的项目时,Xcode将自动创建一个数据模型文件 ,其根名称与新项目名称和扩展名xcdatamodel相匹配。 Xcode数据模型编辑器将您不断发展的设计存储在此文件中,并使用此元数据文件为您生成低级CoreData实体模型类。 在Xcode 10中,生成的模型类将自动提供给您的XCTest目标(在某些旧版本的Xcode中不是这种情况,是的!)。 存储管理器。 虽然直接在整个应用程序中访问CoreData和自动生成的实体模型类当然是可能的并且可以接受的,但是将数据操作封装在服务类中是很常见的。 在这种架构中,我已经做到了。 这种方法简化了其余应用程序的数据访问代码,并提供了某种程度的封装,以防基础数据库物理层将来发生变化。 […]

海鸥和服务器端Swift — 2

第一部分: Seagull和服务器端Swift 。 我已经更新了海鸥版本,现在是0.1.5。 没有大的变化,只有错误修复和改进。 无论如何,Seagull已经距离理想的REST框架又近了一步) 在进行开发时,我获得了一些有关服务器端Swift的新课程。 我想分享我的经验。 Swift和Docker 在Docker容器中运行Swift项目并不像我以前想象的那么容易。 Swift还没有官方形象(真可悲)。 因此,某些项目使用自己的图像。 作为迅速尼奥。 Seagull基于swift-nio,因此我也必须使用它(进行少量修改) 在不同的linux版本上测试项目是一个非常好的主意。 幸运的是,使用docker-compose很容易。 对于Seagull,我为Ubuntu 16.04添加了默认的docker-compose文件,为14.04添加了其他文件。 它是基于Ubuntu 16.04的swift-nio docker映像的docker-compose文件。 现在,我可以使用一个命令在纯Ubuntu 16.04上运行单元测试和测试REST服务器: docker-compose -f docker / docker-compose.yaml进行单元测试 或适用于Ubuntu 14.04的版本: 只需在参数中设置Linux和Swift版本,然后构建并使用其他映像即可。 docker-compose -f docker / docker-compose.yaml -f docker / docker-compose.1404.41.yaml up res 我花了一些时间来了解它在swift-nio中的工作方式以及如何在我的项目中使用它,但是现在我有了简单而强大的工具,可以在Linux环境中测试我的Swift项目。 这非常有帮助。 测试框架 这让我感到惊讶,但是Mac上的“嵌入式” XCTest和开源Swift的XCTest有所不同。 这是XCTest中的“新型”异步测试。 简单,我真的很喜欢。 但是,当您尝试为Linux编译项目时,它不起作用。 感谢Docker,我找到了它。 老款式。 不太优雅和灵活,但可以在所有平台上使用。 可编码 我太懒了,在测试中我使用了Swift如何序列化Encodable对象的假设。 […]

CollectionView自定义布局

在iOS上添加UITableView,在UICollectionView上添加UITableView。 在UICollectionView中使用网格,在UI中使用UI。 UIKitViewKit的UICollectionViewFlowLayout布局,UICollectionViewLayout的自定义视图。 Apple的自定义布局自定义布局流的布局。 (UICollectionViewFlowLayout中的对象列表) 在UICollectionView中添加UICollectionViewLayout在UICollectionViewLayout中。 그래서适用于iOS的Collection View编程指南핵심API와属性와정정해보았다。 UICollectionViewLayoutAttributes CollectionViewLayout和UICollectionViewLayoutAttributes一起显示。 (框架,中心,位置,zIndex등) 본적인용하는게。。。。있다。 (레이아웃반복적으로반복적으것은이많은이비용。) 필수적으로불리는API및属性 prepareLayout conentSize属性 layoutAttributesForElementsInRect prepareLayout 초기계산을회를기회를제공 在UICollectionViewLayoutAttributes中获取结果。 (캐싱) 이부분에서로캐싱하는식으성능상좋음。 (매번属性호출시있음있음있음있음) contentSize 스크롤할지지정할있음。 flowLayout下载스한쪽방향으이아님。 layoutAttributesForElementsInRect prepareLayout음에음에음에호출되는함수 반환(반환사이즈) 필요함사각형과교차되는지를반환이반환이필요함。 layoutAttributesForItemAtIndexPath 요청함기주로개별레이아웃객체에기주로적으。 例如)삭및제시에시에이션정보 initialLayoutAttributesForAppearingItem cell이보여질때기초지정해줄속성을。 이통해서插入애니메이션을수있음。 finalLayoutAttributesForDisappearingItemAtIndexPath cell사라질때지정해줄수。 删除애니메이션을션을수。 invalidateLayout 레이아웃을기초(업데이트할기수제공) 이는레이아웃에지이지데이터를다시정설아님。 (reloadData와다름) targetContentOffsetForProposedContentOffset:withScrollingVelocity: 함마막막막막함정함。 크롤시스통해서지지정해있음있음있음 CustomLayout설정방법 故事板에서collectionView의布局类를변경 collectionView.collectionViewLayout =커스텀레이아웃 请参见UICollectionViewLayout和API。 下载CustomLayout应用程序。 [이미지출처] https://developer.apple.com/library/archive/documentation/WindowsViews/Conceptual/CollectionViewPGforIOS/CreatingCustomLayouts/CreatingCustomLayouts.html#//apple_ref/doc/uid/TP40012334-CH5-SW1