Tag: 开源

为什么我写家庭框架

在Apple平台上构建应用程序时,开箱即用的是模型视图控制器模式。 尽管多年来引起了很多争议,但这种体系结构本身并没有什么坏处。 主要的抱怨是可怕的“ Massive View Controller”,这些年来,它还获得了许多其他同义词,例如哥斯拉控制器,View ConTROLLer,我可以继续说下去。 我分享了很长时间的观点,在其他几个模式中寻找一个穿着闪亮盔甲的骑士。 但是,他们全都走同一条路。 与系统作斗争,直到我迷路了,发现自己回到了Apple为您提供的服务。 看起来一切希望都已荡然无存,Dave DeLong发表了自己的四部分文章系列“更好的MVC”。 更好的MVC,第1部分:问题 “修复”模型视图控制器系列文章的第1部分:修复封装问题修复大规模视图控制器… davedelong.com 使灯泡发光的是第3部分。 我是一个常见的误解的受害者,因为误解是视图控制器需要负责整个屏幕。 一旦我学会了这种“反模式”,生活就变得像一千个太阳的火焰一样明亮。 我开始以不同的方式考虑控制器,并且我接受了子视图控制器。 作为iOS开发人员的生活开始重新变得有意义。 在继续之前,我只想弄清楚本文的目的。 这与流量控制器模式无关。 使用该模式仅暴露了我认为需要修复的情况。 我不认为流量控制器模式是最终的答案。 这是构建模块化,可扩展且可测试的控制器的一种好方法,甚至是一种很好的模式,对于我和我的同事来说,这都是很好的选择。 如果您想更多地了解该模式,则不是本文。 我建议您阅读戴夫的文章。 他解释得比以往任何时候都好。 继续前进,在使用了子视图控制器一段时间之后,我开始看到我的时间花在了哪里,主要是在必须快速适应变化的时候。 更精确地说,构建流量控制器比将多个控制器粘合在一起要麻烦得多。 我想使用Apple提供的所有可用的UI元素来构成我的用户界面,但是当任何需要出队的问题出现时,我很快就感到失望。 必须有更好的方法。 一种不涉及链式约束并且适应变化的方法。 就像过去的爆炸一样,我想到了Spots框架的核心实现,即SpotsScrollView 。 在该类中,我们使用了基于OLEContainerScrollView的Ole Begemanns实现的布局算法。 该算法开放用于在滚动视图内部使用滚动视图,从而为用户创建一致的滚动体验。 我以Spots算法为基础,重新审视了代码,并逐渐对其进行了改进,直到它可以与您喜欢的任何UI元素按预期方式工作,而无需配置单个约束。 在为框架破解公共API时,我希望它尽可能精简。 我的目标是成为一个嵌入式解决方案,使设置子视图控制器变得像馅饼一样容易。 “公共API简洁明了,应该节省很多您想花在其他地方的时间……” 我想出了三种方法,一种用于添加常规子视图控制器,该子视图控制器处理内部调用所有适当的子视图控制器相关方法。 对于需要将控制器(或更确切地说,其视图)限制为特定高度的情况,我又添加了一个。 最后但并非最不重要的一点是,我添加了一个带有闭包的方法来选择与标准UIViewController的视图不同的视图。 这些是当今存在的公共API方法,以与添加视图时相同的线性垂直顺序排列视图,而子视图控制器由框架内部掩盖和处理。 如果视图在任何时间点都应更改,则算法将相应地对视图进行布局。 另外,我实现了对动画的支持,如果通过使用动画将视图的高度设置为零来删除视图,则框架将确定动画的持续时间,并在布置视图的新位置时采用动画。 这样,它尊重用户的意愿,而无需他们做任何额外的工作。 那么关于出队的事情呢,因为该实现植根于Spots框架,该算法已经考虑到了这一点,这意味着您可以自由地混合和匹配集合视图,表视图,堆栈视图,分段控件和常规UIView ‘ s。 Family框架仍处于起步阶段,但是我看到它的前途光明,因为它的责任很轻,公共API简洁明了,应该可以节省很多您想花在其他地方的时间,最好是与人类家庭在一起。 因此,事不宜迟,我给你一个家庭友好的儿童视图控制器框架:家庭。 希望您能像我一样喜欢它! […]

