首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >尽管指示成功,UIDocument仍未保存到文件

尽管指示成功,UIDocument仍未保存到文件
EN

Stack Overflow用户
提问于 2017-04-04 03:43:55
回答 3查看 1.8K关注 0票数 25

我正在尝试使用UIDocument在iCloud驱动器中打开、修改和保存文件。当我调用带有文件位置的save(to:for:completionHandler:)并使用.forOverwriting作为UIDocumentSaveOperation时,它的状态为success = true。但是,iCloud文件(在桌面和iOS文件浏览器中都可以看到)不会更新,并且在重新打开该文件时,不会显示更改。我已经验证了contents(forType:)在保存时返回了正确的(修改过的)文件内容。

(注意:我已经看过this question了,但它没有太大帮助)

以下是代码的相关部分:

MainViewController.swift:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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
    }
}

更新:我真的需要帮助,我已经尝试了我能想到的所有方法来解决这个问题。如果您能给我任何帮助,我们将不胜感激。

EN

回答 3

Stack Overflow用户

发布于 2017-08-25 04:13:45

对于我来说,初始文件生成的方式是:

代码语言:javascript
复制
    let doc = YourUIDocumentClass(fileURL: fileURL) 
    doc.save(to: fileURL, for: .forCreating) { success in
        ...            
    }

然后修改文件,然后执行以下操作:

代码语言:javascript
复制
    doc.save(to: fileURL, for: .forOverwriting)  { success in
        ...            
    }

完成后。对该文件的后续访问是通过以下方式完成的:

代码语言:javascript
复制
    doc.open() { success in
        ...
    }

    doc.close() { success in
        ...            
    }

您可能还需要执行以下操作:

代码语言:javascript
复制
    doc.updateChangeCount(.done)

当文件处于打开状态时,通知文档有未保存的更改。仅设置此选项就会在几秒钟后进行保存。您甚至不需要关闭就可以做到这一点。

那个..。这意味着您要么必须嵌套所有这些内容,要么确保它们之间有足够的时间来完成它们。

票数 2
EN

Stack Overflow用户

发布于 2018-03-10 05:46:34

除了上面的答案之外,造成这种情况的另一个原因可能是在保存过程中出现了与contents(forType:)无关的错误。

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

票数 1
EN

Stack Overflow用户

发布于 2017-04-23 21:01:53

所以根据

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

看起来save函数实际上并不是用来保存文档的。我从阅读它的理解是,保存仅用于创建新文档。我知道您使用.forOverwriting只是为了保存它,但是iCloud中可能有一些东西不会让完全覆盖发生。

在您的doSaveAndClose方法中,尝试调用

代码语言:javascript
复制
self.saveFile?.close(completionHandler: self.didClose)

就是它自己。您可能必须执行某种类型的if查询,以检查文件是否存在。如果没有,则调用.save(),否则调用.close函数。似乎无论文档什么时候关闭,它都会保存更改。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43193010

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档