Swift 中太多的选项使代码混乱

Too many optionals making code messy in 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
}

以这种方式生成的输出中充斥着 Optionals,几乎无法使用。我觉得我做错了什么,因为此代码的 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)
    ]
  ]  )
])

展开选项(您已经为其中一些做了,为所有做):

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

此外,初始化器 Int(...) returns 是可选的,因此您也必须使用可选绑定来解包它:

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

根据您需要的速度,我建议您使用一些第三方库进行 JSON 通信。一个很好的例子是:

SwiftyJSON

你可以在这里查看有关它的教程:

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