投资定制开发

随着INVASIVECODE推出SignaKit,我们想解释为什么您应该投资定制的代码。 SignaKit是一个高级iOS框架,可帮助您创建手写签名并将其添加到PDF文档中。 SignaKit是您需要付费的代码,并提供所需的支持,以确保它在将来的Apple更新中仍然有效。 开发应用程序时,您可以选择使用第三方代码和开源库,也可以创建自定义的构建代码。 使用开源代码看似简单,高效且具有成本效益,但是您可能需要考虑使用这些含义。 从长远来看,这实际上可能会花费您更多的金钱和时间。 随着每个Apple iOS过渡,更新iOS应用程序变得至关重要。 更新提供了机会,包括企业优化其应用程序的功能和美观性的机会,开发人员利用新技术和工具的机会以及吸引对利用最新平台感到兴奋的用户的机会。 很容易想到:我的应用程序现在运行流畅,因此可以轻松过渡到下一个iOS版本。 Apple提供了轻松转换代码的工具和平台。 可以重做图形,并且该应用程序看起来已经过完全重新设计。 但是大多数时候,您尚未编写的代码,一段代码或借来“修补”某种功能的库都会出现问题。 使用第三方代码和开放源代码库意味着相信其他开发人员的工作,并希望代码已经以完整性和标准编写。 但是,您应该考虑信任那些没有为编写的代码付费的开发人员,使他们免于承担全部责任:他们可能没有时间更新开源库,因为他们有一份付费的全职工作或他们的优先级可能已经改变。 或简单地说,他们可以编写或不编写质量代码,但是无论如何,您不能责怪他们,因为他们免费提供了代码! 当您的应用程序停止正常运行,或者在更糟的情况下,您的应用程序停止运行时,这将成为问题。 如果您没有与开发人员承担任何合同义务,则所使用的代码将由您自己承担。 为了理解开发过程,想象一下写一本书。 但是,编写本书时,不要自己写每个句子,而是想从其他作家那里借用每个句子。 此过程将节省您的时间。 从头开始写东西总是比从别人那里借书花费更多的时间和精力,并且基本上您要做的就是复制和重新配置。 但是,如果您必须在手稿上找到一个简单的错字,然后才能出版,那么您基本上是无助的,试图阅读和更正数千个未知的句子,最终无法出版您的书。 现在从应用程序开发以及更新iOS应用程序的实际情况来考虑这个问题。 在更新iOS应用时,Apple要求重新编译代码。 在重新编译过程中,Apple会检查应用程序是否存在错误,并确定它是否可以在新的OS版本上正常运行。 如果发现错误,则必须找到并修复。 如果您仍然希望进行更新(这对于保持相关性至关重要),则需要查找错误。 现在,发现错误似乎很简单。 作为编码员,错误是生活的一部分,发现并修复它们是我们的工作。 但是,如果该错误存在于由第三方编写的一段代码中,则开发人员将被迫花费大量时间和资源来浏览并修复其他人的工作,或者等待开发人员维护该代码修复它,可能会发生或可能不会发生,具体取决于开发人员的时间或关注点。 相反,购买SignaKit之类的定制代码将使您放心,当您可以请求快速,无缝地解决问题所需的支持时。 关键是,将代码片段放在一起看似更快,更容易启动,但要注意,随着技术的进步,您可能会遇到很多麻烦。 因此,内部编写本机iOS应用程序以及了解应用程序构成的重要性。 尽管第三方开源代码允许开发人员在短期内加快开发过程并节省资金,但其风险要比许多人希望的高得多。 产品的成功,无论是汽车应用还是移动应用,都取决于寿命。 如果一个小问题导致产品无用,那么就不可能说该产品具有任何实际价值。 尽管开放源代码的使用非常普遍,但是请考虑为在出现问题时提供支持的代码付费。 事实是,与包含第三方代码的应用程序相比,从头编写的iOS应用程序具有更大的价值,并且更易于维护。 有关SignaKit的更多信息,请访问iNVASIVECODE网站。 —伊娃·迪亚兹·桑塔纳(Eva Diaz-Santana) 她是InvasiveCode的共同创始人,从2008年开始开发iOS应用程序并教授iOS开发。她还曾在Apple担任Cocoa Architect和UX设计师。

