首页 > 解决方案 > 调用中缺少参数“委托”的参数 // JSON 文件在 SWIFT 中损坏?

问题描述

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

Clima 应用教程

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

MVC 设计模式中的 Swift 文件

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

一、模型文件夹

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(出错的地方)

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中的调用错误消息中缺少参数“delegate”的参数

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

dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: “给定的数据不是有效的 JSON。”,underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840“字符 0 周围的值无效。” UserInfo={NSDebugDescription=字符 0 周围的值无效。})))

调试控制台中的错误

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

标签: ios13swift5swift5.1swift5.2ios13.4

解决方案


调用中缺少参数“委托”的参数

当 astruct为每个属性创建一个值时是必需的。

如果每个属性都指定了默认值并且没有用户定义的初始化器,那么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?>并输入您希望传递的值。

高温高压


推荐阅读