调用中缺少参数 'delegate' 的参数 // JSON 文件在 SWIFT 中损坏?

Missing argument for parameter 'delegate' in call // JSON file corrupted in SWIFT?

我正在关注 SWIFT // XCODE 11.4 的电子class 教程,我必须从 Open Weather API 获取数据并将其显示在人们可以在其中输入城市的界面,视图控制器将显示温度、云图标和描述。

Clima App Tutorial

我正在使用 MVC 模式设计和委托设计来完成本教程。我的swift个文件如下:

Swift Files in MVC Design Pattern

以下是每个重要文件中的代码:

我。模型文件夹

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"
        }
    }

}

二.控制器

WeatherViewController.swift (place where the error is)

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


}

这是错误消息:调用中缺少参数 'delegate' 的参数 Error message in WeatherViewControl.swift

当我点击 运行 按钮时,我在调试控制台中也遇到了这个错误:

dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.})))

Error in the debug console

我应该怎么做才能摆脱这些错误?

Missing argument for parameter 'delegate' in call

struct 被创建时,每个 属性 都需要一个值。

如果每个 属性 都指定了默认值 并且 没有用户定义的初始化程序,那么 Swift 将创建一个 struct.

的默认初始值设定项

如果至少有一个 属性 没有默认值并且没有用户定义的初始值设定项,那么 Swift 将创建一个 memberwise 初始值设定项每个 属性 都有一个参数,没有默认值。

例如你的类型:

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 而不调用成员 wise initalizer,所以 Swift 给你错误信息。

如果您单击错误消息本身,您将看到提供了 修复,单击它,Swift 会将您的代码更改为:

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

Select <WeatherManagerDelegate?> 并输入您希望传递的值。

HTH

您需要在 struct WeatherManager 中将 let delegate: WeatherManagerDelegate? 中的关键字“let”更改为“var”。