为iOS打开Sourcing ReactiveLists

在过去的几年中,PlanGrid iOS团队构建了许多内部API,使我们能够更快,更一致地发布新功能。 今天,我们将公开发布第一个组件-您现在可以在GitHub🎉上找到它。 我们的团队有许多开放源代码爱好者,并且我们还使用了大量开放源代码库,因此我们一直计划随着时间的推移发布这些组件。 使用UIKit进行声明式UI编程 ReactiveLists是一个类似React的API,建立在UITableView和UICollectionView 。 该API使我们能够编写无状态函数来生成用户界面。 根据我们的经验,这些无状态函数比*DataSource和*Delegate类型更容易理解,后者是向UIKit组件提供数据的标准模式。 API的用法通常类似于下面的示例,您编写了一个将数据映射到ReactiveLists视图模型的函数,从而产生了一个非常易读的无状态函数: 这不仅使UI代码易于阅读和迭代,而且使其易于测试。 我们的团队成员Benjamin Encz在他的演讲“将UIKit内外翻”中深入讨论了这种声明性UI编程方法的优势。 从封闭到开放 我们团队中有很多人为开源项目做出了贡献,或者从头开始创建了自己的项目。 事实证明,将在现有代码库中演化的组件开放源代码采购的经验大不相同。 我们花了几天的工程时间将组件移至其自己的Swift框架中,删除了对核心应用及其单元测试助手的依赖,将ReactiveSwift集成移至扩展中,并花费大量时间重命名API,改进文档和重构了测试套件。 最重要的是,我们构建了一个示例应用程序,使该库更易于理解。 这是开放构建的另一个好处-它提高了在我们代码库的大部分中使用的组件的数量。 准备生产,但不准备1.0.0 我们没有等到该库完成后才将其发布给公众,因为我们相信它在当前状态下会增加很多价值。 我们发布的版本是已经在PlanGrid iOS应用程序中发布了近两年的版本。 因此,我们绝对认为该库可用于生产。 也就是说,我们期待大量改进,并且API不断变化,因此将此版本发布为0.1.0 。 结论 我们认为这是与iOS社区共享一些内部API的第一步。 我们每天都看到利用开源软件的好处,并且很高兴能够做出贡献。

内部来源

