Tag: swift

鱼子酱的iOS:从AdvancedCollectionView迁移到PJFDataSource

幕后介绍了我们Caviar iOS应用程序中PJFDataSource的演变。 由 Michael Thole 撰写 。 抬起头,我们已经搬家了! 如果您想继续了解Square的最新技术内容,请访问我们的新家https://developer.squareup.com/blog 2014年12月,我们为鱼子酱(高品质的餐厅送餐服务)发布了iOS应用程序的第一个版本。 该应用程序的视图控制器架构主要基于苹果2014年WWDC演讲:具有集合视图的高级用户界面和随附的示例代码中列出的框架。 对于我们的应用程序来说,这是一个很好的起点,但是由于下面将要详述的原因,我们最终对它感到沮丧。 在考虑了多种方法之后,我们决定构建一个小型库,以重新实现我们最重视的AdvancedCollectionView功能,同时保留我们不需要的任何复杂性。 为了推动我们建立一个与Caviar应用程序没有太紧密联系的通用库,我们从一开始就将其构建为外部库。 我们已经成功使用它超过6个月,并决定将其作为PJFDataSource开源。 在本文中,我们将研究PJFDataSource的发展过程:它是我们早期应用程序体系结构中AdvancedCollectionView示例代码的替代品。 如果您只想潜入,请转到我们的GitHub页面。 一个好的起点 尽管我们最终遇到了问题,但将Caviar的iOS应用程序结构基于Apple的AdvancedCollectionView示例代码是一个很好的起点。 它提供了一种一致的方法来在整个应用程序中加载数据和显示内容,并促使我们迈向许多最佳实践。 最重要的是,AdvancedCollectionView帮助我们避免创建Massive View Controller,这是常见的iOS应用程序体系结构的陷阱(为此有很多好的解决方案)。 它这样做的主要目的是要求每条内容都具有一个与视图控制器本身分离的数据源对象。 这些数据源对象是内容视图的模型。 在此实现中,这些对象还负责加载其内容-另一种责任可能是使用不太严格的方法最终在视图控制器中完成的。 这些数据源甚至可以像构建块一样组合在一起构成一个“聚合数据源”,从而鼓励创建较小的组件数据源。 这允许在应用程序不同部分中的相同组件重复使用代码。 例如,您添加到购物车中的食品列表以及历史收据上的食品列表可以共享这些组件数据源之一,因为它们表示的是相同的内容,只是在不同的上下文中。 AdvancedCollectionView还提供了一种一致的方法来显示加载,无内容和错误状态。 它通过将数据源对象与显示您的内容的UICollectionView紧密耦合,并在适当的时候添加辅助的占位符视图来实现。 尽管起初并不明显,但这成为AdvancedCollectionView我们最喜欢的“功能”之一,并且在PJFDataSource的构建中起了很大的作用。 问题和解决方案 当我们摆脱了Caviar的iOS初始发行版,并开始适应常规的功能构建和错误修复发行周期时,我们开始意识到使用AdvancedCollectionView的缺点与我们一样严重。 这些都是相互关联的,但我将围绕灵活性,稳定性和社区性主题进行讨论。 灵活性 正如您可能从名称中猜到的那样,AdvancedCollectionView需要使用UICollectionView。 您可能已经听过这样的格言:“如果您只有锤子,一切看起来都像钉子”。 对于我们来说,UICollectionView是我们的锤子,尽管它并非总是最适合此工作的工具。 缺乏灵活性从多个方面打击了我们。 一个简单的具体示例来自主屏幕,其中,鱼子酱列出了您可以订购的所有餐厅。 在我们较大的市场中,这可能是数百家餐厅,每个餐厅都有一个高度可变的单元,具体取决于相关的元数据。 传统上,集合视图和表视图需要确定每个单元格的大小,以便计算其自己的内容大小。 如果内容很多,这可能会很慢,并且会对用户体验产生负面影响。 对于UITableViews,Apple添加了tableView:estimatedHeightForRowAtIndexPath :,此问题的一种优雅解决方案。 当时无法访问集合视图布局中的类似内容,因此我们不得不实施自己的快速视图大小调整和缓存-我们本来希望避免的复杂性。 更一般而言,在Caviar应用程序中几乎所有地方都使用UICollectionViews实在是太过分了。 使用UITableView可以更简单地实现几乎所有屏幕。 有些甚至可以通过基于UIStackView的布局(与OAStackView for iOS 8兼容)来实现,甚至可以通过手动的基于UIView的布局来实现。 这种经验是我们决定PJFDataSource应该与视图无关的主要原因,而将其留给应用程序来提供自己的内容视图。 PJFDataSource并没有与收集视图紧密结合,而是提供了一个“内容包装视图”,它将显示您提供的内容视图,或者显示用于处理加载,无内容和错误状态的各种占位符之一。 […]

