Отсутствует аргумент для параметра "делегат" в вызове // Файл JSON поврежден в SWIFT?

Я слежу за учебником электронного класса для SWIFT // XCODE 11.4, и мне нужно получить данные из Open Weather API и отобразить их в интерфейсе, где люди могут вводить город, а контроллер представления будет отображать температуру, значок облака и описание.

Учебное пособие по приложению Clima

Я использую дизайн шаблона MVC и дизайн делегата для выполнения этого руководства. Мои быстрые файлы следующие:

Файлы Swift в шаблоне проектирования MVC

Вот коды в каждом из важных файлов:

I. Папка модели

WeatherManager.swift

protocol WeatherManagerDelegate {
    func didUpdateWeather(weather: WeatherModel)
}

struct WeatherManager {
    let weatherURL = "https://api.openweathermap.org/d.5/weather?appid=c8b50079338280b47a65dd6082551e3b&units=imperial"

    let delegate: WeatherManagerDelegate?



    func fetchWeather(cityName: String) {
        let urlString = "\(weatherURL)&q=\(cityName)"
        performRequest(urlString: urlString)
    }

    func performRequest(urlString: String) {

        //create a URL
        if let url = URL(string: urlString) {

            //create a URLSession
            let session = URLSession(configuration: .default)

            //give session a task
            let task = session.dataTask(with: url) { (data, response, error) in
                if error != nil {
                    print(error!)
                    return //exit out of the func if there is an error
                }

                if let safeData = data {

                    if let weather =  self.parseJSON(weatherData: safeData) {
                    self.delegate?.didUpdateWeather(weather: weather)
                    }
                }
            }
            //start the tast
            task.resume()
        }
    }

    func parseJSON (weatherData: Data) -> WeatherModel? {
        let decoder = JSONDecoder()
        do {
            let decodedData = try decoder.decode(WeatherData.self, from: weatherData)
            let id = decodedData.weather[0].id
            let temp = decodedData.main.temp
            let name = decodedData.name


            let weather = WeatherModel(conditionId: id, cityName: name, temperature: temp)
            return weather

        } catch {
            print(error)
            return nil
        }
    }

}

WeatherData.swift

struct WeatherData: Codable {
    let name: String
    let main: Main
    let weather: [Weather]
}

struct Main: Codable {
    let temp: Double
}

struct Weather: Codable {
    let id: Int
}

WeatherModel.swift

struct WeatherModel {
    let conditionId: Int
    let cityName: String
    let temperature: Double

    var temperatureString: String {
        return String(format: "%.1f", temperature)
    }

    var conditionName: String {
        switch conditionId {
        case 200...232:
            return "cloud.bolt"
        case 300...321:
            return "cloud.drizzle"
        case 500...531:
            return "cloud.rain"
        case 600...622:
            return "cloud.snow"
        case 701...781:
            return "cloud.fog"
        case 800:
            return "sun.max"
        case 801...804:
            return "cloud.bolt"
        default:
            return "cloud"
        }
    }

}

II. Контроллер

WeatherViewController.swift (место, где ошибка)

class WeatherViewController: UIViewController, UITextFieldDelegate, WeatherManagerDelegate {

    @IBOutlet weak var conditionImageView: UIImageView!
    @IBOutlet weak var temperatureLabel: UILabel!
    @IBOutlet weak var cityLabel: UILabel!
    @IBOutlet weak var searchTextField: UITextField!

    var weatherManager = WeatherManager()

    override func viewDidLoad() {

        super.viewDidLoad()
        weatherManager.delegate = self

        searchTextField.delegate = self
    }

    @IBAction func searchPressed(_ sender: UIButton) {
        searchTextField.endEditing(true)
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        searchTextField.endEditing(true)
        print(searchTextField.text!)
        return true
    }

    func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
        if textField.text != "" {
            return true
        } else {
            textField.placeholder = "Type something..."
            return false
        }
    }

    func textFieldDidEndEditing(_ textField: UITextField) {
        if let city = searchTextField.text {
            weatherManager.fetchWeather(cityname: city)
        }

        searchTextField.text = ""

    }

    func didUpdateWeather(weather: WeatherModel) {
        print(weather.temperature)
    }


}

Вот сообщение об ошибке: Отсутствует аргумент для параметра "делегат" в вызове Сообщение об ошибке в WeatherViewControl.swift

И когда я нажимаю кнопку запуска, я также получаю эту ошибку в консоли отладки:

данные Недопустимое значение около символа 0.})))

Ошибка в консоли отладки

Что мне делать, чтобы избавиться от этих ошибок?

2 ответа

Решение

Отсутствует аргумент для параметра "делегат" в вызове

Когда struct необходимо создать значение для каждого свойства.

Если для каждого свойства указано значение по умолчанию и нет определяемого пользователем инициализатора, то Swift создаст инициализатор по умолчанию дляstruct.

Если есть хотя бы одно свойство без значения по умолчанию и нет определяемого пользователем инициализатора, тогда Swift создаст поэлементный инициализатор, который имеет один параметр для каждого свойства без значения по умолчанию.

Например, ваш тип:

struct WeatherModel {
   let conditionId: Int
   let cityName: String
   let temperature: Double
...

имеет три свойства без значений по умолчанию. Если вы начнете печатать:

let myWeatherModel = WeatherModel(

а затем возьмите предложенное завершение и получите (что-то вроде):

let wm = WeatherModel(conditionId: <Int>, cityName: <String>, temperature: <Double>)

Завершение показывает поэлементный инициализатор.

Ваш тип, вызывающий ошибку:

struct WeatherManager {
   let weatherURL = "https://api.openweathermap.org/d.5/weather?appid=c8b50079338280b47a65dd6082551e3b&units=imperial"
   let delegate: WeatherManagerDelegate?

который имеет два свойства, только одно из которых имеет значение по умолчанию и не имеет инициализаторов, поэтому Swift автоматически создаст членный инициализатор.

Пока нет ничего плохого.

Строка с ошибкой:

var weatherManager = WeatherManager()

Здесь вы пытаетесь создать WeatherManager без вызова инициализатора для каждого члена, поэтому Swift выдает сообщение об ошибке.

Если вы нажмете на само сообщение об ошибке, вы увидите, что предлагается исправление, щелкните по нему, и Swift изменит ваш код на:

var weatherManager = WeatherManager(delegate: <WeatherManagerDelegate?>)

Выберите <WeatherManagerDelegate?> и введите значение, которое вы хотите передать.

HTH

Вам нужно изменить ключевое слово «let» на «var» в let delegate: WeatherManagerDelegate?в struct WeatherManager.

Другие вопросы по тегам