我在解析新版Pokemon API中的JSON数据时遇到问题,特别是在“类型”键中使用“名称”的值。
Json看起来像这样:
"types": [
{
"slot": 2,
"type": {
"name": "poison",
"url": "https://pokeapi.co/api/v2/type/4/"
}
},
{
"slot": 1,
"type": {
"name": "grass",
"url": "https://pokeapi.co/api/v2/type/12/"
}
}
],
"weight": 69
在Alamofire中解析后,我得到了下一个解决方案:
if let types = dict["types"] as? [Dictionary<String, String>] , types.count > 0 {
if let type = types[0]["type"] as? Dictionary<String, String> {
if let name = type["name"] {
self._type = name.capitalized
}
}
print("TypeAA: \(self._type)")
} else {
self._type = ""
}
这行也不会执行。 print(“ TypeAA:(self._type)”) 请告知,如何正确解析并获取名为“ type”的键中“ name”的值?
答案 0 :(得分:1)
您无法执行dict["types"] as? [Dictionary<String, String>]
,因为types
中的项目无法转换为Dictionary<String, String>
。 item
具有整数,如"slot": 2
和字典"type": {...}
。因此,必须首先将其强制转换为[String : Any]
。
if let types = dict["types"] as? [Any], types.count > 0 {
if let firstObject = (types.first as? [String : Any]),
let type = firstObject["type"] as? [String : String],
let name = type["name"] {
self._type = name.capitalized
}
}
如果需要每个项目的名称,则必须遍历items
数组。
答案 1 :(得分:0)
或在此处尝试类似的操作:
if let types = dict["types"] as? [Any] {
guard types.count > 0 else {
return
}
for elment in types {
if let type = elment["type"] as? [String:Any] {
let name = type["name"] as! String
// Do what you want with it here
}
}
}
答案 2 :(得分:0)
您可以使用AlamofireObjectMapper轻松解析来自Alamofire的JSON响应。
class PokemonTypesResponse: Mappable {
var types:[Types]?
var weight:Int?
required init?(map: Map){
}
func mapping(map: Map) {
types <- map["types"]
weight <- map["weight"]
}
}
class Types: Mappable {
var slot:Int?
var name:String?
var url:String?
required init?(map: Map){
}
func mapping(map: Map) {
slot <- map["slot"]
type <- map["type.name"]
url <- mapp["type.url"]
}
}
使用alamofire执行请求并使用
.responseArray { (response: DataResponse<[PokemonTypesResponse]>) in
switch response.result {
case .success:
//this is the response as PokemonTypesResponse
response.result.value
case .failure(let error):
print(error)
}
映射JSON结果 我还没有测试过,而是根据经验编写的。 我希望它能正常工作并且易于理解。
答案 3 :(得分:0)
您的代码不起作用,因为第一个条件下调失败。
键types
的值为[Dictionary<String, Any>]
(请注意JSON中的嵌套字典),而不是[Dictionary<String, String>]
。
所以基本上可以用
if let types = dict["types"] as? [Dictionary<String, Any>] , types.count > 0 {
if let type = types[0]["type"] as? Dictionary<String, String> {
if let name = type["name"] {
self._type = name.capitalized
}
}
print("TypeAA: \(self._type)")
} else {
self._type = ""
}
但是厄运金字塔很麻烦,并且从不使用.count > 0
检查空数组,因此效率更高
if let types = dict["types"] as? [Dictionary<String, Any>],
let firstType = types.first, let typeInfo = firstType["type"] as? Dictionary<String, String>,
let name = typeInfo["name"] {
self._type = name.capitalized
print("TypeAA:", self._type)
} else {
self._type = ""
}
如果您需要考虑所有名称,则必须使用循环
if let types = dict["types"] as? [Dictionary<String, Any>] {
for type in types {
if let typeInfo = type["type"] as? Dictionary<String, String>,
let name = typeInfo["name"] {
print("TypeAA:", name)
}
}
} else {
self._type = ""
}
如果要打印所有名称,请用逗号分隔
if let types = dict["types"] as? [Dictionary<String, Any>] {
let names = types.compactMap { type -> String? in
guard let typeInfo = type["type"] as? Dictionary<String, String>,
let name = typeInfo["name"] else { return nil }
return name
}
print(names.joined(separator: ", "))
}