Swift类型属性

关于属性的另一件事是,您还可以在类型本身(类,结构,枚举)上定义它们。 当您想要定义与该类型的所有实例相同的属性时很有用。 类型属性的好处: 您可以访问它们而无需创建该特定类型的新对象。 这些类型属性区域可用于该特定类型的任何实例 类型属性既可以是计算属性也可以是存储属性(var或let)。 但是,在类中,要在子类中重写的类型属性只能是计算属性。 如果尝试其他方法,将得到此错误: 错误:类中不支持的类存储属性; 您是说“静态”吗? 由于类型属性中缺少初始化,因此您需要提供默认值,但是无需初始化类型就可以访问它。 就使用的关键字而言,值类型(结构和枚举)与引用类型(类)之间存在微小但相关的差异。 结构/枚举: struct和enum中的类型属性以关键字struct开头 类: 如果类型属性不是要被子类覆盖,则类中的类型属性(由于其引用类型)将使用关键字static;如果是,则使用关键字类 (在这种情况下,在子类中,您还必须使用关键字重写以向编译器发出信号,表明子类正在实现其自己的type属性) 另外,如果要使用关键字class以便可以在子类中更改属性,则似乎无法在存储的属性上使用它。 另一个重要的区别是,类中的静态属性不能被子类覆盖,但是子类可以通过点语法使用它(您可以通过在类型属性中使用类型名称,后接点(。)和类型属性的名称)。 您可以使用OctagonSide2看到它,它可以从其超类访问静态属性

如何使用Dynamsoft iOS相机SDK

几周前,Dynamsoft发布了一个iOS相机SDK,旨在帮助开发人员快速构建适用于iOS平台的文档扫描应用。 在本文中,我将分享如何在Xcode中配置SDK,以及如何从头开始创建简单的文档扫描器应用程序。 适用于iOS 1.0的Dynamsoft Camera SDK Xcode 9.2 迅捷4.0 在使用SDK之前,您最好了解不同类之间的关系。 打开Xcode,然后按Shift + Command + N创建一个Single View App。 在Xcode中构建项目时,出现以下错误: 这是StackOverflow的解决方案: 关闭Xcode。 打开钥匙链。 在本地中找到iOS开发者证书。 将证书从“本地”拖放到“系统”选项卡。 出现提示时输入管理员密码。 启动Xcode并为您的设备构建项目。 将DynamsoftCameraSDK.framework拖到您的项目中。 确保选中“如果需要复制项目”。 该SDK取决于sqlite3和stdc ++ 。 单击项目设置>常规 ,添加libsqlite3.tbd和libstdc ++。tbd 。 如果要使用视频视图实时扫描文档,请单击项目设置>信息以添加“隐私-相机使用说明”。 如果没有此属性,则会收到错误消息: 2018-02-02 15:55:08.511904+0800 docscanner[4310:948418] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles 2018-02-02 15:55:08.511904+0800 docscanner[4310:948418] [MC] System group container […]

迦太基的依赖性管理策略

