1

在基于文档的 SwiftUI 应用程序中,我想使用 GRDB 作为 Sqlite 包装器将每个文档保存到单独的 Sqlite 文件中。在实现协议的文档中加载 Sqlite 文件很简单,方法是为要加载的文件FileDocument创建一个DatabaseQueue并使用其.backup(to:)方法复制到内存中DatabaseQueue。我应该如何在方法中实现保存func fileWrapper(configuration: WriteConfiguration)?似乎没有明显的方法可以使用相同的.backup(to:)方法。

我发现了 Andre Yonadam 的一个示例应用程序,它在 NSDocument 的子类中以相同的方式处理这个问题:

override func write(to url: URL, ofType typeName: String, for saveOperation: NSDocument.SaveOperationType, originalContentsURL absoluteOriginalContentsURL: URL?) throws {
    let destination = try DatabaseQueue(path: url.path)
    do {
        try memoryDBQueue.backup(to: destination)
    } catch {
        throw NSError(domain: NSOSStatusErrorDomain, code: unimpErr, userInfo: nil)
    }
}

override func read(from url: URL, ofType typeName: String) throws {
    let source = try DatabaseQueue(path: url.path)
    do {
        try source.backup(to: memoryDBQueue)
    } catch {
        throw NSError(domain: NSOSStatusErrorDomain, code: unimpErr, userInfo: nil)
    }
}
4

1 回答 1

2

这可能不是最干净的解决方案,但我通过实现一个知道如何写入 Sqlite 文件的 FileWrapper 子类来解决这个问题:

class SqliteFileWrapper: FileWrapper {

    var databaseQueue: DatabaseQueue

    init (fromDatabaseQueue databaseQueue: DatabaseQueue) {
        self.databaseQueue = databaseQueue
        super.init(regularFileWithContents: "".data(using: .utf8)!)
    }

    required init?(coder inCoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func write(
        to url: URL,
        options: FileWrapper.WritingOptions = [],
        originalContentsURL: URL?
    ) throws {
        let destination = try DatabaseQueue(path: url.path)
        do {
            try databaseQueue.backup(to: destination)
        } catch {
            throw NSError(domain: NSOSStatusErrorDomain, code: unimpErr, userInfo: nil)
        }
    }

}

然后在我的 FileDocument 子类中创建一个SqliteFileWrapper而不是 FileWrapper:

func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
    SqliteFileWrapper(fromDatabaseQueue: memoryDBQueue)
}
于 2021-02-25T21:36:12.057 回答