我正在使用Core Data来存储用户的数据。我想在用户界面中提供一个“共享”按钮以将数据导出到他们希望的任何位置。我做了一个符合UIActivityItemSource
的类。仅从activityViewController:itemForActivityType
返回Data对象但该文件具有系统提供的文件名时,即表示成功。因此,我现在尝试立即生成一个UIDocument
,将其保存到文件系统中,然后将URL
(UIDocument.fileURL
)返回到活动视图控制器。问题是UIDocument.save
是异步的,但是在保存文件之前我无法从activityViewController:itemForActivityType
返回。我的最新代码如下所示:
类的init:
let saveQueue = DispatchQueue(label: "saveQueue")
let saveSemaphore = DispatchSemaphore(value: 0)
...
func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
var success = false
self.saveQueue.async {
self.document.save(to: self.document.fileURL,
for: .forOverwriting) {(didSucceed) in
success = didSucceed
self.saveSemaphore.signal()
}
}
saveSemaphore.wait()
return success ? document.fileURL : nil
}
行为是异步代码启动,但从未调用保存的完成功能。我做错了什么?
在Casey的帮助下,我的最终解决方案是覆盖
UIDocument.save
。override func save(to url: URL, for saveOperation: UIDocument.SaveOperation, completionHandler: ((Bool) -> Void)? = nil) {
do {
let contents = try self.contents(forType: GlobalConst.exportType) as! Data
try contents.write(to: url, options: [.atomicWrite])
completionHandler?(true)
} catch {
print("write error: \(error)")
completionHandler?(false)
}
}
我还没有理解为什么超类保存是一个问题,但是我可以让它滑动。
最佳答案
为了使其正常工作,我必须创建UIDocument的子类并覆盖func save(to:for:completionHandler:)
class MyDocument: UIDocument {
var body: String = "Hello world, this is example content!"
override func save(to url: URL, for saveOperation: UIDocument.SaveOperation, completionHandler: ((Bool) -> Void)? = nil) {
do {
try self.body.write(toFile: url.path, atomically: true, encoding: .utf8)
completionHandler?(true)
} catch {
print("write error: \(error)")
completionHandler?(false)
}
}
}
您的代码保持完全相同,只需确保
self.document
的类型为MyDocument
(或您可能已经拥有的任何子类)。let document = MyDocument(fileURL: URL(fileURLWithPath: NSHomeDirectory() + "/Documents/output.txt"))
关于ios - 在UIActivityItemProvider中动态创建UIDocument,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55697625/