Как декодировать и получать значения из ответа API, который хранится в словаре в swift

#ios #swift #xcode

#iOS #swift #xcode

Вопрос:

У меня есть ответ API, который хранится в словаре, я создал структуры в разных папках, но когда я пытаюсь их декодировать с помощью метода decode, он выдает ошибку, в ошибке упоминается, что «Данные не могут быть прочитаны, потому что они не в правильном формате». , вот код и структуры, которые я создал:

 import UIKit

class ViewController: UIViewController {

    @IBOutlet var cityButtons: [UIButton]!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }


    @IBAction func handleSelection(_ sender: UIButton) {
        cityButtons.forEach{ (button) in
            UIView.animate(withDuration: 0.3) {
                button.isHidden = !button.isHidden
                self.view.layoutIfNeeded()
            }
            
        }
    }
    enum Cities:String {
        case amman = "Amman"
        case azzerqa = "Az zerqa"
        case irbid = "Irbid"
        case aqaba = "Aqaba"
    }
    @IBAction func cityTapped(_ sender: UIButton) {
        guard let title = sender.currentTitle, let City = Cities(rawValue: title)
            
            else {
            return
        }
        var city:String
        switch City {
        case .amman:
            city = "Amman"
        case .azzerqa:
                  city = "zerqa"
        case .irbid:
            city = "Irbid"
        case .aqaba:
            city = "Aqaba"
        }
        
        let url = URL(string: "https://api.weatherapi.com/v1/current.json?key={ket}amp;q=(city)")
        guard url != nil else {
            print("error creating URL Object")
            return
        }
        var request = URLRequest(url: url!, cachePolicy: .useProtocolCachePolicy , timeoutInterval: 10)
        let headers = ["Content-Type" : "application/json"]
        request.allHTTPHeaderFields = headers
        request.httpMethod = "GET"
        let session = URLSession.shared
        let dataTask = session.dataTask(with: request) {(data, response, error) in
            if error == nil amp;amp; data != nil {
                do {
                    let dictionary = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? [String:Any]
                 let decoder = JSONDecoder()
                    print(dictionary)
                    do {
                        let weatherdatadecoded = try decoder.decode(WeatherData.self, from: data!)
                        print(weatherdatadecoded)
                    }
                    catch {
                        print(error.localizedDescription)
                    }
                }
                catch {
                    print(error.localizedDescription)
                }
                
            }
            
        }
        dataTask.resume()
    }
}
  

и вот структуры (каждая в отдельном файле):

 import Foundation

struct WeatherData : Codable {
    var location: Location?
    var current: Current?
}

import Foundation

struct Location : Codable {
    var name: String = ""
    var region: String = ""
    var localtime: String = ""
    var country: String = ""
}

import Foundation

struct Current : Codable {
    var temp_c = 0.0
    var is_day = false
    var condition: Condition?
}

import Foundation

struct Condition : Codable {
    var text: String = ""
    var icon: String = ""
    var code: Int = 0
}
  

Комментарии:

1. Вы получите гораздо более значимое сообщение об ошибке, если измените print(error.localizedDescription) на print(error) . Кроме того, вам следует удалить ключ api перед публикацией вашего кода в режиме онлайн

2. @JoakimDanielson Я удалил ключ и попробовал ошибку print, я получил эту ошибку: typeMismatch(Swift. Bool, Swift. Ошибка декодирования. Контекст(codingPath: [CodingKeys(stringValue: «current», intValue: nil), CodingKeys(stringValue: «is_day», intValue: nil)], debugDescription: «Ожидалось декодировать Bool, но вместо этого найдено число»., Лежащая в основе ошибка: nil))

3. Вы проанализировали ошибку, говорит ли она вам что-нибудь?

4. @JoakimDanielson Я понял это, is_day в struct был объявлен как bool, а его значение равно int, я изменил его, и это сработало, спасибо

5. Отлично, сначала эти сообщения об ошибках могут быть немного пугающими, но как только вы научитесь их читать, они станут понятными и полезными.