如何使用SwiftyJSON从文件中保存/检索字典

时间:2016-12-14 14:24:25

标签: ios swift swifty-json

我试图将Objc转换为快速转换,并且过得更好。

我有一个带字典的课程:

 collaborationDictionary:[String:Set<String>]

我正在尝试向/从文件中写入/读取此词典,但似乎无法使其正常工作。我必须使用以下JSON结构保存字典,我必须使用SwiftyJSON。

 { "Collaborations" : {
          "5604" : [
              "whiteboard.png",
              "VID_20161123_135117.3gp",
              "Photo_0.jpeg"]
          "5603" : [
              "VID_20161123_135117.3gp"],
          "5537" : [
              "Screenshot_20151212-132454.png",
              "VID_20161202_083205.3gp",
              "VID_20161123_135117.3gp",
              "Photo_0.jpeg",
              "Screenshot_20151212-132428.png",
              "Screenshot_20151212-132520.png",
              "IMG_20161017_132105.jpg",
              "whiteboard.png"]}
 }

查找/检索文件或编写文件时,我没有任何实际问题。我只是无法弄清楚如何手动加载SwiftyJSON。我需要一个名为&#34; Collaborations&#34;的JSON对象。在顶部。它需要包含协作ID字典(5604,5603 ......)。每个协作都包含一个字符串数组(文件名)。我包含了用于读取/写入文件的代码,但我需要有关SwiftyJSON库的帮助。

这是我用来存储上述数据的会员数据成员:

这些是我需要完成的功能:

     private var collaborationDictionary:[String:Set<String>] = [:]


  func getUploadedFileSet() {
    collaborationDictionary = [:]
    let documentsURL = URL(string: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0])
    let appURL = documentsURL?.appendingPathComponent(APP_DISTINGUISHED_NAME)
    let jsonFileURL = appURL?.appendingPathComponent(UPLOADED_ITEMS_DB_JSON)

    if FileManager.default.fileExists(atPath: (jsonFileURL?.absoluteString)!) {
        do {
            let data = try Data(contentsOf: jsonFileURL!, options: .alwaysMapped)
            let json = JSON(data: data)

            // ************************************************
            // NEED HELP START
            // NOW WHAT????  What is the SwiftyJSON code

            ?????????????????????????                

            // NEED HELP END
            // ************************************************

        } catch let error {
            print(error.localizedDescription)
        }
    }
 }

  func saveUploadedFilesSet() {        
    let documentsURL = URL(string: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0])
    let appURL = documentsURL?.appendingPathComponent(APP_DISTINGUISHED_NAME)
    let jsonFileURL = appURL?.appendingPathComponent(UPLOADED_ITEMS_DB_JSON)

    do {
        let dirExists = FileManager.default.fileExists(atPath: (appURL?.absoluteString)!)
        if !dirExists {
            try FileManager.default.createDirectory(atPath: (appURL?.absoluteString)!, withIntermediateDirectories: false, attributes: nil)
        }

        // ************************************************
        // NEED HELP START
            // NOW WHAT????  What is the SwiftyJSON code

            ?????????????????????????                

        // NEED HELP END
        // ************************************************

        // Write to file code - haven't written it yet but that should be easy          

    } catch let error as NSError {
        print(error.localizedDescription);
    }
 }

任何方向都将不胜感激。谢谢!

修改

我能够弄清楚如何从文件加载提供的JSON结构。这是代码:

 func getUploadedFileSet() {
    let documentsURL = URL(string: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0])
    let appURL = documentsURL?.appendingPathComponent(APP_DISTINGUISHED_NAME)
    let jsonFileURL = appURL?.appendingPathComponent(UPLOADED_ITEMS_DB_JSON)

    if FileManager.default.fileExists(atPath: (jsonFileURL?.absoluteString)!) {
        do {
            let data = try Data(contentsOf: jsonFileURL!, options: .alwaysMapped)
            let json = JSON(data: data)
            if json != nil {
                for (key, subJson) in json[kCollaborations] {
                    let stringArray:[String] = subJson.arrayValue.map { $0.string! }
                    let stringSet = Set(stringArray)
                    collaborationDictionary.updateValue(stringSet, forKey: key)
                }
            } else {
                print("Could not get json from file, make sure that file contains valid json.")
            }
        } catch let error {
            print(error.localizedDescription)
        }
    }