在与iOS和macOS开发人员进行讨论时,我意识到他们几乎所有人都知道迦太基,但是不幸的是,一些开发人员认为它仅限于carthage update命令来下载框架。 如果您只知道update作为选项,或者仅倾向于使用此选项,那么您将在本文中找到一种简单而有效的依赖项管理策略,该策略仅基于两个Carthage选项update和bootstrap 。 迦太基使用基础 迦太基工作流程基于Cartfile ,后者是开发人员和工具之间的接口。 我们在该文件中以OGDL格式添加了我们想要的所有框架。 为简化起见,我们每行通过添加其来源(Git repo,github或二进制文件)以及可选的要下载的版本来编写一个框架。 注意 :第一次添加每个框架都需要其他必要步骤(请参阅:将框架添加到应用程序)。 迦太基更新 该命令将通过解决所有依赖关系来下载Cartfile中列出的所有框架; 构建它们(如果未指示版本要求,则下载依赖项的最新版本)并更新解析文件carthage.resolved ,列出所有依赖项(甚至是嵌套的依赖项),并列出每个要下载的确切版本。 迦太基靴 此命令将完全按照carthage.resolved文件中的说明下载和构建框架。 如果文件( carthage.resolved )不存在,则此命令将执行update ,它将解决依赖关系并(重新)生成它。 战略 首先,它包括将Cartfile和carthage.resolved添加到版本控制系统(大多数情况下为Git),并排除Carthage目录及其子目录,以使存储库轻巧。 然后,所有团队成员每次需要获取所需框架时都需要使用carthage bootstrap (例如,当切换到不包含相同框架版本的新分支或包含新框架的分支时)。 最后,仅在确实需要更新框架并将这两个文件添加到commit (当然,在测试和/或调整实现以适应更改之后),才使用carthage update 。 一般 可以将相同的策略应用于其他依赖项管理工具,例如: Cocoapods ,带有pod install , pod update以及Podfile和Podfile.lock Bundler ,具有bundle install , bundle update以及Gemfile和Gemfile.lock 并且可能是其他同类工具。 本文的其他版本:法语 Github项目: 迦太基

Swift World:设计模式-外立面

