AppFolder 是一个轻量级框架,允许你为应用程序容器内的目录设计友好、强类型的表示。所有系统目录,如 "Caches/" 和 "Application Support/" 已经存在,你可以用几行代码添加自己的目录。
AppFolder 具有简单而美观的界面,这得益于 Swift 的魔法:继承 😱
如果你想了解更多关于这个想法的信息,请查看 Medium 上的 Introducing AppFolder。
import AppFolder
let documents = AppFolder.Documents
let caches = AppFolder.Library.Caches
let cachesURL = caches.url
extension Library.Caches {
class Images: Directory { }
var Images: Images {
return subdirectory()
}
}
let imageCache = AppFolder.Library.Caches.Images
let imageCacheURL = imageCache.url
let documents = AppFolder.Documents
let tmp = AppFolder.tmp
let applicationSupport = AppFolder.Library.Application_Support
let caches = AppFolder.Library.Caches
caches.url // full URL
caches.folderName // "Caches"
caches.subpath // "Library/Caches"
caches.baseURL
// the same as
AppFolder.baseURL
let fileURL = caches.url.appendingPathComponent("cached-file.json")
AppFolder 代表你应用程序容器的文件结构,让你更好地了解文件存储的位置。AppFolder 是进入文件夹的主要入口点。在里面你可以找到
AppFolder.Documents)。你应该在此目录中存储 "仅由用户生成,或者你的应用程序无法重新创建的文档和其他数据。" - iOS 数据存储指南AppFolder.Library.Application_Support)。 "Application Support 目录是存储可能位于 Documents 目录中,但不应被用户看到的文件的理想位置。例如,你的应用程序需要但用户永远不会手动打开的数据库。" - iOS 存储最佳实践AppFolder.Library.Caches)。Caches 目录用于 "...可以再次下载或重新生成的数据。...你应该放在 Caches 目录中的文件示例包括数据库缓存文件和可下载的内容,例如杂志、报纸和地图应用程序所使用的内容。" - iOS 数据存储指南AppFolder.tmp)。 "使用此目录写入应用程序启动之间不需要持久存在的临时文件。你的应用程序应在不再需要时从此目录中删除文件;但是,当你的应用程序未运行时,系统可能会清除此目录。" - 文件系统编程指南假设我们想在 "Application Support" 目录中声明一个 "Files" 文件夹。
事实证明,AppFolder 中的每个文件夹都由一个具体的 Directory 子类表示。例如,"Application Support" 的类型为 Library.Application_Support。要声明我们自己的文件夹,我们需要创建一个新的 Directory 子类
final class Files : Directory { }
默认情况下,文件夹名称将从类名自动生成。
现在我们可以以一种非常直接的方式访问我们的新文件夹
let filesFolder = AppFolder.Library.Application_Support.appending(Files.self)
但是,如果我们想要获得更高的类型安全性,我们应该将整个逻辑放入一个扩展中
extension Library.Application_Support {
final class Files : Directory { }
var Files: Files {
return subdirectory()
}
}
现在,你可能想知道:既然 var Files 是一个属性,为什么 var Files... 是大写的?
好吧,这是一个有意的 AppFolder 设计决策。为了尽可能准确地表示文件夹结构,所有属性都必须按照它们的真实名称书写(空格用 _ 代替)。因此,例如,"Documents" 是 AppFolder.Documents,而 "tmp" 是 AppFolder.tmp - 就像在“现实世界”中一样。
使用 _ 命名你的类(例如,class User_Files : Directory)将自动生成带有空格的文件夹名称(在这种情况下为“User Files”)
所以,这部分应该很清楚了。现在我们可以完全直观地使用我们的文件夹
let files = AppFolder.Library.Application_Support.Files
let filesURL = files.url
重要提示: 描述文件夹不会自动创建它们。 AppFolder 提供了一种在代码中组织文件夹结构的方法,而不是主动管理磁盘上的文件夹结构。 为了使用,所有非系统目录都应该使用 FileManager.default.createDirectory(at:) 或类似的 API 显式创建。
AppFolder 还支持通过 AppGroupContainer 与应用程序组共享的容器
enum MyAppGroup : AppGroup {
static var groupIdentifier: String {
return "group.com.my-app.my-app-group"
}
}
let sharedCaches = AppGroupContainer<MyAppGroup>.Library.Caches
通过这种方式,例如,你可以简化共享 Core Data 堆栈的创建,而不会失去对该过程的控制
let applicationSupportURL = AppGroupContainer<MyAppGroup>.Library.Application_Support.url
let sqliteFileURL = applicationSupportURL.appendingPathComponent("db.sql")
let model = NSManagedObjectModel(contentsOf: sqliteFileURL)
let container = NSPersistentContainer(name: "my-app-db", managedObjectModel: model!)
要了解更多关于应用程序组的信息,请查看 App Extension Programming Guide: Handling Common Scenarios (“与你的包含应用共享数据”部分)。
如果你对自动生成的名称不满意,你可以提供自己的名称
final class CustomNamedFolder : Directory {
override var folderName: String {
return "Custom"
}
}
AppFolder 在底层使用 NSHomeDirectory(),因此,根据你的 macOS 应用程序,它可能只会将你定位到用户的 home 目录,正如文档所述
在 macOS 中,它是应用程序的沙盒目录或当前用户的 home 目录(如果应用程序不在沙箱中)
AppFolder.tmp 在 macOS 上也已弃用,因为它可能给出与 NSTemporaryDirectory() 不同的结果。要在 macOS 上使用临时目录,我们建议使用 FileManager.default.temporaryDirectory。
AppFolder 仍处于非常早期的阶段。某些东西在某些时候可能会出现故障。
从 Xcode 11 开始,AppFolder 仅 通过 Swift Package Manager 正式提供。
在 Xcode 11 或更高版本中,在你的项目中,选择:File > Swift Packages > Add Pacakage Dependency
在搜索栏中输入
https://github.com/dreymonde/AppFolder
然后继续安装。
如果你在 Swift Packages 面板中找不到任何内容,可能你还没有添加你的 github 帐户。你可以在 Xcode 的 Preferences 面板中的 Accounts 部分中执行此操作。
对于基于命令行的应用程序,你可以直接将其添加到你的 Package.swift 文件中
dependencies: [
.package(url: "https://github.com/dreymonde/AppFolder", from: "0.2.0"),
]
当然,你始终可以选择复制粘贴代码 - AppFolder 只有几个文件,所以随意吧。
支持 Carthage 和 Cocoapods 的最新 AppFolder 版本是 0.2.0。 Carthage 和 Cocoapods 将不再正式支持。
Carthage
github "dreymonde/AppFolder" ~> 0.2.0
Cocoapods
pod 'AppFolder', '~> 0.2.0'