介绍AppFolder

每个iOS应用程序都有一个关联的容器,作为开发人员,您可以在其中基本上存储所需的任何内容。 这通常称为“沙盒”。 在此沙箱中,您可以放置​​用于不同目的的文件-它可以是用户可见的文档,数据库文件,缓存或某种元数据-任何东西。 基本上,iOS上的所有持久性技术都使用应用程序的容器在其中存储信息。 因此,了解应用程序文件夹的外观,结构以及放置在其中的文件对于每个iOS开发人员都是至关重要的。 但是,这里存在问题:

不幸的是,对于每个iOS应用程序都至关重要的概念,Apple并未对其API进行过多考虑

因此,例如,如果您需要获取应用程序的“ Documents”文件夹URL,则需要编写以下代码:

  let urls = FileManager.default.urls(for:.documentDirectory,in:.userDomainMask) 
让documentsURL = urls [0]

如果您确切知道该代码在做什么,那可能看起来还不错。

但是对于不习惯此API的人来说,它看起来也很恐怖。 因为当您尝试使用自动完成功能来发现您的选项时,会得到以下信息:

在这种情况下,有人会怀疑“这里到底发生了什么?”。 .adminApplicationDirectory.applicationScriptsDirectory.moviesDirectory.trashDirectory吗? 有很多东西,其中大多数对于iOS应用程序绝对没有任何意义

然后是搜索路径域掩码:

…嗯, 是的,确切知道该选择哪一个。

这个API对于macOS可以说是合理的,但是在iOS上,这显然是令人误解的:

  • cachesDirectory放置在musicDirectorydesktopDirectory (显然,这不仅对每个设备而言都是唯一的,而且对于iOS而言也是荒谬的)。
  • 由于某种原因,“ Documents / ”目录表示为.documentDirectory (单数),这可能使您质疑是否选择了正确的文件夹。
  • 它返回一个URL 数组 (可以有多个URL吗?可以没有一个吗?谁知道。)
  • 最后,使用此API,您几乎不了解文件夹在磁盘上的实际结构。 尚不清楚此巨型列表中的哪个文件夹甚至存在,哪些不存在。

我们可以做得更好

好吧,想象一下我们是否可以交易上面的代码

  let urls = FileManager.default.urls(for:.documentDirectory,in:.userDomainMask) 
让documentsURL = urls [0]

对于这样的事情

 让documentsURL = AppFolder.Documents.url 

还利用了Xcode自动补全功能:

会不会很好?

好吧,这正是AppFolder的用途:

dreymonde / AppFolder
AppFolder –🗂切勿再次使用NSSearchPathForDirectoriesInDomains。 决不。 github.com

AppFolder是一个很小的库,可通过代码可视化您应用的文件夹结构 您可以轻松访问系统定义的目录,如下所示:

 让文档= AppFolder.Documents 
让tmp = AppFolder.tmp
让applicationSupport = AppFolder.Library.Application_Support
让缓存= AppFolder.Library.Caches
 让cachesURL = caches.url 

一切的布局都与磁盘上的布局完全相同 。 这样,与磁盘相关的操作就更加直观:

 让cachesURL = AppFolder.Library.Caches.url 
让userCacheURL = cachesURL.appendingPathComponent(“ user-cache.json”)
让userCacheData =试试数据(contentsOf:userCacheURL)

AppFolder旨在让开发人员在应用程序的容器内描述其完整的文件夹结构,包括他们自己创建的目录:

 扩展文件{ 

期末照片:目录{}

var照片:照片{
返回子目录()
}

}

就像这样,新创建的文件夹现在可以像其他文件夹一样对待

 让照片= AppFolder.Documents.Photos.url 

该目录的名称将自动生成,因此子路径将类似于“ Documents / Photos /”

继承的黑暗力量

AppFolder是使用Swift功能构建的,该功能如今经常被忽略-继承。 您可能会注意到,每个目录都是Directory的强类型子目录。 Swift的嵌套类型和扩展使我们能够以最自然的方式来构造代码。 例如,这是Library的实现方式:

 公共最终班图书馆:目录{ 

公共最终课程缓存:目录{}
公共变量缓存:缓存{
返回子目录()
}

公共最终课程Application_Support:目录{}
公共变量Application_Support:Application_Support {
返回子目录()
}

}

从字面上看, Documents实现只是一行代码

 公共最终课程文件:目录{} 

我尝试了许多不同的方法,包括协议和幻像类型-但没有一个方法允许这种级别的自定义和便利。 对于此任务,子类化是正确的选择。

这得出了一个重要的结论:无论您对某些技术或模式有什么看法,都不应该害怕在满足您的需求时使用它们。 子类化只是Swift提供给我们的另一种工具-拥抱还是放弃它是我们选择的问题。