Слишком много опций делают код беспорядочным в Swift

Я разбираю JSON, и это первый раз, когда я делаю это на Swift. В последнее время я избегаю принудительного приведения вниз, так как это плохая практика.

К сожалению, недостатком этого является то, что мой код стал намного более беспорядочным, особенно в этом конкретном случае попытки парсить JSON.

Это мой код:

if let dic = try NSJSONSerialization.JSONObjectWithData(currentData!, options: NSJSONReadingOptions.AllowFragments) as? [String: AnyObject] {
    student["roll"] = dic["roll"] as? Int
    student["firstName"] = dic["name"]?.componentsSeparatedByString(" ").first
    student["lastName"] = dic["name"]?.componentsSeparatedByString(" ").last

    var subjects = [[String: AnyObject?]]()

    if let dicSubs = dic["subs"] as? [AnyObject] {
        for dicSub in dicSubs {
            var sub = [String: AnyObject?]()

            sub["name"] = dicSub["name"] as? String

            if let code = dicSub["code"] as? String {
                sub["code"] = Int(code)
            }
            if let theory = dicSub["theory"] as? String {
                sub["theory"] = Int(theory)
            }
            if let prac = dicSub["prac"] as? String {
                sub["prac"] = Int(prac)
            }

            subjects.append(sub)
        }
    }

    student["subjects"] = subjects
}

Таким образом, полученный результат замусорен опционами, что делает его практически непригодным для использования. У меня такое чувство, что я делаю что-то не так, поскольку версия этого кода на языке Objective C намного чище и короче.

Есть ли способ сделать это лучше?

Если необходимо, вот результат:

[  
  roll:Optional(1234567),
  firstName:Optional("FIRSTNAME"),
  lastName:Optional("LASTNAME"),
  subjects:Optional(  [  
    [  
      "code":Optional(123),
      "theory":Optional(73),
      "name":Optional(REDACTED)
    ],
    [  
      "code":Optional(123),
      "theory":Optional(76),
      "name":Optional(REDACTED)
    ],
    [  
      "code":Optional(123),
      "theory":Optional(48),
      "name":Optional(REDACTED)
    ],
    [  
      "code":Optional(123),
      "theory":Optional(75),
      "prac":Optional(19),
      "name":Optional(REDACTED)
    ],
    [  
      "code":Optional(123),
      "theory":Optional(69),
      "prac":Optional(18),
      "name":Optional(REDACTED)
    ],
    [  
      "code":Optional(123),
      "theory":Optional(63),
      "prac":Optional(28),
      "name":Optional(REDACTED)
    ]
  ]  )
])

person duci9y    schedule 17.07.2015    source источник
comment
Не могли бы вы добавить расширение к словарям Swift, которое превращает возможную строку в необязательный Int?   -  person gnasher729    schedule 17.07.2015
comment
@ gnasher729 Да, мне это пришло в голову, но мне кажется, что это хакерское решение, поэтому мне было интересно, есть ли у людей лучшие предложения.   -  person duci9y    schedule 17.07.2015


Ответы (2)


Разверните опции (вы уже делаете это для некоторых из них, сделайте это для всех):

if let roll = dic["roll"] as? Int {
    student["roll"] = roll
}

Кроме того, инициализатор Int(...) возвращает необязательный элемент, поэтому его также необходимо развернуть с помощью привязки необязательного параметра:

if let code = dicSub["code"] as? String, let myInt = Int(code) {
    sub["code"] = myInt
}
person Eric Aya    schedule 17.07.2015
comment
Это лучший способ пойти? Это добавило бы 3 строки кода для каждого ключа, который я разбираю, и мне было интересно, можно ли его сократить. - person duci9y; 17.07.2015
comment
Да, это способ сделать это вручную. Если вы сочтете это громоздким, вы можете использовать библиотеку, такую ​​как SwiftyJSON, которая автоматически развернет все для вас, но добавит шаблон и накладные расходы в других местах, так что... ваш выбор. :) Оба пути в порядке. Лично я предпочитаю вручную, когда JSON не слишком сложен, так я точно знаю, что происходит. - person Eric Aya; 17.07.2015
comment
Спасибо! Мне нравятся ваши рассуждения о знании того, что происходит. Думаю, я пойду по этому пути, хотя попробую SwiftyJSON. - person duci9y; 17.07.2015
comment
Пожалуйста. :) Действительно, декодирование JSON вручную в Swift иногда может быть многословным, но я считаю, что на самом деле это не проблема: со временем вы будете добавлять свои собственные расширения и методы, чтобы не вводить одно и то же снова и снова. - person Eric Aya; 17.07.2015

В зависимости от скорости, которая вам нужна, я бы предложил вам использовать стороннюю библиотеку для связи JSON. Хороший пример:

SwiftyJSON

Вы можете проверить учебник об этом здесь:

http://www.raywenderlich.com/82706/working-with-json-in-swift-tutorial

person hris.to    schedule 17.07.2015
comment
SwiftyJSON сэкономит вам бессчетное количество часов. Это делает синтаксический анализ JSON таким же простым, как сравнение двух чисел. - person lagoon; 17.07.2015