2017-04-03 36 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

相關問題