无法将保存的JSON数据加载到视图中

时间:2019-04-21 13:42:04

标签: ios json swift encoding decoding

在我创建的基于文档的应用程序中,我有一个名为“ TestDraw”的视图,可以在其中从collectionView拖放UILable。在“ TestDraw”上,还可以自由绘图...

我还设置了BarItems来保存用户放置UILabel的位置及其上的信息,以便以后可以将信息解码为卡对象...

但是,每次打开一个我认为已成功保存的JSON文件时,结果都是空白...

我试图将已保存文件的jsonString打印到控制台中,这被证明是正确的,因此显示信息已成功保存。

这是NumberCardsSetDocument中的代码:

class NumberCardsSetDocument: UIDocument {

var numberCardsSet: NumberCardsSet?

override func contents(forType typeName: String) throws -> Any {
    // Encode your document with an instance of NSData or NSFileWrapper
    return numberCardsSet?.json ?? Data()
}

override func load(fromContents contents: Any, ofType typeName: String?) throws {
    if let json = contents as? Data{
        numberCardsSet = NumberCardsSet(json: json)
    }else {
        print("Error trying to load NumberCards. Content is not JSON data")
    }
  }
}

这是NumberCardsSet中的代码:

struct NumberCardsSet: Codable{
var numberCards = [CardInfo]()
struct CardInfo: Codable{
    let x: Int
    let y: Int
    let text: String
    let size: Int
}
init?(json:Data){
    if let newValue = try? JSONDecoder().decode(NumberCardsSet.self, from: json){
        self = newValue
    }else{
        return nil
    }
}
var json: Data? {
    return try? JSONEncoder().encode(self)
}
init (numberCards:[CardInfo]){
    self.numberCards = numberCards
}
}

这就是我要加载已保存数据的方法:

class DocumentBrowserViewController: UIDocumentBrowserViewController, UIDocumentBrowserViewControllerDelegate {

override func viewDidLoad() {
    super.viewDidLoad()
    delegate = self
    allowsPickingMultipleItems = false
    allowsDocumentCreation = true
    template = try? FileManager.default.url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent("UntitledHMS.json")
    if template != nil {
        allowsDocumentCreation = FileManager.default.createFile(atPath: template!.path, contents: Data() )
    }
}

var template:URL?
// MARK: UIDocumentBrowserViewControllerDelegate

func documentBrowser(_ controller: UIDocumentBrowserViewController, didRequestDocumentCreationWithHandler importHandler: @escaping (URL?, UIDocumentBrowserViewController.ImportMode) -> Void) {
    importHandler(template,.copy)
}

func documentBrowser(_ controller: UIDocumentBrowserViewController, didPickDocumentsAt documentURLs: [URL]) {
    guard let sourceURL = documentURLs.first else { return }
    presentDocument(at: sourceURL)
}

func documentBrowser(_ controller: UIDocumentBrowserViewController, didImportDocumentAt sourceURL: URL, toDestinationURL destinationURL: URL) {
    presentDocument(at: destinationURL)
}

func documentBrowser(_ controller: UIDocumentBrowserViewController, failedToImportDocumentAt documentURL: URL, error: Error?) {
}

// MARK: Document Presentation
func presentDocument(at documentURL: URL) {
    let storyBoard = UIStoryboard(name: "Main", bundle: nil)
    let documentVC = storyBoard.instantiateViewController(withIdentifier: "DocumentMVC")
    if let trailMakingTestViewController = documentVC.contents as? DocumentViewController{
        trailMakingTestViewController.document = NumberCardsSetDocument(fileURL: documentURL)
    }
    present(documentVC,animated: true)
}
}

我认为问题可能出在信息解码过程中。希望有人可以给我一些线索。这是我第一次尝试自行构建复杂的应用程序。

1 个答案:

答案 0 :(得分:1)

我认为您可以进一步缩小范围。你有这行

return try? JSONEncoder().encode(self)

然后在代码中处理nil个返回值,这没关系。

但是,如果您怀疑编码可能失败,一种获取更好信息的方法是在do - catch周围使用适当的try块,而不是使用try?。如果仅从将错误打印到控制台开始,则可能会有所帮助。以我的经验,这些消息有助于指出为什么某些东西无法编码(或解码)。