我尝试使用UIDocument
在iCloud Drive中打开,修改和保存文件。当我使用文件位置调用save(to:for:completionHandler:)
并使用.forOverwriting
UIDocumentSaveOperation
时,它的状态为success = true
。但是,iCloud文件(如桌面和iOS文件浏览器中所示)不会更新,重新打开文件时,不会显示更改。我已经确认contents(forType:)
在保存时会返回正确(已修改)的文件内容。
(注意:我已经查看了this question,但这并不是很有帮助)
以下是相关的代码部分:
MainViewController.swift:
var saveFile: SBDocument?
@IBAction func bbiOpen_pressed(_ sender: UIBarButtonItem) {
if saveFile == nil {
let importMenu = UIDocumentMenuViewController(documentTypes: self.UTIs, in: .import)
importMenu.delegate = self
importMenu.popoverPresentationController?.barButtonItem = bbiOpen
self.present(importMenu, animated: true, completion: nil)
} else {
willClose()
}
}
func willClose(_ action: UIAlertAction?) {
if saveFile!.hasUnsavedChanges {
dlgYesNoCancel(self, title: "Save Changes?", message: "Would you like to save the changes to your document before closing?", onYes: doSaveAndClose, onNo: doClose, onCancel: nil)
} else {
doSaveAndClose(action)
}
}
func doSaveAndClose(_ action: UIAlertAction?) {
saveFile?.save(to: saveFileURL!, for: .forOverwriting, completionHandler: { Void in
self.saveFile?.close(completionHandler: self.didClose)
})
}
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
saveFile = SBDocument(fileURL: url)
saveFile!.open(completionHandler: { success in self.finishOpen(didCompleteSuccessfully: success) })
}
func finishOpen(didCompleteSuccessfully result: Bool) {
if result {
print(saveFile!.localizedName)
saveFileURL = saveFile!.fileURL
saveFileName = saveFile!.localizedName
self.navTitleBar.prompt = saveFileName
bbiOpen.title = NSLocalizedString("titleClose", comment: "Close")
bbiOpen.style = .plain
} else {
saveFile = nil
}
}
@IBAction func bbiSave_pressed(_ sender: UIBarButtonItem) {
self.saveFile!.save(to: self.saveFileURL!, for: .forOverwriting, completionHandler: self.didSave)
}
func didSave(_ success: Bool) {
guard success else {
print("Error saving soundboard file to \(String(describing: saveFileURL))")
return
}
print("File saved successfully")
}
SBDocument.swift:
class SBDocument: UIDocument {
override var fileType: String? { get { return "com.whitehatenterprises.SoundBoardFX.sbd" } }
override var savingFileType: String? { get { return "com.whitehatenterprises.SoundBoardFX.sbd" } }
override init(fileURL url: URL) {
super.init(fileURL: url)
}
override func contents(forType typeName: String) throws -> Any {
let arr = NSArray(array: SoundEffects)
let data: NSData = NSKeyedArchiver.archivedData(withRootObject: arr) as NSData
return data
}
}
更新 我真的需要帮助,我已经尝试了一切我能想到的解决这个问题的方法。您可以给我的任何帮助将不胜感激。
答案 0 :(得分:1)
除了上述答案之外,另一个原因可能是保存过程中与contents(forType:)
无关。
例如,如果您实现fileAttributesToWrite(to:for:)
并抛出错误,那么即使UIDocumentState.savingError
返回正确的数据,这也会导致contents(forType:)
。
答案 1 :(得分:0)
所以根据
https://developer.apple.com/reference/uikit/uidocument
看起来保存功能实际上并不用于保存文档。我从阅读中理解的是,保存仅用于创建新文档。我知道你正在使用.forOverwriting来保存它,但iCloud中可能会有一些东西不会让完全覆盖发生。
在doSaveAndClose方法中尝试调用
self.saveFile?.close(completionHandler: self.didClose)
本身。您可能必须执行某种类型的if查询,以检查文件是否存在。如果没有,则调用.save(),否则调用.close函数。似乎无论什么时候关闭文档都会保存更改。
答案 2 :(得分:0)
初始文件生成对我有用的方式是:
let doc = YourUIDocumentClass(fileURL: fileURL)
doc.save(to: fileURL, for: .forCreating) { success in
...
}
然后修改文件,然后执行:
doc.save(to: fileURL, for: .forOverwriting) { success in
...
}
完成后。随后对文件的访问由以下内容完成:
doc.open() { success in
...
}
doc.close() { success in
...
}
您可能还需要执行以下操作:
doc.updateChangeCount(.done)
当文件打开时告诉文档有未保存的更改。只需设置此项将在几秒钟后进行保存。你甚至不需要接近这样做。
...意味着您要么必须嵌套所有这些,要么确保它们之间有足够的时间以便它们完成。