Сериализация JSON ReadingOptions с противоречивым выводом в Swift 4.2 - PullRequest
0 голосов
/ 12 октября 2018

Я работаю над проектом для домашних животных, где сериализую JSON, используя класс JSONSerialization и jsonObject(with:options:).Объект не может быть использован до тех пор, пока не будет приведен в словарь [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 в вызове jsonObject имеет эквивалентное значение 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

1 Ответ

0 голосов
/ 12 октября 2018

Параметры чтения не имеют значения.В 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 
}
...