使用 Sqlite 和 GRDB 的 SwiftUI FileDocument
SwiftUI FileDocument using Sqlite and GRDB
在基于文档的 SwiftUI 应用程序中,我想使用 GRDB 作为 Sqlite 包装器将每个文档保存到一个单独的 Sqlite 文件中。通过为要加载的文件创建一个 DatabaseQueue
并使用其 .backup(to:)
方法复制到内存中 DatabaseQueue
。我应该如何在func fileWrapper(configuration: WriteConfiguration)
方法中实现保存?似乎没有明显的方法可以使用相同的 .backup(to:)
方法。
我找到了 Andre Yonadam 的 example application,它在 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)
}
}
这可能不是最干净的解决方案,但我通过实现知道如何写入 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)
}
在基于文档的 SwiftUI 应用程序中,我想使用 GRDB 作为 Sqlite 包装器将每个文档保存到一个单独的 Sqlite 文件中。通过为要加载的文件创建一个 DatabaseQueue
并使用其 .backup(to:)
方法复制到内存中 DatabaseQueue
。我应该如何在func fileWrapper(configuration: WriteConfiguration)
方法中实现保存?似乎没有明显的方法可以使用相同的 .backup(to:)
方法。
我找到了 Andre Yonadam 的 example application,它在 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)
}
}
这可能不是最干净的解决方案,但我通过实现知道如何写入 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)
}