可以将这个Alamofire结果转换成一系列字典

时间:2016-06-21 23:59:35

标签: swift dictionary alamofire

我不是iOS开发者,不得不对Swift / AlamoFire项目(不是我的)进行一些更改,而且有点迷失。

我有以下JSON:

{"metro_locations":
 [
   {
     "name":"Ruby Red"
   },
   {
      "name":"Blue Ocean"
    }
  ]
}

课程(我知道这里有问题):

class Location{
  var name=""
  init(obj:tmp){
    self.name=tmp["name"]
  }
}

需要拨打AlamoFire

Alamofire.request(.GET, "https://www.domain.com/arc/v1/api/metro_areas/1", parameters: nil)
  .responseJSON { response in

    if let dataFromNetworking = response.result.value {
      let metroLocations = dataFromNetworking["metro_locations"]
      var locations: [Location]=[]
      for tmp in metroLocations as! [Dictionary] { // <- not working, Generic Paramter 'Key' could not be inferred
        let location=Location.init(obj: tmp)
        locations.append(location)
      }
    }
}

我已经包含错误消息,&#34;没有工作&#34;但是觉得其他部分也存在问题(比如期望在初始化中使用字典)。什么是&#39; Key&#39;无法推断是否意味着我需要做出其他改变?

编辑#1

我已将此位置更新为此以反映您的建议:

  init?(dictionary: [String: AnyObject]) {
    guard let id = dictionary["id"] else { return nil }
    guard let name = dictionary["name"] else { return nil }
    guard let latitude = dictionary["latitude"] else { return nil }
    guard let longitude = dictionary["longitude"] else { return nil }
    self.name = name as! String
    self.id = id as! Int
    self.latitude = latitude as! Double
    self.longitude = longitude as! Double
  }

但是我收到了错误:

Could not cast value of type 'NSNull' (0x10f387600) to 'NSNumber' (0x10f77f2a0).
像这样:

enter image description here

我认为guard语句会阻止这种情况。我错过了什么?

1 个答案:

答案 0 :(得分:1)

您可以将metroLocations转换为字典数组,即:

Array<Dictionary<String, String>>

或者,更简洁:

[[String: String]]

因此:

if let dataFromNetworking = response.result.value {
    guard let metroLocations = dataFromNetworking["metro_locations"] as? [[String: String]] else {
        print("this was not an array of dictionaries where the values were all strings")
        return
    }

    var locations = [Location]()
    for dictionary in metroLocations {
        if let location = Location(dictionary: dictionary) {
            locations.append(location)
        }
    }
}

其中

class Location {
    let name: String

    init?(dictionary: [String: String]) {
        guard let name = dictionary["name"] else { return nil }
        self.name = name
    }
}

显然,我使用[[String: String]]来表示字典数组,其中值都是字符串,如示例所示。如果值包含除字符串以外的对象(数字,布尔值等),则可以使用[[String: AnyObject]]

在您的修订版中,您向我们展示了更完整的Location实施方案。您应该避免as!强制转换,而应在as?语句中使用guard

class Location {
    let id: Int
    let name: String
    let latitude: Double
    let longitude: Double

    init?(dictionary: [String: AnyObject]) {
        guard let id = dictionary["id"] as? Int,
            let name = dictionary["name"] as? String,
            let latitude = dictionary["latitude"] as? Double,
            let longitude = dictionary["longitude"] as? Double else {
                return nil
        }
        self.name = name
        self.id = id
        self.latitude = latitude
        self.longitude = longitude
    }
}