从字面上看,立面意味着 建筑物的正面,尤其是可望向街道或开放空间的主要正面。 来自Facade — Google搜索 类似地,当设计模式立面定义到复杂子系统的更简单接口时。 例如,在我们的汽车制造厂,我们有不同的部门来生产不同的组件,例如引擎,车身和配件。 作为客户,我们不在乎每个部门如何完成自己的工作。 我们只是创建一个工厂实例并使它工作。 class Engine { func produceEngine () { print (“prodce engine”) } } class Body { func produceBody () { print (“prodce body”) } } class Accessories { func produceAccessories () { print (“prodce accessories”) } } 因此,我们构建了一个外观以提供一个简单的界面。 class FactoryFacade { let engine = Engine () let […]

在Swift中使用二次曲线进行动画处理

在 Github 上可以找到该项目的完整代码 如果浏览移动UX / UI设计网站时发现了任何东西,那么流畅的动画就是设计师展示其才能的最喜欢的方式。 在完成了一些需要从After Effects文件转换动画曲线(定时和坐标值)的项目后,我可以体会这种转换带来的难度和断开连接的程度。 在最近的iOSoho Meetup上,谷歌的Adrian Secord(iOS UI框架技术负责人)讲述了为解决将 曲线 转换为代码这一问题的解决方案。 从他的讲话中 看来我对困难的理解是正确的! 尽管快速发展的设计标准已成为移动开发的标志,但似乎无法忍受流体动力学过时的那一天。 因此,我决定真正倾身并拥抱流畅的动画。 挥手? 还是杰洛? 也许至少是牛顿? 这是今天在星巴克玩贝塞尔曲线约两个小时的最终结果。 是否像您在iOS中遇到的一些流畅的交互一样酥脆和干净? 不,一点也没有。 但这无疑是一个很好的例子,说明了在iOS中添加动画曲线而无需吊舱很简单。 二次曲线 这很困难,但是当我刷二次曲线时,我能够阻止自己迷失在Wikipedia反馈循环中。 这是一个非常有趣的话题,有许多分支节点值得进一步探讨。 但就目前而言,足以知道向UIBezierPath添加二次曲线将使两个端点之间的线向第三点(称为控制点)弯曲。 一个有助于理解这些曲线的现实世界模拟方法包括在您的拇指和食指之间拉伸橡皮筋,然后用另一只手拉动拉伸的一侧。 您的食指和拇指充当线条的端点 ,而无用的手(拉动乐队)充当控制点 。 在您的脑海中,您仍然必须想象实际的曲线,但是当您将自由手( 控制点 )移动到拇指和食指( 端点 )之间的不同点时,应该能够更轻松地可视化该曲线的变化。 句法糖 为了使我的视觉神经平静,我在项目中添加了一些语法糖,以减少必须编写的CGRectGetXXX的数量。 我创建了RectFramer来包含每个CGPoint或CGFloat值的自动完成属性 我可能需要在给定的CGRect(UIView.bounds)上进行访问: 动画波峰 就iOS动画而言,wave的动画实现是相当标准的,因此我决定不做进一步介绍。 而是以下是负责动画的代码: 简洁的iOS动画代码 波浪“低谷” 将波动画完成到其周期的下一个部分,即波谷,与波峰几乎完全相同,而只是使用反转的控制点值。 有关此部分的更多详细信息,请查看该项目的Github。 结论 一旦我在纸上画出动画的不同阶段,就很容易将其转录为代码。 这就是在iOS中制作动画的秘密。 因为插值是“免费的”,所以您只需要知道动画需要命中的不同阶段。 如果您可以考虑然后绘制出这些不同的阶段,将它们链接在一起将变得更加容易管理。 >思想

Todays Extension ve ortak钥匙扣kullanımı

iOS版本,扩展名为’larda Keychain’desakladığınızverilereerişmenizgerekebilir。 密码登录Token’ınkeychain’e kaydettiniz veuygulamanızaeklediğinibirwidget’ında bu Token’aerişmesigerekiyor。 Uygulamanızveextesion’larınıarasında钥匙扣paylaşımıoldukçakolay。 1-开发人员hesabınızdanuygulama Prefix’inialın: developer.apple.com->证书,标识符和配置文件->应用程序ID->Uygulamanızaltındali“前缀”我不是。 2-钥匙串共享 ProjeayarlanızındaKeychain Sharing’i aktive edin。 Ve 1.adımdakiprefix’iaşağıdakigibi ekleyin。 3-.dosyasınıkontrol edin的权利: 项目Navigator’da XCode’unoluşturduğu.entitlementsdosyalarınıaçın(1个aduuygulamanıziçin1个adet deoluşturduğunu扩展名için)。 扩展名.dosyasında的“钥匙串访问组”项0到项1扩展名2。添加“钥匙串组”的名称2的名称。 Veişlemtamam,扩展名veuygulamanızkeychain’ipaylaşıyor。

使用IGCStatefulView管理UIView状态

当今大多数(如果不是全部)应用程序都会向其用户显示某种数据,无论是体育应用程序的记分板,新闻应用程序的各种新闻和文章,还是金融应用程序中与股市相关的信息。 这些应用程序希望一直向其用户提供有价值的信息,因此在某些情况下,这些应用程序将无法正常运行,例如网络错误或服务器错误。 然后,应用程序应该能够以某种方式向用户显示这些错误,使用户可以清楚地了解他们尝试查看应用程序中的信息时所发生的情况。 对于移动应用程序开发,表视图有一个特殊的子类别,它可以执行这种数据处理,即有状态表视图 。 这些表视图就其对应的数据集传达了不同的状态。 大多数有状态表视图都围绕以下三个状态: 加载,成功,错误 。 载入中 是当应用程序仍在处理其数据以将其作为数据源馈送到其表视图时。 成功 是指应用程序成功处理了数据后,在此过程中将其显示在表格视图中。 错误 是当应用程序遇到任何可能阻止应用程序获取必要数据的错误(上述示例)时。 现在,您可能想知道如何处理此类情况。 幸运的是,对于我们的iOS开发人员而言,Cocoapods拥有大量的图书馆,可以为我们完成工作。 考虑到这一点,让我们专注于一个库,它不仅显示表视图的状态,而且还显示集合视图和一般视图的状态-IGCStatefulView。 顾名思义 , IGCStatefulView的功能与其他状态表视图库相同,但是它的优点之一是,除了对UITableView实例的支持外,它还可以容纳UICollectionView和UIView 。 其背后的想法是数据的显示不仅限于UITableView实例。 由于它的功能类似于UITableView,因此也可以通过UICollectionView完成。 另外,并非所有数据都以列表形式显示。 例如,假设有一个新闻页面的详细信息页面。 虽然合理,但大多数时候,显示相关信息是通过UIScrollView或UIView完成的。 希望您会发现此库对您的项目有用。 如果您想了解有关IGCStatefulView的更多信息,以及如何将其集成到您自己的项目,使用它或为它做贡献,请检查其GitHub存储库。 干杯! 吉尔斯·兰伯特(Gilles Lambert)摄

在视图坐标系之间转换框架

知道子视图的确切位置是一种可以在多种情况下派上用场的技术。 您可能想知道用户是否可以看到该视图,从视图的初始位置执行动画或将视图还原到其原始目的地。 有很多用例。 您可能还会想到更多。 但是,当您要执行此操作时,您不能仅仅依赖目标视图的框架,因为它只是其超级视图坐标系的一部分,这很快会引起问题,具体取决于您如何构成视图层次结构。 幸运的是, UIView和NSView都有一些方法可以为我们提供所需的结果。 如果您阅读我的上一篇有关框架如何在macOS上工作的文章,您可能还记得我们曾简要介绍过坐标系。 因此,让我们深入了解如何在不同的坐标系之间转换框架。 现在,我们已经设置了场景,让我们看一下整篇文章所涉及的方法, convert(CGRect,to:UIView?)方法。 如果我们检查从访问视图框架中获得的值。 它是视图坐标空间内的正确值,但是当尝试在扩展到视图坐标空间外部的上下文中组合这些类型的值时,这并不能使其普遍正确。 我们要实现的是知道视图在屏幕上的确切位置,而不是子视图内的位置。 因此,通过传递当前帧并将其指向所需的坐标空间,我们现在可以获得所需的测量值。 您可以切换到任何您喜欢的坐标系。 我选择了过去与我最相关的窗口。 在实现中执行此操作时,访问视图的窗口很简单。 所有UIView都有对其所属窗口的可选引用,如果该值为nil,则表示该视图尚未添加到窗口中。 附带说明,这只是冰山一角。 这些方法中有更多的是采用点而不是框架。 请查看UICoordinateSpace以获取更多信息。 https://developer.apple.com/documentation/uikit/uicoordinatespace 这些方法在UIWindow上也可用的原因是它继承自UIView ,后者又符合UICoordinateSpace 。 如您所见,这是直接但功能强大的,但是macOS呢? 让我们看一下带有一些macOS代码的另一个示例。 该技术本身以及转换时的结果保持不变。 这两个示例之间唯一明显的区别是,它使用NSView表示窗口。 原因是NSWindow不符合PlaygroundLiveViewable 。 即使这看起来很虚伪,但在思考如何解决特定情况时,该技术也具有巨大的价值。 我在优化滚动视图和集合视图的滚动性能时都使用了此方法,如果该视图在屏幕上不可见,则不执行布局操作。 我还使用了这些类型的值来定义核心动画的开始和结束位置。 我相信您可以提出更多方案,关键是要知道该技术可以扩展您的工具箱,并且您获得的工具箱越大,找到问题的最佳解决方案就越自然。 希望您觉得这有用,对我而言,这已经无数次挽救了生命。

Swift:没有人会打扰的常见错误-属性和函数调用的明确性

您好,我亲爱的开发人员, 我想提到的一件事是,Swift在函数和属性调用中引入了隐式性(可以避免调用self): 我们在ObjC遇到了这样的事情,但是到目前为止,这种疾病已经扩散到了各处。 使用该语言功能有几点要点: 没有语法高亮显示的代码不可读; 即使语法高亮显示,如果您不完全了解代码库,如果有全局函数和变量以及与全局变量同名的局部函数和变量,也很难得出所谓的东西。 当与属性一起使用时,开发人员往往会忘记,对属性的多次调用应缓存在局部变量中,因为在没有显式调用的情况下,他们只是不会将对属性的调用视为重复。 因此,我对所有人的建议是:不要使用快捷方式。 显式和重复数据删除代码,而不是在视觉上隐藏重复代码,而不在逻辑上隐藏它。 是的,像鸵鸟一样把头埋在沙子里,对您没有任何好处,因为属性不是万能的,无论您怎么想,它们可能或可能变得计算昂贵。 因此,为了排练,请明确: 就是这样,伙计们。 祝您有美好的一天,无论您身在何处,都要保持干燥。