这有什么不同? 在Impala Studios,我们从拥有共享维护权的两个团队待办事项到通常由模块化和微服务件组成的包含我们所有产品的单个待办事项。 您会看到我们的产品由应用程序,框架,第三方模块和后端服务组成。 每个模块都可以设置为特定产品。 例如,Alarm Clock HD的iOS应用程序内部具有Alarm Clock Framework。 它使用多个SDK和3rd Party模块在应用程序营销和新闻中显示广告,收集数据,并使用我们自己的气象服务来获取新气象。 在我们当前的设置中,整个应用都有一个监护人和一个产品负责人,但是没有一个模块具有特定的所有权。 基本上每个人都拥有内部维护的代码,没有人拥有由外部各方维护的代码。 由于集成产品由其每个模块(不断更新)的最新版本组成,因此创建了相当复杂的依赖关系集。 随着模块的更新,诸如App之类的集成产品将会崩溃。 我们通常也不知道有没有损坏,因为应用程序中的大多数集成都不受自动化测试的影响。 当前,查看已经存在于存储库中一段时间​​的App是否仍然有效的唯一方法是制作和测试当前版本,然后修复发现的内容。 借助Innersourcing,Alarm Clock HD将拥有一个“所有者”(即产品所有者),但是监护权现在将进入每个模块。 现在,团队将负责团队中具有监护人的所有模块。 每个人仍然可以更改这些模块,但是拥有该模块监护权的团队拥有最终批准权。 监护团队确保它使用自己的模块(例如Cocoapods)的依赖处理程序来制作其模块的新版本,然后可用于新版本。 从例子中学习 Google — 20亿行代码 使用内部外包的单个产品的最大示例可能是Google的实现。 Google的所有25,000名工程师都可以在一个存储库中访问几乎所有20亿行代码! 我们可以从Google中学到的东西: 他们将代码保存在团队拥有的“目录”中。 除目录外,任何开发人员都可以进行任何更改,您的更改必须经过所有者的批准。 分支-它们具有“基于主干”或“发布分支”的模型。 尽可能晚地制作master分支的快照,并在此基础上开发新功能。 如果主服务器上已更新了开发所需的内容,则可以将其“放入樱桃”到发行分支中(由于其大小,他们甚至没有选择与主分支保持同步)。 发布分支是生产的基础。 我们可以考虑使用GitLab Flow,当然也可以考虑使用CocoaPods冻结版本。 它们具有每次提交时运行的单元测试的代码覆盖率。 他们使用拉取请求和自动部署进行代码检查。 贝宝(Paypal)-开源和内部源之间的优势 有许多公司一直活跃在开源社区中,而不是从专有或内部源码,甚至是开源方面发生变化的公司。 Google和Facebook在开放源代码许可下拥有部分代码,Apache基金会和Ubuntu / Canonical拥有完全基于社区的软件。 Paypal是后来者,但自2014年初以来,他们在kraken.js项目上开始从Java过渡到JavaScript和Node.js时,就采用了Inner Source。 他们注意到,要为许多项目做出贡献,就必须采用一种新的工作方式。 一个重要的变化是迁移到GitHub和使用Git。 另一个是就质量标准达成共识,例如单元测试。 最后,他们注意到开放源代码贡献者的工作是分散的,而他们正在迁移到同一地点的团队。 面对面交流的缺点是,对于不了解该软件的人而言,没有文档记录,他们必须学习使用readme.txt,changelog.txt并在git中进行文明的在线公开讨论注释。 由于kraken.js是开源的,因此与外部贡献者的通信在某种程度上迫使了这一点。 O’Reilly上提供了对Paypal内源的深入了解。 […]

为我们的iOS 360视频库开放源代码:DDDKit

https://github.com/team-pie/dddkit 在Pie,我们正在开放资源库以显示360个视频。 自2016年11月推出以来,我们一直在我们的应用程序中使用它,对我们来说一直很好。 因此,我们很高兴将其开放给他人使用,从中获得启发,并提出更改和贡献的建议! 现在可以作为可可豆荚使用: pod ‘DDDKit’ 我们的重点是360视频,360图像和滤镜。 因此,我们设计了DDDKit来简化这些部分。 用法 DDD360VideoViewController 这是一个预烘焙的便捷视图控制器,可以处理大多数逻辑,以便您快速入门。 当您对此更加认真时,您将需要在DDDKit中进行更深入的研究: 我们希望为他们提供超级简单的支持,而又不会失去我们可以创建的所有过滤器范围。 因此,我们将它们留在了着色器程序级别,但受SceneKit的着色器修改器的启发,使它成为易于使用的API 还记得着色器代码吗? 这里有两条注释行// header modifier here和// body modifier here它们是我们可以插入的代码块的占位符。 为了做一个简单的黑白过滤器,我们将程序定义替换为: 完整的代码在这里。 为什么不使用SceneKit? SceneKit是Apple的3D渲染框架。 它具有广泛的关注点,并且在很多方面都非常强大且设计合理。 但是,我们决定建立自己的替代产品,因为: SceneKit在iOS 10.0中引入了内存泄漏 对视频的支持不是自然的,而是通过Apple的2d渲染框架SpriteKit完成的。 我们发现SceneKit的在线文档在与视频和着色器修改器相关的功能方面非常差。 当您遇到问题时,没有代码需要看,只有一个很小的SO社区可以使用,也没有人及时响应您的错误报告。 苹果!=开源! 我们的关注点小于SceneKit的关注点,我们认为我们可以在更严格的范围内提供更好的解决方案。 期待 我们想到了以下几点: 完善我们自己的文档。 调查金属支持 添加单元测试 你怎么能帮忙 使用DDDKit,打开带有错误和建议的问题。 我们会及时回应。 让我们知道您如何使用或计划使用DDDKit以及是否缺少某些功能。 给我们一颗星星 !

