Как лучше всего обрабатывать необязательный элемент в SwiftyJSON?

Я использую SwiftyJSON (https://github.com/SwiftyJSON/SwiftyJSON). Предположим, у меня есть ответ JSON одного из двух форматов:

{
    "id": 1,
    "foo": "bar"
}

Or

{
    "id": 1,
    "foo": "bar",
    "user": {"id": 2}
}

Я хочу обновить атрибут «пользователь» моего объекта Swift только тогда, когда присутствует элемент «пользователь» в JSON. Прямо сейчас я делаю это:

let userJson = json["user"]
if userJson.type != .Null && userJson.type != .Unknown {
    user = User.create(userJson)
}

Есть ли лучший способ справиться с этим? Скажем, используя синтаксис Swift if-let?


person franklsf95    schedule 17.12.2014    source источник


Ответы (2)


Я не могу придумать более элегантного способа, чем то, что вы делаете, но, кроме того, я переместил свои проверки в конструкторе. Что я делаю для своей реализации, так это то, что для каждого класса, который может десериализоваться в объект передачи данных, я должен предоставить реализацию для конструктора, который принимает словарь в качестве параметра. Словарь - это json, который исходит от API. Я, очевидно, гарантирую на своем прокси-уровне, что он действительно может десериализоваться, не является нулевым и может быть представлен в виде словаря.

Поскольку я знаю, что вызов API может либо возвращать какой-либо неверный ответ (обрабатываемый в общем случае с моего прокси-уровня), либо именно тот контракт, который мне нужен для этого вызова (преобразованный в DTO), я могу сделать некоторые предположения о том, что возвращается.

В вашем случае, когда у вас есть вероятность того, что что-то не вернется, если это не сложный проект, вам, вероятно, может сойти с рук выполнение таких проверок в вашем конструкторе следующим образом:

 required init(dict dictionary: NSDictionary)
 {
    self.id = dictionary["id"] as Int
    self.foo = dictionary["foo"] as String
    self.user = ( (dictionary["user"] == nil) ? User() : User(dictionary["user"]))
 }

Итак, теперь здесь я говорю, что если это nil, верните новый пользовательский объект, но, возможно, вы хотите просто оставить его nil. В противном случае, если это не так, передайте «пользовательский словарь» (дочерний элемент в исходном JSON, в данном случае {«id»: 2}) в конструктор пользовательского класса, и он в значительной степени сделает то же самое, но увлажнит ваш пользовательский объект. .

Я предполагаю, что класс пользователя может быть:

 required init(dict dictionary: NSDictionary)
 {
    self.id = (dictionary["id"] as Int)
 }
person NullHypothesis    schedule 17.12.2014

Поскольку SwiftyJSON позволяет вам использовать объекты так, как будто они существуют (при условии, что идентификатор пользователя всегда существует, если возвращается пользовательский объект), вы также можете использовать следующее в качестве проверки, чтобы немного упростить ситуацию:

if let userId = json["user"]["id"].string {
  user = User.create(json["user"])
} else {
  // Do something else, or just ignore it.
}
person Jonathan Bender    schedule 17.12.2014
comment
Это приятно! Хотя с небольшим чувством взлома :) - person franklsf95; 17.12.2014