Swift 4:JSONDecoder 在一种特定情况下失败-“操作无法完成”[关闭]
Posted
技术标签:
【中文标题】Swift 4:JSONDecoder 在一种特定情况下失败-“操作无法完成”[关闭]【英文标题】:Swift 4: JSONDecoder fails in one specific case - "The operation could not be completed" [closed] 【发布时间】:2018-04-24 15:53:07 【问题描述】:我正在接收 JSON 文本,将其转换为数据,然后使用 JSONDecoder 创建由 JSON 文本/字符串表示的具体类型。
它确实适用于我的“复杂”数据结构(实现 Codable),甚至是一个简单的 Int 数组,如下所示:
import Foundation
let jsonTextContainigArrayOfInt: String = "[1,2,3]"
let data = jsonTextContainigArrayOfInt.data(using: .utf8)!
do
let arrayOfInt: [Int] = try JSONDecoder().decode([Int].self, from: data)
for n in arrayOfInt
print(n)
catch
print(error)
前面的代码可以正常工作并正确创建 Int 数组并打印它们。
使用 JSON 文本中的单个 Int 执行相同方法时会出现问题:
import Foundation
let jsonTextContainigOneInt: String = "1"
let data = jsonTextContainigOneInt.data(using: .utf8)!
do
let myInt: Int = try JSONDecoder().decode(Int.self, from: data)
print(myInt)
catch
print(error)
对于第二种方法,我收到以下错误:
“操作无法完成”
*** 编辑 ***
已存在此问题的错误报告:https://bugs.swift.org/browse/SR-6163
【问题讨论】:
"1" 不是有效的 JSON。 感谢您的时间 picciano。您能否对此发表评论:***.com/a/7487892/8284660。它指出诸如单个字符串之类的值现在应该是有效的(在 RFC 7159 中) 由于 (NS)JSONSerialization 不接受它,所以 JSONDecoder 一点也不奇怪。请参阅文档:developer.apple.com/documentation/foundation/… 此外,它似乎只符合 RFC 4627,而不是新的 (github.com/gnustep/libs-base/blob/master/Source/…) 使用JSONSerialization
,查看这个答案***.com/questions/47941826/…
谢谢你们!我确实看到 JSONSerialization 不接受非数组、非字典对象作为有效的 JSON,即使(正如我告诉@picciano)在 RFC-7159 中,它现在是有效的 JSON。我现在看到 JSONDecoder 没有 JSONSerialization 中的“.allowFragments”选项。感谢@schmidt9 的澄清。
【参考方案1】:
JSONDecoder
只能将集合类型(数组或字典)解码为根对象。
在后台JSONDecoder
使用JSONSerialization
没有任何选项。但是,要解码 String
或 Int
,您必须指定 .allowFragments
选项。
将JSONSerialization
与.allowFragments
选项一起使用
let jsonTextContainingOneString = "1"
let data = Data(jsonTextContainingOneString.utf8)
do
let myString = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
print(myString)
catch
print(error)
【讨论】:
【参考方案2】:有趣...我发现了这个:
https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/JSONSerialization.swift#L120
特别是这个保护声明:
open class JSONSerialization : NSObject
//...
// top level object must be an Swift.Array or Swift.Dictionary
guard obj is [Any?] || obj is [String: Any?] else
return false
//...
然后我查看了一个简单的文本字符串是否应该被视为有效的 JSON,显然现在应该被视为有效的 JSON(以前不被接受为有效的 JSON)。至少,基于这个出色的答案:https://***.com/a/7487892/8284660
这让我想知道我原来帖子上的行为是否应该是一个错误。
【讨论】:
错误报告已经存在:bugs.swift.org/browse/SR-6163以上是关于Swift 4:JSONDecoder 在一种特定情况下失败-“操作无法完成”[关闭]的主要内容,如果未能解决你的问题,请参考以下文章
Swift - 使用 JSONDecoder 解码 JSON 数据
使用 Swift 4 中的 JSONDecoder,缺少的键可以使用默认值而不是可选属性吗?
使用 Swift 4 中的 JSONDecoder,缺少的键可以使用默认值而不是可选属性吗?