我仍然没有想出如何将collaborationDictionary对象保存到文件中。我最大的问题是弄清楚如何加入&#34; Collaborations&#34;键。有什么想法吗?

2 个答案:

答案 0 :(得分:5)

我终于开始工作了。最大的问题是我无法将collaborationDictionary转换为JSON。我最后不得不将它转换为数组字典与集合字典。以下是两种方法:

     // **************************************************************************
func getUploadedFileSet() {
    let documentsURL = URL(string: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0])
    let appURL = documentsURL?.appendingPathComponent(APP_DISTINGUISHED_NAME)
    let jsonFileURL = appURL?.appendingPathComponent(UPLOADED_ITEMS_DB_JSON)

    if FileManager.default.fileExists(atPath: (jsonFileURL?.absoluteString)!) {
        do {
            let data = try Data(contentsOf: jsonFileURL!, options: .alwaysMapped)
            let json = JSON(data: data)
            if json != nil {
                for (key, subJson) in json[kCollaborations] {
                    let stringArray:[String] = subJson.arrayValue.map { $0.string! }
                    let stringSet = Set(stringArray)
                    collaborationDictionary.updateValue(stringSet, forKey: key)
                }
            } else {
                print("Could not get json from file, make sure that file contains valid json.")
            }
        } catch let error {
            print(error.localizedDescription)
        }
    }
}

// **************************************************************************
func saveUploadedFilesSet() {
    let documentsURL = URL(string: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0])
    let appURL = documentsURL?.appendingPathComponent(APP_DISTINGUISHED_NAME)
    let jsonFileURL = appURL?.appendingPathComponent(UPLOADED_ITEMS_DB_JSON)
    let adjustedJSONFileURL = URL(fileURLWithPath:(jsonFileURL?.absoluteString)!)

    do {
        let dirExists = FileManager.default.fileExists(atPath: (appURL?.absoluteString)!)
        if !dirExists {
            try FileManager.default.createDirectory(atPath: (appURL?.absoluteString)!, withIntermediateDirectories: false, attributes: nil)
        }

        // Convert set elements to arrays
        var convertedCollaborationDictionary: [String:[String]] = [:]
        for (sessionID, fileNameSet) in collaborationDictionary {
            let array = Array(fileNameSet)
            convertedCollaborationDictionary.updateValue(array, forKey: sessionID)
        }
        let json: JSON = JSON(convertedCollaborationDictionary)
        let fullJSON: JSON = [kCollaborations:json.object]
        let data = try fullJSON.rawData()
        try data.write(to: adjustedJSONFileURL, options: .atomic)

    } catch let error as NSError {
        print(error.localizedDescription);
    }
}

答案 1 :(得分:2)

如果你深入了解源代码,SwiftyJSON包含JSONSerialization,它可以被初始化并转换回Data,它知道如何从磁盘读取和写入自己:

  func readJSON() -> JSON? {
      guard let url = Bundle.main.url(forResource: "data", withExtension: "json"),
            let data = try? Data(contentsOf: url) else {
          return nil
      }
      return JSON(data: data)
  }

  func write(json: JSON, to url: URL) throws {
      let data = try json.rawData()
      try data.write(to: url)
  }

请注意,您可以从包括Bundle在内的任何位置加载静态数据,但只能写入沙箱(即Documents目录)。如果您打算阅读/写入同一文件,您可能希望在首次运行时从Bundle复制到文档目录。

你的样本JSON也不好(lint它)。在“Photo_0.jpeg”]

之后你需要一个逗号