首页 文章

Swift 4:JSONDecoder在一个特定情况下失败 - “操作无法完成”[关闭]

提问于
浏览
1

我正在接收JSON文本,将其转换为Data,然后使用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)
}

对于第二种方法,我收到以下错误:

“操作无法完成”

***** Edit *****

针对此的错误报告已存在:https://bugs.swift.org/browse/SR-6163

2 回答

  • 1

    JSONDecoder 只能将集合类型(数组或字典)解码为根对象 .

    引擎盖 JSONDecoder 使用 JSONSerialization without 任何选项 . 但是要解码 StringInt ,您必须指定 .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)
    }
    
  • 0

    有趣......我发现了这个:

    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) . 至少,基于这个出色的答案:https://stackoverflow.com/a/7487892/8284660

    这让我想知道我原来的帖子上的行为是否应该是一个bug .

相关问题