Мой код запроса API вызывает ошибку, которую я не могу отладить или понять

Я не уверен, где определить проблему в этом коде

var events = [Events]()

    let URL_GET_DATA = "http://192.168.100.4/PrototypeWebService/api/getevents.php"

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        Alamofire.request(URL_GET_DATA).responseJSON{ response in
            if let json = response.result.value {
                print(json)
                let swiftvar = JSON(json).array
                for i in 0..<(swiftvar?.count)! {
                    let jsonObject = swiftvar?[i].object
                    self.events.append(jsonObject as! Events)
                }
                self.EventTable.reloadData()
            }
        }
    } 

Я ожидаю, что он создаст массив объектов типа Events, но выдает эту ошибку:

Thread 1: EXC_BREAKPOINT (code=1, subcode=0x102ca0f4c

Код очень небезопасен, вы должны обернуть инициализацию неизменяемого значения swiftvar в предложение if let. Кроме того, принудительное применение jsonObject as! Events является возможной точкой отказа, и я действительно сомневаюсь, что это вообще можно опустить. Пожалуйста, попытайтесь написать свой код, избегая принудительного приведения типов.

Isaaс Weisberg 28.05.2019 14:12
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
70
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ваш код неправильно использует API SwiftJSON. Виновником является линия

jsonObject as! Events

Если бы вы на самом деле писали код безопасным образом, используя as? динамический оператор приведения вниз, компилятор с радостью сообщил бы вам, что тип Events и тип jsonObject являются частями отдельных иерархий типов, и поэтому приведение вниз всегда будет неудачным.

Согласно документации SwiftJSON, которую можно найти по адресу https://github.com/SwiftyJSON/SwiftyJSON, фреймворк управляет десериализацией, однако его базовый API не предоставляет никаких средств для заполнения объектов, и поэтому это задача программистов.

Скажем, тип Events имеет 2 сохраненных свойства, let string: String и let int: Int. Чтобы создать объект Events из проанализированного объекта JSON, вам необходимо извлечь значения вручную как таковые.

let string = jsonObject["name"].string
let int = jsonObject["int"].int

а затем вы должны передать эти значения в свой собственный конструктор как таковой

let events = Events(string, int)

Только после этого у вас действительно будет объект Events, который вы сможете использовать.

Обновлено: также с момента выпуска Swift 4 существует протокол Codable и тип JSONDecoder, которые обеспечивают надежные, гибкие и безопасные средства для декодирования ваших полезных данных json, представленных объектом Data, и вам, вероятно, следует отказаться от SwiftyJSON, потому что это ненужный зависимость.

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

Carl 01.06.2019 11:06

Если бы вы могли помочь мне с образцом учебника

Carl 01.06.2019 11:13
Ответ принят как подходящий

Прежде всего, вам предлагается отказаться от SwiftyJSON в пользу Codable.

Ошибка возникает из-за того, что объект (Swifty)JSON не может быть приведен к пользовательской структуре или классу.

Вы должны передать значение JSON инициализатору пользовательской структуры.

struct Event { // it's highly recommended to name this kind of object in singular form
   let varA : String
   let varB : Int

   init(json: JSON) {
      self.varA = json["varA"].string ?? ""
      self.varB = json["varB"].int ?? 0
   }
}

И, пожалуйста, никогда не используйте циклы на основе индекса, если вам вообще не нужен индекс. Создайте экземпляр Event из объекта JSON и добавьте его

guard let swiftvar = JSON(json).array else { return }
for item in swiftvar {
     let event = Event(json: item)
     self.events.append(event)
}

или еще проще

guard let swiftvar = JSON(json).array else { return }
self.events = swiftvar.map{ Event(json: $0) } 

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

Carl 01.06.2019 11:06

Если бы вы могли помочь мне с образцом учебника

Carl 01.06.2019 11:12

Я столкнулся с ошибкой времени выполнения, которая говорит Дополнительный аргумент 'json' в вызове для обоих вариантов.

Carl 01.06.2019 11:52

В какой строке?

vadian 01.06.2019 11:55

Здесь: пусть событие = события (json: элемент)

Carl 01.06.2019 11:57

Вы должны добавить (и настроить) предлагаемый метод init в классе Event(s)

vadian 01.06.2019 11:59

В классе событий написано Использование необъявленного типа JSON

Carl 01.06.2019 12:05

Поскольку вы используете SwiftyJSON, в любом случае он должен быть доступен

vadian 01.06.2019 12:07

Я решил это. Я забыл импортировать SwiftyJSON в класс событий

Carl 01.06.2019 12:09

Готово с настройками.. Он по-прежнему показывает Дополнительный аргумент 'json' в вызове

Carl 01.06.2019 12:11

Я не знаю, какие еще инициализаторы содержит класс. Есть ли метод init() без параметров? Если да, удалите его

vadian 01.06.2019 12:17

Ну, это хорошо работает со вторым вариантом, но ничего не отображает в моей таблице.

Carl 01.06.2019 12:32

это другой вопрос

vadian 01.06.2019 12:37

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