无畏和高效地使用第三方iOS框架

当我开始职业生涯时,我在一家不允许使用第三方框架的公司里工作。

我们必须从头开始编写所有功能,以使其可以在其他项目中作为我们自己的内部框架重用的方式来构建它们。

这是一个奇怪的政策,但它可能是我作为软件开发人员曾经遇到的最好的学习工具之一。 而且,如果您认为从头开始编写功能不可行,我可以向您保证。 尽管进行了额外的工作,我们始终设法按时交付,并且该业务是可盈利的。

也就是说,我完全理解了这种情况无法承受的情况。 实际上,在我的另一项工作中,该协议正好相反:如果有一个第三方框架可以完成我们不希望使用的功能,那么我们会因浪费时间和资源进行重新发明而受到谴责。车轮。

那也是一个很奇怪的政策,但是我从使用第三方框架中学到了很多-这样做使我可以接触到其他人的代码,这反过来又为我提供了很多额外的知识和经验。 我记得那时起有那么多aha时刻。

在我的职业生涯中经历过两次极端时,我发现在两者之间取得平衡通常会给我带来更好的工作成果。

一方面,我坚信自己做事是最好的学习方法,并且从零开始编写一切都教会了我如何构建框架,可重用的模块化代码,良好的API等。 它促使我学习如何有效地编码并解决任何问题,尤其是在我的职业生涯早期,学习曲线陡峭的时候。

另一方面,选择使用第三方框架可以帮助我快速创建高质量的解决方案,使我能够向世界各地经验丰富的开发人员学习,并在遇到软件开发方面的不同见解时提高了自己的技能。

这两种工作方式都非常有价值,我希望每个开发人员也有机会体验它们。

当然,并不是每个人都可以自由地从头开始编写自己的工作,在这种情况下,通过附带项目进行尝试通常是学习的好方法。 这正是我所做的。

早在2009年,作为学习如何编写iOS应用程序的练习,我为网络和JSON,XML和HTML解析器编写了所有Objective-C实现。

为了持久性,我编写了SQLite和Core Data包装器。 我什至编写了自己的基于文本的文件存储方案,这听起来很愚蠢,但这是解决许多问题的简单方法,最终使我的客户满意。

我们非常习惯使用已知技术,以至于我们常常忘记像Core Data这样的框架在很多情况下是过大的,而自定义解决方案更便宜,构建和维护也更快。

明确地说,我还不时使用Core Data,它为更复杂的项目提供了巨大的价值。 例如,即使在过去我曾经在iPod Touch(第3代)上测试应用程序的过去,它也有助于保持较低的内存占用并保持响应式UI线程。 使用定制解决方案来做这些事情将是困难且昂贵的,尤其是在处理大量数据时。

那么,您如何在这两个极端之间找到平衡?

每次从头开始编写都是很浪费的,但是编写模块并在项目领域中重用它们是一个不错的选择,尤其是在学习时。

同时,忽略第三方框架也很浪费,这样做可能会导致您面临许多在其他人的项目中已经解决和验证的挑战。

但…

还记得解析吗? 我做。

我们很难宣布。 从今天开始,我们将关闭Parse服务,经过长达一年的时间(截至2017年1月28日),Parse将完全退休。我们很自豪能够帮助如此多的人构建出色的移动应用程序,对此我们感到很自豪,但我们需要将资源集中在其他地方。 —来自他们的 博客

解析“继续前进”,但是他们的客户继续前进又有多容易呢?

我敢肯定,你们中的许多人都受到Parse关闭的影响,这很可能是关于过多依赖第三方服务的重要教训。

但这并不总是必须像关闭服务那样极端。 例如,当您使用的服务仍然存在但不再满足您的需求时会发生什么?

长期以来,我最喜欢的REST应用程序入门框架是RestKit-与其说是REST方面,不如说是它的主要功能,而是它强大的映射框架,它允许我从JSON / XML源创建应用程序域模型而无需将该责任泄露给模型类。

我希望我可以只使用框架的那部分,但是它的体系结构使得很难分开。

令我感到奇怪的是,我无法创建自己的客户端实现,因为RestKit的许多类都在子类化AFNetworking组件(它是建立在AFNetworking 1.x之上的),因此该项目完全依赖于AFNetworking。 即使这样,我还是决定接受这些缺点并将其用于网络层。

尽管我决定仍然使用它来节省很多开发时间,但我将其隐藏在一个不会泄漏对我的应用程序依赖关系的协议后面。

我的应用程序仅使用API​​协议,并且期望返回不从Core Data,RestKit或任何框架依赖项继承的应用程序域模型。 这使得应用程序极其易于编写和编写,维护和测试,而且轻巧。

然后是苹果推出NSURLSession的那一天,而我正在从事的项目之一需要一些新功能,例如后台下载。

RestKit社区开始了有关如何移植其客户端体系结构以支持此操作的漫长讨论,但截至目前,它尚未完成。 AFNetworking 2.x以NSURLSession为核心发布,似乎可以解决RestKit的问题,但是由于涉及所有重大更改,因此很难切换到新版本。

幸运的是,由于我拥有自己的体系结构,因此很容易将客户的项目迁移到新的网络实现中。

而且,您是否会知道,过渡很容易且没有回归。 没有。 零。

我觉得那很了不起。

RestKit的错误是在没有适当分离关注点的情况下混合了太多的责任,因此付出了代价。 下图显示了可以节省RestKit的网络层的建议体系结构。

(要清楚,我过去也做过同样的事情,我也付出了代价。可以肯定的是,我第二天会分享更多有关此事的信息,以便您可以从我的错误中学习。)

诸如Parse和RestKit之类的故事强化了模块化方法的重要性,以及我们作为专业人员必须如何不断地意识到这一点。 对我来说,这种方法不再是问题,而是我对客户和我本人的责任。

如果您想知道从哪里开始采用模块化方法,建议您从小处着手,以便在大规模使用之前先熟悉一下该想法。 定义协议以区分域问题的职责,并首先编写自己的实现。 在适当的时候,选择一个好的第三方框架并将其隐藏在您的协议后面,以便您可以分别开发,维护,测试和部署它们。 通过这种方法,可以轻松地将实现与新的实现互换,并使模块可重用。

您也可以将精力集中在重构一个模块(我们都有一个)上,这将大大降低您的生产率并引起很多麻烦。 也尝试使用该设置添加一些测试。 您会很快发现它会多么令人愉快。

这样会花费更多时间吗? 似乎是这样。 但是,根据我自己的经验,更容易适应变化。 它使您可以通过分担责任与同行进行协作,而不会互相妨碍。 并且许多代码可在同一域中的许多其他应用程序中重用,从而使其超级灵活,可在macOS和tvOS等不同平台上进行部署。

业务需求总是在变化,开发人员通常会担心这些变化。 他们了解变化的风险,但往往找不到方法来保护自己不受变化的影响。

看一下您现在正在工作的项目,找到易受攻击的相关部分。 您可以轻松地交换它们吗? 您可以独立开发,维护,测试和部署它们吗?

两者之间存在差距,并且存在巨大的机会来创造价值并将您的职业提升到新的水平。 帮助您创建模块化和解耦组件的母带处理技术是关键,我们将在以后的博客文章中进一步讨论。