问题描述
我以前使用过Alamofire,但是没有问题,这次我的json有点奇怪,我找不到通过它的方法。
这是我的json的样子,我对其进行了简化,但是上下文是相同的:
{
"categories": [
{
"categories": {
"id": 1,"name": "A"
}
},{
"categories": {
"id": 2,"name": "B"
}
},{
"categories": {
"id": 3,"name": "C"
}
}]
}
struct Category {
let id: Int
let name: String
init(id: Int,name: String) {
self.id = id
self.name = name
}
}
最后,我的Alamofire request
:
func getCategories(completed: @escaping () -> ()) {
let baseUrl = ""
let api_key = ""
let headers : HTTPHeaders = [
"user-key":api_key
]
Alamofire.request(baseUrl,method: .get,parameters: nil,headers: headers).responseJSON { response in
guard let value = response.value as? [String:Any] else { return }
guard let cats = value["categories"] as? [Category] else { return}
print(cats)
completed()
}
}
Problem
-我已经打印了一个值并且可以正常工作,但是此print(cats)
从未因为之前的行而被调用,它会返回。
看起来我在模型和解析方面有问题,无法弄清原因。
解决方法
Alamofire的responseJSON(completionHandler:)
使用原生jsonObject(with:opt:)的JSONSerialization功能。这是将json数据转换为Swift本机类型。每当有这样的json对象:
{
"id": 3,"name": "C"
}
将被翻译成字典[String: Any]
。每当有这样的json对象的json数组:
[
{
"id": 1,"name": "A"
}
]
将被翻译成字典[[String: Any]]
的数组。因此,您的getCategories(completed:)
函数很可能应该像这样:
func getCategories(completed: @escaping () -> ()) {
let baseUrl = ""
let api_key = ""
let headers: HTTPHeaders = [
"user-key":api_key
]
Alamofire.request(baseUrl,method: .get,parameters: nil,headers: headers).responseJSON { response in
var categories = [Category]()
if let json = response.value as? [String: Any] {
if let array = json["categories"] as? [[String: Any]] {
for category in array {
let categoryDetails = category["categories"] as? [String: Any]
if let id = categoryDetails?["id"] as? Int,let name = categoryDetails?["name"] as? String {
categories.append(Category(id: id,name: name))
}
}
}
}
print(categories)
completed()
}
}
这有很多样板代码。您应该考虑使用本机Codable类型和JSONDecoder类型。它需要更少的代码。