I am creating an application where users can set reminders for things. The application is connected to a firebase database where all of the data is stored. When the user saves the the event that they are setting this new even should appear on the home page in a table view. I keep getting the error:
"Extra trailing closure passed in call"
I have been unable to find a solution that fixes the function so I am able to view the data. Here is my code below
import FirebaseAuth
import Firebase
import FirebaseDatabase
import FirebaseFirestore
class DashboardViewController: UIViewController {
@IBOutlet weak var reminderList: UITableView!
var reminders = [EntryViewController]()
func viewWillAppear(animated: Bool) {
viewWillAppear(animated: animated)
loadData()
}
func loadData() {
self.reminders.removeAll()
let ref = Database.database().reference()
ref.child("usersEvents").observeSingleEvent(of: .value, withBlock: { (snapshot) in
if let reminderDict = snapshot.value as? [String:AnyObject] {
for (_,reminderElement) in reminderDict {
print(reminderElement);
let reminder = Reminder()
reminders.event = reminderElement["event"] as? String
reminders.dateAndTime = reminderElement["data and time"] as? String
reminders.message = reminderElement["notes"] as? String
self.reminders.append(reminder)
}
}
self.tableView.reloadData()
}) { (error) in
print(error.localizedDescription)
}
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.reminders.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ToDoCell")
cell!.textLabel?.text = reminders[indexPath.row].event
return cell!
}
}
I am getting the error on this line
}) { (error) in
I do not practice Firebase, but looked at doc: https://firebase.google.com/docs/reference/swift/firebasedatabase/api/reference/Classes/DatabaseQuery#observesingleeventof:with:withcancel:
The API is
func observeSingleEvent(of eventType: DataEventType, with block: @escaping (DataSnapshot) -> Void, withCancel cancelBlock: ((Error) -> Void)? = nil)
So most likely your code should be:
ref.child("usersEvents").observeSingleEvent(of .value, with: { (snapshot) in
if let reminderDict = snapshot.value as? [String:AnyObject] {
for (_,reminderElement) in reminderDict {
print(reminderElement);
let reminder = Reminder()
reminders.event = reminderElement["event"] as? String
reminders.dateAndTime = reminderElement["data and time"] as? String
reminders.message = reminderElement["notes"] as? String
self.reminders.append(reminder)
}
}
self.tableView.reloadData() // Should it be inside the if let ?
}, withCancel: { (error) in
print(error.localizedDescription)
})
.
What do you want to do in viewWillAppear ? You call it recursively, in an infinite loop (but in fact it will never be called, because the system will not recognise the signature) and it will not compile as is.
func viewWillAppear(animated: Bool) { // define a new func ? In fact, need to override
viewWillAppear(animated: animated) // recursive call
loadData()
}
You probably want:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
loadData()
}
It seems you are using very old API versions. Take care.
This
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
is now:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
And calling cell!.textLabel is now deprecated. You should replace with ContentConfiguration.
In addition, forcing unwrap is dangerous, better use if let
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "ToDoCell") {
var content = cell.defaultContentConfiguration()
content.text = reminders[indexPath.row].event
cell.contentConfiguration = content
return cell
} else {
return UITableViewCell()
}
}