我如何用 alamofire 解析 JSON

Posted

技术标签:

【中文标题】我如何用 alamofire 解析 JSON【英文标题】:How I can parse JSON with alamofire 【发布时间】:2019-04-27 08:19:05 【问题描述】:

我想用 Alamofire 解析 JSON。我可以在项目中看到 30 个元素,但我无法解析。错误是

无法将“String”类型的值转换为预期的参数类型“Int”

Alamofire.request("https://api.github.com/search/repositories?q=+language:swift&sort=stars&order=desc&page=%5Bdf6f765c265c02c1ef978f6ee3207407cf878f4d").responseJSON  response in

    //print(response)

    if let itemJson = response.result.value
        let itemObject : Dictionary = itemJson as!    Dictionary<String,Any>
        //print(itemObject)
        let items : NSArray = itemObject["items"] as! NSArray
        print(items)

        let name : String = items["name"] as! String // Error is here
        print(name)
    



  "total_count": 551163,
  "incomplete_results": false,
  "items": 
  [
    
      "id": 21700699,
      "node_id": "MDEwOlJlcG9zaXRvcnkyMTcwMDY5OQ==",
      "name": "awesome-ios",
      "full_name": "vsouza/awesome-ios",
      "private": false,
      "owner": 
      
        "login": "vsouza",
        "id": 484656,
       
      "forks": 5231,
      "open_issues": 4,
      "watchers": 31236,
      "default_branch": "master",
      "score": 1.0 
    ,

    
      "id": 21700699,
      "node_id": "MDEwOlJlcG9zaXRvcnkyMTcwMDY5OQ==",
      "name": "awesome-ios",
      "full_name": "vsouza/awesome-ios",
      "private": false,

      "owner": 
      
        "login": "vsouza",
        "id": 484656,
       

      "forks": 5231,
      "open_issues": 4,
      "watchers": 31236,
      "default_branch": "master",
      "score": 1.0 
    
   ]

【问题讨论】:

【参考方案1】:

您的响应是一个称为字典的 JSON 对象,请使用以下行

let itemObject = response.result.value as? [String : Any]

继续解析内部数组items

if let array = itemObject?["items"] as? [[String : Any]] 
    for dict in array 
        guard
            let id = dict["id"] as? Int,
            let name = dict["name"] as? String,
            let owner = dict["owner"] as? [String : Any],
            let ownerId = owner["id"] as? Int

        else 
            print("Error parsing \(dict)")
            continue
        

        print(id, ownerId, name)
    

不要手动解析 JSON,而是使用 Codable 和 Alamofire 的 responseData,下面是一个示例

struct Item: Decodable 
    let id: Int
    let name: String
    let owner: Owner

struct Owner: Decodable 
    let id: Int
    let login: String

struct PageData: Decodable 
    let totalCount: Int
    let incompleteResults: Bool
    let items: [Item]

    enum CodingKeys: String, CodingKey 
        case totalCount = "total_count"
        case incompleteResults = "incomplete_results"
        case items
    


Alamofire.request("URL").responseData  response in
    switch response.result 
    case .failure(let error):
        print(error)
    case .success(let data):
        do 
            let pageData = try JSONDecoder().decode(PageData.self, from: data)
            print(pageData, pageData.items.first?.name ?? "", pageData.items.first?.owner.id ?? 0)
         catch let error 
            print(error)
        
    

【讨论】:

嘿 AamirR,我想问最后一个问题。我还需要所有者 ID。你能帮我解决这个问题吗【参考方案2】:

items——正如复数形式所暗示的——是一个包含多个items的数组。你必须使用循环。

并且使用 Swift 原生类型并且不要注释编译器可以推断的类型

if let itemJson = response.result.value as? Dictionary<String,Any>,
   let items = itemJson["items"] as? [[String:Any]] 
     for item in items 
         let name = item["name"] as? String
         print(name ?? "n/a")
           

考虑使用Decodable

【讨论】:

以上是关于我如何用 alamofire 解析 JSON的主要内容,如果未能解决你的问题,请参考以下文章

“”和“”有啥区别,我如何用字符来测试前者?

我如何用 pandas.groupby() 总结时间戳

看我如何用 20 行代码改变女神看我的眼神

我如何用 Jasmine 和 Karma 覆盖承诺响应

我如何用 pafy 为进度条制作线程

如果一个元素正在被动画,我如何用 jQuery 找出?