Swift 5 - Firebase - 从 Firebase 中的数据创建数组
Swift 5 - Firebase- create array from data in firebase
我正在尝试根据我在 firebase 中的数据创建一个数组,以便我可以将它作为 header 加载到我的表视图中。当我将信息硬编码在代码中的数组中时,我了解如何将数据放入 headers 部分,但我不确定当数据在 Firebase 中时该怎么做,我想将其放入放入一个数组中,然后将其放入 header 中。希望这是有道理的。
我的 Firebase 数据是
usclmainmenu
events
USCL Open House
date:
"September 31 2020"
info:
"Opening to new students"
place:
"USC Lancaster"
time:
"8 pm"
title:
"USCL Open House"
我从 firebase 获取数据的函数是:
private func getEventsFromFirebaseDB()
{
datref = Database.database().reference().child("events")
datref.observe(DataEventType.value, with: { [weak self] (snapshot) in
guard snapshot.childrenCount > 0 else { return }
var events: [EventsInfo] = []
for event in snapshot.children.allObjects as! [DataSnapshot]
{
let object = event.value as? [String: AnyObject]
let title = object?["title"]
let place = object?["place"]
let info = object?["info"]
let date = object?["date"]
let time = object?["time"]
let event = EventsInfo(title: title as! String, place: place as! String, info: info as! String, time: time as! String, date: date as! String)
events.append(event)
}
self?.eventsFetched(events)
self?.eventTableView.reloadData()
})
}
我的数据模型是:
class EventsInfo {
var title: String
var place: String
var info: String
var time: String
var date: String
init(title: String, place: String, info: String, time: String, date: String) {
self.title = title
self.place = place
self.info = info
self.time = time
self.date = date
}
}
这是我对数据源和委托方法的扩展
extension EventsTableViewController: UITableViewDataSource, UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int
{
sectionNames.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
{
sectionNames[section]
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
let char = sectionNames[section]
return events[char]!.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = eventTableView.dequeueReusableCell(withIdentifier: "eventsCell") as! EventsTableViewCell
let char = sectionNames[indexPath.section]
let event = events[char]![indexPath.row]
cell.eventTitleLabel.text = event.title
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "showEvent", sender: self)
}
问题中未提及要用作部分 headers 的字符串,但根据先前的问题,我认为这些部分是事件日期。然后在该日期发生的事件将在该日期部分中列出。
此答案中的代码未经测试,它只是众多选项中的一个。我还稍微改变了动态,将更多的责任放在 EventInfo class 逻辑而不是循环中处理快照。
首先,我们从 object 开始保存事件详细信息。注意它是使用 Firebase Datasnapshot 初始化的。万一出现问题,它会利用可选值的默认值。另请注意,我添加了一个 eventID,用于跟踪 Firebase 密钥,以便稍后可以通过该 ID 更改或删除 object。
class EventInfo {
var eventId: String
var title: String
var place: String
var date: String
init(eventSnap: DataSnapshot) {
self.eventId = eventSnap.key
self.title = eventSnap.childSnapshot(forPath: "title").value as? String ?? "No Title"
self.place = eventSnap.childSnapshot(forPath: "title").value as? String ?? "No Place"
self.date = eventSnap.childSnapshot(forPath: "date").value as? String ?? "Unknown Date"
}
}
然后是一个 class var 数组来保存所有事件。这将用作部分 headers 和 tableView 数据
的数据源
class EventSectionHeader {
var eventDate = ""
var eventArray = [EventInfo]()
}
然后是一个 class 变量来保存所有的 EventSectionHeaders
var eventSectionArray = [EventSectionHeader]()
最后,读取数据并填充数据源的代码。
func getEventsFromFirebaseDB() {
//var eventArray = [EventInfo]()
let eventRef = Database.database().reference().child("events")
eventRef.observeSingleEvent(of: .value, with: { snapshot in
let allEventSnaps = snapshot.children.allObjects as! [DataSnapshot]
for eventSnap in allEventSnaps {
let event = EventInfo(eventSnap: eventSnap)
if let foundEventSection = self.eventSectionArray.first(where: { [=13=].eventDate == event.date } ) {
foundEventSection.eventArray.append(event) //found same date, add event
} else { //eventSection with this date doesn't exist, add a new section with this date and add this
// event to that new section
let eventSection = EventSectionHeader()
eventSection.eventDate = event.date
self.eventSectionArray.append(eventSection)
}
}
self.tableView.reloadData()
})
}
以上代码一次读入所有事件,不留下观察者。它遍历快照中的所有事件,为每个事件创建 EventObject,并检查是否有任何事件日期(该部分)已经存在。
如果是这样,它将添加到该部分日期数组的事件。
如果不是,则创建一个新的 EventSectionHeader,设置日期并添加事件。
我正在尝试根据我在 firebase 中的数据创建一个数组,以便我可以将它作为 header 加载到我的表视图中。当我将信息硬编码在代码中的数组中时,我了解如何将数据放入 headers 部分,但我不确定当数据在 Firebase 中时该怎么做,我想将其放入放入一个数组中,然后将其放入 header 中。希望这是有道理的。
我的 Firebase 数据是
usclmainmenu
events
USCL Open House
date:
"September 31 2020"
info:
"Opening to new students"
place:
"USC Lancaster"
time:
"8 pm"
title:
"USCL Open House"
我从 firebase 获取数据的函数是:
private func getEventsFromFirebaseDB()
{
datref = Database.database().reference().child("events")
datref.observe(DataEventType.value, with: { [weak self] (snapshot) in
guard snapshot.childrenCount > 0 else { return }
var events: [EventsInfo] = []
for event in snapshot.children.allObjects as! [DataSnapshot]
{
let object = event.value as? [String: AnyObject]
let title = object?["title"]
let place = object?["place"]
let info = object?["info"]
let date = object?["date"]
let time = object?["time"]
let event = EventsInfo(title: title as! String, place: place as! String, info: info as! String, time: time as! String, date: date as! String)
events.append(event)
}
self?.eventsFetched(events)
self?.eventTableView.reloadData()
})
}
我的数据模型是:
class EventsInfo {
var title: String
var place: String
var info: String
var time: String
var date: String
init(title: String, place: String, info: String, time: String, date: String) {
self.title = title
self.place = place
self.info = info
self.time = time
self.date = date
}
}
这是我对数据源和委托方法的扩展
extension EventsTableViewController: UITableViewDataSource, UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int
{
sectionNames.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
{
sectionNames[section]
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
let char = sectionNames[section]
return events[char]!.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = eventTableView.dequeueReusableCell(withIdentifier: "eventsCell") as! EventsTableViewCell
let char = sectionNames[indexPath.section]
let event = events[char]![indexPath.row]
cell.eventTitleLabel.text = event.title
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "showEvent", sender: self)
}
问题中未提及要用作部分 headers 的字符串,但根据先前的问题,我认为这些部分是事件日期。然后在该日期发生的事件将在该日期部分中列出。
此答案中的代码未经测试,它只是众多选项中的一个。我还稍微改变了动态,将更多的责任放在 EventInfo class 逻辑而不是循环中处理快照。
首先,我们从 object 开始保存事件详细信息。注意它是使用 Firebase Datasnapshot 初始化的。万一出现问题,它会利用可选值的默认值。另请注意,我添加了一个 eventID,用于跟踪 Firebase 密钥,以便稍后可以通过该 ID 更改或删除 object。
class EventInfo {
var eventId: String
var title: String
var place: String
var date: String
init(eventSnap: DataSnapshot) {
self.eventId = eventSnap.key
self.title = eventSnap.childSnapshot(forPath: "title").value as? String ?? "No Title"
self.place = eventSnap.childSnapshot(forPath: "title").value as? String ?? "No Place"
self.date = eventSnap.childSnapshot(forPath: "date").value as? String ?? "Unknown Date"
}
}
然后是一个 class var 数组来保存所有事件。这将用作部分 headers 和 tableView 数据
的数据源class EventSectionHeader {
var eventDate = ""
var eventArray = [EventInfo]()
}
然后是一个 class 变量来保存所有的 EventSectionHeaders
var eventSectionArray = [EventSectionHeader]()
最后,读取数据并填充数据源的代码。
func getEventsFromFirebaseDB() {
//var eventArray = [EventInfo]()
let eventRef = Database.database().reference().child("events")
eventRef.observeSingleEvent(of: .value, with: { snapshot in
let allEventSnaps = snapshot.children.allObjects as! [DataSnapshot]
for eventSnap in allEventSnaps {
let event = EventInfo(eventSnap: eventSnap)
if let foundEventSection = self.eventSectionArray.first(where: { [=13=].eventDate == event.date } ) {
foundEventSection.eventArray.append(event) //found same date, add event
} else { //eventSection with this date doesn't exist, add a new section with this date and add this
// event to that new section
let eventSection = EventSectionHeader()
eventSection.eventDate = event.date
self.eventSectionArray.append(eventSection)
}
}
self.tableView.reloadData()
})
}
以上代码一次读入所有事件,不留下观察者。它遍历快照中的所有事件,为每个事件创建 EventObject,并检查是否有任何事件日期(该部分)已经存在。
如果是这样,它将添加到该部分日期数组的事件。
如果不是,则创建一个新的 EventSectionHeader,设置日期并添加事件。