我不是 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)
}
}
}
我已经包括了错误消息,“不工作”,但感觉其他部分也有问题(比如在初始化中期待字典)。无法推断“ key ”是什么意思,我是否需要进行其他更改?
编辑#1
我已将我的位置更新为此以反射(reflect)您的建议:
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).
像这样:
我认为 guard
语句会阻止这种情况。我错过了什么?
最佳答案
您可以将 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]]
来表示字典数组,其中的值都是字符串,如您的示例所示。如果值包括字符串以外的对象(数字、 bool 值等),则您可以使用 [[String: AnyObject]]
。
在您的修订版中,您向我们展示了更完整的 Location
实现。您应该避免 as!
强制转换,而是在 guard
语句中使用 as?
:
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
}
}
关于swift - 可以将此 Alamofire 结果转换为字典数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37956463/