自学成才的软件开发人员:为什么开源对我们很重要

这是一个关于我对开源的看法如何随时间变化以及如何对我的职业生涯产生帮助的故事。 开源简介 大约13年前(在高中时),一个朋友(Netcyrax)向我介绍了开源社区。 他向我介绍了有关开放源代码及其运行方式的所有内容。 然后,他给了我一张Ubuntu CD,并告诉我Ubuntu正在通过发送免费副本来推广其操作系统。 第二天,我使用56k连接访问了www.ubuntu.com,并订购了50份Ubuntu。 我的意图是将它们出售给其他人,而不是免费提供。 那是15岁的我,我不了解开放源代码的目的。 无法理解目的 然后我开始编程。 我已经知道了开源,但实际上我不明白为什么我必须共享我的宝贵代码行。 为什么免费共享我花了几个月时间开发的程序源代码? 如果有人偷了怎么办? 如果我的“竞争对手”使用我的源代码来改进他们的产品怎么办? 当时我不明白的是,我不是一名杰出的软件开发人员,我的程序可以由经验丰富的软件开发人员在几天之内(而不是几个月)从头开始开发。 使用开源库很方便 是2008年,我有了第一部iPhone(3G)。 苹果宣布推出iOS 2和iOS SDK。 我决定(在业余时间)成为一名iOS开发人员。 由于还没有人使用过iOS SDK,因此我不得不自己学习开发应用程序。 我使用WebView创建了一个简单的应用程序,并且业务逻辑在使用JavaScript构建的Web应用程序内部。 我对iOS SDK感到非常失望(菜鸟开发人员+ Objective-C +手动引用计数=灾难),因此我暂停了本机iOS开发两年。 同时,我正在试验混合的SDK,例如Titanium,Adobe Air-ActionScript。 当我回到iOS 5(回到本机)时,一切都不同了。 在大约一个月的时间里,我设法构建了第一个真实的应用程序并将其上传到App Store。 但是发生了什么变化(自动引用计数除外)? 答 :iOS开发的开源社区。 ASIHTTPRequest(用于网络请求)和SDWebImage(用于下载和缓存图像)帮助我构建了第一个应用程序。 版本控制和GitHub 大多数开源项目和库都托管在Github上。 所以我当时使用Github下载我的库,但是由于我是在业余时间编程的,并且没有商业环境的经验,所以我不能说Git和Github之间的区别。 在构建了一些iOS应用之后,我对自己的技能充满信心,因此我决定申请iOS机会。 在第一次面试中的某个时刻: -访者:您使用什么版本控制? 我是什么意思版本控制? -访者:我的意思是您如何保留代码库的版本? SVN? 吉特? -Me:时间机器(OS X的备份软件)! 因此,在与访问者进行了交谈之后,我决定我想了解更多有关Git(以及一般而言的版本控制)的知识,并希望在自己的项目中使用它。 我阅读了很多有关Git的文章,以及如何在团队中使用它。 我学会了在BitBucket存储库中使用“提交”和“推送”。 我将其用作代码的备份和版本控制,但不用作协作工具。 […]

在iOS项目上使用Travis-CI和Fastlane设置CI

