Отсутствует аргумент для параметра "делегат" в вызове // Файл 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
.