在 Swift 4.2 中使用不一致的输出序列化 JSON ReadingOptions

Serializing JSON ReadingOptions with inconsistent output in Swift 4.2

我正在做一个宠物项目,我正在使用 JSONSerialization class 和 jsonObject(with:options:) 序列化 JSON。该对象在转换为字典 [String: Any] 或数组 [Any] 之前是不可用的。这就是不一致发生的地方。以下是我的 classes 之一的方法。输入经过测试有效。

private static func parse(data: Data) -> [JSONDictionary]? {
    do {
        let options = JSONSerialization.ReadingOptions() // rawValue = UInt 0
        let otherOptions: JSONSerialization.ReadingOptions = [] // rawValue = UInt 0
        let jsonAny = try JSONSerialization.jsonObject(with: data, options: otherOptions)
        if let array = jsonAny as? [String: Any] {
            print(array)
        }
    } catch {
        return nil
    }

    return nil
}

两个 ReadingOption 对象都是有效的并产生可以正确转换的有效输出,并且 print(array) 被调用。

但是,当我使用以下内容时,返回无效输出并且无法正确转换。请注意 jsonObject 调用中的 options 与上例中的 otherOptions 具有等效值。

private static func parse(data: Data) -> [JSONDictionary]? {
    do {
        let jsonAny = try JSONSerialization.jsonObject(with: data, options: [])
        if let array = jsonAny as? [String: Any] {
            print(array) // never called
        }
    } catch {
        return nil
    }

    return nil
}

我想因为它们具有相同的值,所以我可以使用它们来代替彼此。但事实并非如此。这是一个错误,还是我使用不正确?

编辑:这里是正在使用的数据集https://www.govtrack.us/api/v2/role?current=true&role_type=senator

阅读选项无关紧要。在 Swift 中,ReadingOptions 仅在预期结果为 而不是 数组或字典时才有用。

如果预期类型是数组或字典,则省略 options 参数

不一致之处在于你的return类型是一个数组([JSONDictionary])但实际类型是一个字典。

private static func parse(data: Data) -> JSONDictionary? {
    do {
        let jsonAny = try JSONSerialization.jsonObject(with: data)
        if let jsonDictionary = jsonAny as? JSONDictionary {
            return jsonDictionary 
        }
    } catch {
        print(error)
        return nil
    }
    return nil
}

建议交出一个投掷方法的错误

enum SerializationError : Error {
   case typeMismatch
}

private static func parse(data: Data) throws -> JSONDictionary {
    let jsonAny = try JSONSerialization.jsonObject(with: data)
    guard let jsonDictionary = jsonAny as? JSONDictionary else { throw SerializationError.typeMismatch }
    return jsonDictionary 
}