前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何在iOS中构建模块化架构

如何在iOS中构建模块化架构

原创
作者头像
会写bug的程序员
修改2020-06-12 14:48:28
2.4K0
修改2020-06-12 14:48:28
举报
文章被收录于专栏:iOS面试

随着时间的推移,任何代码库都会随着项目的发展和成熟而增长。它为开发人员带来了两个主要限制:如何使代码井井有条,同时保持构建时间尽可能短。让我们看看模块化体系结构如何解决该问题

xcode库
xcode库

模组

模块开始,我们可以将其表示为与其他主应用程序隔离的代码资源。然后,将其作为依赖项添加到我们的iOS应用中。

创建模块还可以大大提高代码的可测试性和可重用性。

这种依赖关系可以是应用程序的技术方面(网络,存储等),也可以是功能(搜索,帐户等)来封装复杂性。

定义后,我们就可以开始添加要隔离的代码和资源。

打包代码的方式只有两种:动态框架静态库

两者之间的主要区别在于它们在最终可执行文件中的导入方式。静态库包含在编译类型中,可在可执行文件中进行复制,动态库在可执行文件的运行时包含在其中,而从不复制,因此启动时间更快。

创建一个模块

现在我们知道了什么可以成为模块,让我们创建一个。假设我们为电子商务创建了一个新应用程序,则需要创建一个特定的依赖项,以表示我们应用程序的核心概念。我称它为Core

首先,我创建一个动态框架项目。

模块动态框架
模块动态框架

由于它是一个电子商务应用程序,因此我们应用程序的核心是由我们销售的产品代表的。让我们为此创建一个简单的对象。

代码语言:txt
复制
public struct Product {
    let name: String
    let price: Double
}

由于我们的用户想要浏览产品,因此我们需要一种获取产品的方法。让我们创建一个协议来公开这一点。

代码语言:txt
复制
public protocol ProductServiceProtocol {
    func getAllProducts() -> [Product]
}

public final class ProductService: ProductServiceProtocol {
    public init() { }

    public func getAllProducts() -> [Product] {

        // imagine we fetch products from server
        let products = [Product(name: "shoe", price: 100), Product(name: "t-shirt", price: 30)]

        return products
    }
}

请注意,我们需要定义initpublic,否则internal默认情况下为,这使得它无法从其他导入中使用。

我们的模块已经准备好,让我们将其导入到应用中。

导入模块

创建依赖项后,我们可以将其包含到我们的应用程序中。对于这一部分,我首先创建了一个工作区,这使得一次处理两个项目变得更加容易。

我向工作区以及我的核心模块添加了一个应用程序。它们尚未链接。

为了在应用程序中导入Core框架并能够使用它,我只将框架文件拖放到主应用程序的部分中。Linked Framework and Libraries

模块应用
模块应用

如果构建主应用程序,则可以看到Core也是其中的一部分。太好了,我现在可以使用它。

模块应用程序构建
模块应用程序构建

通过一个非常简单的示例,让我们看看是否可以在主应用程序中获取产品。

代码语言:txt
复制
import Core

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let products = ProductService().getAllProducts()
        print(products)
    }
}

无警告,控制台按预期记录结果。

代码语言:txt
复制
[Core.Product(name: "shoe", price: 100.0), Core.Product(name: "t-shirt", price: 30.0)]

等等,但是我有很多依赖关系,有些相互联系,我该如何处理它们?

有了更多的模块和依赖项,接下来的问题显然是如何管理它们。让我们来看一些依赖管理器。

依赖经理

为了处理越来越多的依赖关系,我们需要一些方法来对它们进行分组和管理。

让我们从没有依赖项管理器的方法开始幼稚,所有代码在同一项目下的一个仓库中。

嵌入式应用
嵌入式应用

如果它非常适合小型应用程序,那么如果您拥有一个或两个以上的模块,它很快就会变得令人头疼。文件夹将无助于分隔。

进一步采用这种方法,下一步将是在一个工作空间中分离项目。这就是上面演示的解决方案。这是隔离代码并了解代码的可见性和责任的好方法。

模块应用
模块应用

但是,它仍然在同一个git repo下。当项目要扩展时,回购可能会变得很拥挤。还要考虑构建时间:每个依赖项都是使用主应用程序重建的。

让我们尝试分离git repo并使用git子模块。已经更好了,代码可以在其他项目中重用,但是我们仍然受到构建时间的限制。

处理依赖关系的另一个角度是创建一个伞形框架,以将每个依赖关系嵌入到一个程序包中,以限制构建并保持整洁的工作空间。 事实是,如果您使用CocoaPods,您可能已经做到了

如果您查看工作空间并探索Pods项目,它就是处理依赖项的方式。但是,构建时间仍然是瓶颈。

最后,另一个流行的依赖性管理器是Carthage。主要区别在于依赖项是在导入之前构建的。这是保持优化构建的最佳解决方案。

我没有提到Swift Package Manager(或SPM),因为到目前为止它仅可用于macOS。

它们也是Buck或Bazel等其他用于增量构建的新兴解决方案,但这首先要针对连续集成管道。


总之,我们了解了如何将代码隔离到模块中,使其在保持整洁的项目的同时易于重用和测试。可以在此处找到带有模块的示例项目。

加微信 一起来交流

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 模组
  • 创建一个模块
  • 导入模块
  • 依赖经理
  • 加微信 一起来交流
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档