Преобразование строки JSON в словарьсериализует логическое значение как Int - PullRequest
0 голосов
/ 14 мая 2019

Я пытаюсь сериализовать строку Json в словарь И он преобразует значение boolean в значение int. проверить код.

Проверьте выходное значение для ключа "BoolArgument", возвращая его 1 вместо true

Примечание: я не могу преобразовать строку в быстрый объект данных, используя Codable, поскольку ключи в словаре json не являются константами.

========================
Code
========================

let inputArgumentsString = "{\"FloatArgument\":1.0,\"BoolArgument\":true,\"ObjectArgument\":{}}"

var toJson: Dictionary<String, Any>? {
     guard let data = self.data(using: .utf8) else { return nil }
     do {
         return try JSONSerialization.jsonObject(with: data, options : .allowFragments) as? Dictionary<String, Any>
     } catch let error {
         print(error.localizedDescription)
         return nil
     }
 }

print(self.inputArgumentsString?.toJson)```

========================
Output
========================

po self.inputArgumentsString?.toJson
▿ Optional<Dictionary<String, Any>>
  ▿ some : 3 elements
    ▿ 0 : 2 elements
      - key : "BoolArgument"
      - value : 1
    ▿ 1 : 2 elements
      - key : "ObjectArgument"
      - value : 0 elements
    ▿ 2 : 2 elements
      - key : "FloatArgument"
      - value : 1

Ответы [ 2 ]

2 голосов
/ 14 мая 2019

Это просто описание отладчика результата.

Для Bool используется NSNumber со значениями 1 как true и 0 как false.

Если вы вызываете в своем коде что-то вроде:

guard let json = self.inputArgumentsString?.toJson,
        let boolean = json["BoolArgument"] as? Bool
        else { return }

print(boolean)

Будет напечатано true или false.


Если вы хотите проверить, является ли значение логическим или нет, вы можете попробовать использовать что-то вроде этого:

for key, value in json {
  if let number = value as? NSNumber {
    let numberType = CFNumberGetType(number as CFNumberRef)

    switch numberType {
      case .charType:
        //Bool
        print(key, value as? Bool)
      case .sInt8Type, .sInt16Type, .sInt32Type, .sInt64Type, .shortType, .intType, .longType, .longLongType, .cfIndexType, .nsIntegerType:
        //Int
        print(key, value as? Int)
      case .float32Type, .float64Type, .floatType, .doubleType, .cgFloatType:
        //Double
        print(key, value as? Double)
    }
  }
}
1 голос
/ 14 мая 2019

Внутренне, JSONSerialization - это класс Objective-C, который использует NSNumber экземпляры для представления как числовых, так и логических значений из JSON. Когда вы печатаете словарь, эти экземпляры имеют свои числовые значения. Однако NSNumber знает, когда оно хранит логическое значение, поэтому оно будет автоматически соединено при попытке доступа к значению. toJSON["BoolArgument"] as? Bool должно дать правильное значение.

В любом случае, использование Codable для правильного анализа типов может быть лучшим решением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...