无法使用Alamofire解析json

问题描述

我以前使用过Alamofire,但是没有问题,这次我的json有点奇怪,我找不到通过它的方法
这是我的json的样子,我对其进行了简化,但是上下文是相同的:

    {
        "categories": [
            {
                "categories": {
                    "id": 1,"name": "A"
                }
            },{
                "categories": {
                    "id": 2,"name": "B"
                }
            },{
                "categories": {
                    "id": 3,"name": "C"
                }
            }]
}

此外,我有一个Category结构,如下所示:

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类型。它需要更少的代码。