Как я могу разобрать JSON с alamofire - PullRequest
1 голос
/ 27 апреля 2019

Я хочу разобрать JSON с Alamofire. Я вижу 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 
    }
   ]
}

Ответы [ 2 ]

0 голосов
/ 27 апреля 2019

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.

0 голосов
/ 27 апреля 2019

Ваш ответ - объект 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 с responseData Alamofire, ниже приведен пример

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)
        }
    }
}
...