Прежде всего, вам нужно создать модель, чтобы вы могли преобразовать свой JSON в пригодные для использования объекты. Для этого рекомендуется использовать протокол Codable, который автоматически сопоставит ваши JSON ключи с переменной структуры / класса
struct Event: Codable {
var name: String!
var date: String!
var time: String!
var am_or_pm: String!
var day: String!
var description: String!
}
struct Events: Codable {
var events: [Event]!
}
Теперь, когда у вас есть модель, которая будет сгенерирована из JSON, вам нужно декодировать ваш JSON в вашу модель. Есть много способов сделать это, мне нравится использовать JSONEncoder / JSONDecoder. Итак, допустим, ваша строка JSON хранится в переменной myJsonString
, вам нужно будет
if let jsonData = myJsonString.data(using: .utf8) {
do {
let events = try JSONDecoder().decode(Events.self, from: jsonData)
} catch {
print("Error decoding json!", error.localizedDescription)
}
} else {
print("Failed to get bytes from string!")
}
. Теперь мы можем превратить этот блок кода в функцию, которая возвращает события, или ноль, если он не может декодировать строку.
func getEvents(from jsonString: String) -> Events? {
guard let jsonData = myJsonString.data(using: .utf8) else { return nil }
return try? JSONDecoder().decode(Events.self, from: jsonData)
}
Круто! Теперь мы можем легко получить наши события на основе строки JSON! Все, что нам нужно сделать, это заполнить tableView! Для этого мы можем создать несколько функций в нашей структуре Events
, которые будут возвращать только то, что нам нужно для заполнения нашего раздела. Первая функция вернет разделы для нашего tableView, а вторая вернет все элементы для данного раздела. Давайте изменим Events
struct
struct Events: Codable {
var events: [Event]!
func getSections() -> [String] {
return Array(Set(self.events.map { $0.date }))
}
func getItems(forSection dateSection: String) -> [Section] {
return self.events.filter {$0.date == dateSection}
}
}
Теперь в вашем классе источника данных TableView вам нужно использовать созданную нами модель. Я сделаю для вас пример
class YourTableView: UIViewController, UITableViewDataSource, UITableViewDelegate {
// This is loaded from the getEvents function!
var events: Events!
func numberOfSections (in tableView: UITableView) -> Int {
return self.events.getSections().count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let dateSection = self.events.getSections()[section]
return self.events.getItems(forSection: dateSection ).count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let dateSection = self.events.getSections()[indexPath.section]
let currentEvent = self.getItems(forSection: dateSection)
// Build your cell using currentEvent
}
}
Вероятно, вы получаете эти JSON из Интернета, поэтому вам нужно обрабатывать состояние «загрузка», когда вы возвращаете JSON из API. Это легко сделать, превратив events
var в необязательный, установив его при получении JSON и перезагрузив данные из tableView