2017-04-03 68 views
18

我试图使用UIDocument在iCloud Drive中打开,修改和保存文件。当我使用文件位置调用save(to:for:completionHandler:)并将.forOverwriting用于UIDocumentSaveOperation时,它会以success = true的状态完成。但是,iCloud文件(如桌面和iOS文件浏览器中所示)不会更新,并且在重新打开文件时,不会显示更改。我已验证contents(forType:)在保存时会返回正确(已修改)的文件内容。尽管指示成功,UIDocument仍未保存到文件

(注:我已经看过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

@matt对不起,这应该是'.forOverwriting'。我只是暂时改变它,看看它是否有所作为(它没有)。 – Matt

+0

而不是downvoting,有人可以提供一些建设性的反馈?我真的需要找到一个答案。 – Matt

+1

观察“UIDocumentStateChanged”通知。在回调中,你是否碰巧报告过'inConflict'的状态? –

回答

0

所以根据

https://developer.apple.com/reference/uikit/uidocument

它看起来像保存功能实际上不是用于保存文档。我从阅读中了解到,保存只是为了创建一个新文档。我知道你正在使用.forOverwriting来保存它,但是在iCloud中可能会有某些东西不会让整个覆盖发生。

在你doSaveAndClose方法尝试调用

self.saveFile?.close(completionHandler: self.didClose) 

本身。如果查询文件是否存在,则可能必须执行一些类型的查询。如果不存在,则调用.save(),否则调用.close函数。看起来无论什么时候关闭它的文档都可以保存更改。

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) 

,而文件是打开的,告诉文档有未保存的更改。只需设置它将在几秒钟后导致保存。你甚至不需要靠近就可以做到这一点。

......意味着您必须嵌套所有这些或确保它们之间有足够的时间以便它们完成。

0

除了上面的答案,另一个原因可能是在保存过程中出现错误contents(forType:)无关。

例如,如果您实施了fileAttributesToWrite(to:for:)并发生错误,那么即使contents(forType:)返回了正确的数据,这也会导致UIDocumentState.savingError

相关问题