持续集成(CI)是一种很棒的软件工程实践。 它要求开发人员在每次提交之后频繁提交。 这样,可以自动运行测试,计算覆盖率,执行静态代码分析等,以确保每次提交都不会破坏构建过程并且不会带来副作用。 如果提交破坏了构建,则进行更改的人员将收到一封电子邮件,需要检查并修复构建。 通常,在构建结束时,会创建一个测试版本。 通常,这就是过程,但是各个公司的过程可能有所不同。 这种工作流程的好处来自频繁的集成-您很快就会发现问题所在,并有机会快速进行修复。 团队越大,拥有这样的自动化集成过程就越重要,因为在每次提交之后,都有可能破坏代码库。 在本文中,我们将使用Travis CI和Fastlane为一个开源iOS项目设置CI。 目标是在GitHub存储库上的每次提交上运行CI,并在自述文件部分中显示有关构建状态和覆盖率的信息。 实作 特拉维斯CI 首先,您需要在GitHub上拥有一个带有单元测试的开源iOS项目。 在这篇文章中,我将与即将发布的iOS框架GirdersSwift合作。 第一步是通过单击“使用GitHub登录”按钮将GitHub帐户连接到Travis CI。 系统将要求您提供对Travis CI的某些权限,以使他们能够访问您的开源存储库。 Travis CI对于开源项目是免费的,但是对于商业项目也有一些付费计划。 成功注册Travis CI后,您应该在仪表板中看到所有项目。 找到您要为其添加配置项的配置项,然后启用绿色开关。 这就是我们目前在Travis CI上需要做的所有事情。 有了这个小的更改,我们已经告诉Travis CI,它应该为GirdersSwift回购运行连续构建,但是我们仍然没有告诉它该怎么做。 Travis CI不知道它是iOS,Android,Java还是其他类型的项目。 它还不知道是否应该运行测试,计算覆盖率等等。 我们通过在GitHub项目的根目录下创建.travis.yml文件来提供此信息。 让我们看看这个文件应该包含什么。 osx_image:xcode9.3 语言:迅捷 脚本: – fastlane ios覆盖率 如您所见,我们告诉Travis CI,它应该使用Xcode 9.3运行构建,并且语言是Swift。 在脚本部分,我们提供了每次构建后都需要执行的步骤。 在这里,我们使用Fastlane进行测试和覆盖。 快车道 Fastlane是一个出色的工具,可以自动完成与iOS开发相关的所有繁琐工作,从测试,构建,创建发行版到部署到商店。 它基于在Fastfile中定义的通道的概念。 您可以在一个泳道中定义几个动作,并且已经开发了动作,这些动作是我们iOS工程师最需要的。 通过在项目的根目录中键入fastlane init ,为项目启用fastlane。 您也可以输入您的开发者帐户信息,但这不是必需的。 这将创建一个Fastlane目录,其中包含Fastfile。 现在,让我们定义我们的覆盖范围,它将用于执行连续构建。 default_platform:ios […]

轻松将Unsplash搜索添加到您的iOS应用中

两个月前,我们共享了第一个iOS开源组件。 正如我随后解释的那样,我们在移动设备上开源的策略是提供易于集成的本机UI组件,而不是标准的API包装器。 UnsplashImageView是开胃菜,现在成为UnsplashPhotoPicker 。 这个新组件使应用程序可以轻松地从Unsplash库搜索和下载照片。 只需几行代码,应用程序便可以为用户提供精美的高质量照片,从而开辟了全新的移动用例。 一些例子: 假设您是一个博客平台,希望允许其用户将Unsplash中的照片插入其博客文章中,此组件将使您的生活变得轻松。 (中😉) 或者,您可以成为一个项目管理工具,向其用户提供更改其项目背景的工具。 (Trello😉) 哦! 您是一项可帮助人们建立网站的服务,如何让他们使用其主页上Unsplash的高质量照片呢? (平方😉) 或者,也许您是一个专门制作演示文稿的应用程序,并希望您的用户将精美的摄影作品插入其精美的套牌中? 我们有你覆盖。 (苹果😉) 在使用它之前,您需要获得Unsplash API访问权限和秘密密钥。 访问我们的Unsplash API页面,以注册为开发人员以获取更多信息。 UnsplashPhotoPicker是UIViewController的子类,并且很容易配置: 要检索选定的照片,请实现UnsplashPhotoPickerDelegate协议: 而已! 您可以使用更多选项来配置照片选择器。 并查看UnsplashPhoto.swift以查看返回的信息。 您可以在Github上找到该项目:https://github.com/unsplash/unsplash-photopicker-ios 如果您有任何反馈或问题,请随时通过apps@unsplash.com发送电子邮件。 并让我们知道您是否在项目中使用它。 Android即将推出。

