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

时间:2018-10-12 18:24:16

标签: swift nsjsonserialization

我正在一个宠物项目中,正在使用JSONSerialization类和jsonObject(with:options:)序列化JSON。在转换成字典[String: Any]或数组[Any]之前,该对象不可用。这就是不一致的地方。以下是我的一个课程中的一种方法。输入已测试且有效。

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)

但是,当我使用以下命令时,将返回无效的输出,并且无法正确转换。请注意,在以上示例中,options调用中的jsonObjectotherOptions等效。

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

1 个答案:

答案 0 :(得分:1)

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

如果期望的类型是数组或字典,请省略options参数

不一致之处在于您的返回类型是数组([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 
}