【问题标题】:Cannot serializing sorted dictionary to JSON - Swift 3无法将排序字典序列化为 JSON - Swift 3
【发布时间】:2017-05-26 12:26:10
【问题描述】:

无法通过JSONSerialization.data(withJSONObject:options:)将我的排序字典序列化为 JSON

序列化适用于未排序的字典,但使用已排序的应用程序会抛出描述错误:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (_SwiftValue)'

这是我的方法的样子:

func createJSONFile(){
    // create path to json file
    let fileManager = FileManager.default
    let urls = fileManager.urls(for: .documentDirectory, in: .userDomainMask)
    let documentDirectory = urls[0] as NSURL
    guard let jsonURL = documentDirectory.appendingPathComponent("graphData") else {
        print("Failed to create path to json file.")
        return
    }

    print(jsonURL.absoluteString)
    // creating a .json file in the Documents folder
    if !fileManager.fileExists(atPath: jsonURL.absoluteString){
      fileManager.createFile(atPath: jsonURL.absoluteString, contents: nil, attributes: nil)
        print("file created")
    }

    do {
        let unsortedDic = self.tempDictionaryForJsonFile
        let sortedDic = unsortedDic.sorted(by: <)
        let jsonData = try JSONSerialization.data(withJSONObject: sortedDic, options: .prettyPrinted)
        print(jsonData)
        try jsonData.write(to: jsonURL)

        print(fileManager.fileExists(atPath: jsonURL.absoluteString))

        let content = try String.init(contentsOf: jsonURL, encoding: .utf8)
        print(content)

    } catch {
        print(error.localizedDescription)
    }
}

有趣的是,在检查器中调试未排序的字典看起来像这样:unsorted dictionary 和排序看起来像这样 sorted dictionary

请帮忙解决这个问题。

【问题讨论】:

  • Dictionary 没有任何订单。

标签: ios json swift dictionary foundation


【解决方案1】:

首先,在 Swift 标准库中没有排序的目录(或者在 JSON 中;JSON 对象是无序的)。当您在字典上调用 .sorted() 时,它会返回一个键/值对数组 [(Key, Value)]

JSONSerialization 有关于它可以序列化什么的规则:

  • 顶级对象是 NSArray 或 NSDictionary。

  • 所有对象都是 NSString、NSNumber、NSArray、NSDictionary 或 NSNull 的实例。

  • 所有字典键都是 NSString 的实例。

  • 数字不是 NaN 或无穷大。

从 NS 兼容的集合到它们的 NS 等价物之间存在隐式桥梁,但只有当内容可以用 ObjC 表示时才能得到这个(而(Key, Value) 不能)。

如何正确实现这在很大程度上取决于tempDictionaryForJsonFile 的类型和内容,这里没有给出。它还取决于您尝试使用“排序字典”(JSON 中不存在,因此无法从 Swift 获取它)来实现的目标。如果您的意思是“一个有序的 JSON 对象数组,每个对象都有一个键/值”,则可以构建它(但您需要在任何消耗此数据的情况下支持它)。

【讨论】:

  • 感谢您的信息!我的任务是最后制作带有 X 和 Y 音频图的 JSON 文件。为清楚起见,我在播放期间从音频文件中提取采样率,然后将采样率的每个值附加到 [Float] 数组中。然后我用 .enumerate 遍历这个 [Float] 数组并构造一个字典,其中键是 [Float] 数组的索引转换为字符串,值是数组的相应值也转换为字符串。最后发现这个输出字典有无序键。
  • "最后发现这个输出字典有无序键。"正确的。所有 Swift 字典都有无序键(JSON 对象有无序键)。这是一个问题吗?尚不清楚为什么要将这些数字中的任何一个转换为字符串;这很奇怪且容易出错(如果您要排序,则无法正确排序)。这似乎非常令人费解。如果你已经有[Float],为什么不直接序列化呢?或者[Record]Record 会有采样时间,X 和 Y 浮动?
  • 感谢您的友好回答。在您发布之前,我已设法将图形数据序列化为 [[String: Float]] 数组,其中 String 是图形的 Y 值(浮点数)的索引,因此我有一个 JSON 文件,其内容如下: [ { "index" :值},{“索引”:值...}。这是求职面试测试任务的一部分。
猜你喜欢
  • 2018-09-21
  • 2019-02-08
  • 1970-01-01
  • 2019-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-19
  • 2017-10-19
相关资源
最近更新 更多