iOS版Firefox Focus中的错误修复

大多数浏览器上的“私人浏览”并不全面,也不易于使用。 焦点是免费的,永远存在且始终在您身边的下一个级别的隐私-因为它得到了Mozilla的支持,Mozilla是为您的Web权利而战的非营利组织。 (摘自App Store中的应用说明) 它的功能之一是,如果您不想从Safari切换,仍然可以在Safari中使用Firefox Focus功能(请按照以下步骤操作)。 虫❌ 问题在于,使用前后导航后,URL栏中的搜索文本与实际搜索不匹配。 让我们来看一个例子: 搜索“监护人” 搜索“ mozilla” 按回 搜索“ firefox” 按回 搜索页面显示 “监护人”请求的结果,但URL栏包含“ mozilla”而不是“监护人”。 修复🔧 问题的作者在那里留下了注释,表明该问题可能存在于SearchHistoryUtils堆栈中。 它帮助我开始了对该问题的调查。 我找到了SearchHistoryUtils类,其中包含两个布尔属性。 isFromURLBar isNavigating 和四个功能: pushSearchToStack(with searchedText: String) —当用户发出新的搜索请求时,此函数将搜索推入堆栈。 pullSearchFromStack() -> String? —此函数不会从堆栈中弹出搜索,而是返回当前搜索文本(如果存在)的值。 goForward() —更新堆栈对象的isCurrentSearch值。 goBack() -与#3相同 当我分析代码时,我取消了pullSearchFromStack , goForward和goBack函数,因为它们并未真正处理堆栈更改。 因此,我开始调试pushSearchToStack函数。 我调试了几个测试用例,然后让我们看一下我的发现。 因此,我几乎重现了问题中描述的错误,然后发现了问题: 当最后一个搜索不是当前搜索(例如,在执行第一个“返回”用户操作后的堆栈中),并且用户进行了新搜索时,最后一个搜索不会被新搜索覆盖(请查看上表中的红线) )。 这就是为什么当用户返回时,URL Bar会采用旧的搜索文本,那时候甚至不应该将其放在堆栈中。 让我们看一下pushSearchToStack函数的一部分伪代码: 让我们分解上面的代码: 它声明一个空堆栈currentStack 。 它将currentStack的值设置为全局状态searchedHistory值的值。 然后,它遍历堆栈中的每个搜索,并将isCurrentSearch属性的值设置为false 。 […]

适用于iOS的加密和开源应用

以下是iOS平台的应用程序列表,这些应用程序不仅具有客户端加密功能,而且还具有开源功能。 我觉得您可以拥有一个。 通过使应用程序开源,除了编码本身,没有其他人可以信任,因此是一种很好的选择,可以使我们的数据不受他人的控制。 当我在iPhone上找到各种股票应用的替代产品时,我将更新此列表。 现在还添加了指向App Store中应用程序下载的直接链接。 注释 :progenius标准注释 消息传递 :Wire — Wire Swiss GMBH的私人信使 存储 :Cryptomator — Skymatic UG的云存储加密 密码 管理 :主密码•••| —免疫损失。 由Lhunath SSH 密钥 存储 / 登录 :Kryptonite —由KryptCo,Inc.保护您的SSH私钥。