我以前有一个可行的解决方案,但找不到在Firebase上删除条目的方法。旧的解决方案仅删除本地设备上的条目(只有“列表”和“ desc”阵列会从本地设备上删除,而不会从数据库中删除)。因此,我添加了“ post”变量,以使每个标题和描述与唯一的ID绑定在一起,因此我可以检索该ID以便从数据库中删除该条目。
现在使用“ post”变量,标题和描述上载到Firebase,但是我在UITableView上检索和显示在Firebase上发布的数据时遇到了麻烦。尝试将快照数据追加到名为“ post”的字典中时出现错误。
此行发生错误:
if let itemArray = snapshot.value as? [[String : Optional <String>]]
{
post.append(itemArray) \\ERROR: Value of type '[String : Optional<String>]' has no member 'append'
self.myTableView.reloadData()
}
}
这是下面的完整代码
class FirstViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {
//******THIS IS THE TABLEVIEWCONTROLLER******
@IBOutlet weak var myTableView: UITableView! // link to tableview item in storyboard
//required function when using tableview; wants to know how many cells to produce (takes template from prototype cell in storyboard)
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return(list.count)
}
// required function when using tableview; actual link to each cell from storyboard
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = UITableViewCell(style: UITableViewCell.CellStyle.default, reuseIdentifier: "cell")
cell.textLabel?.text = list[indexPath.row]
return (cell)
}
//function allows you to swipe left to delete an entry(cell)
public func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath){
if editingStyle == UITableViewCell.EditingStyle.delete
{
var key = [String]()
ref?.child(key[indexPath.row]).setValue(nil) // removes a entry on Firebase using its unique ID
key.remove(at: indexPath.row)
list.remove(at: indexPath.row)
desc.remove(at: indexPath.row)
myTableView.reloadData()
}
}
override func viewDidAppear(_ animated: Bool) {//change "viewDidLoad()" back to "viewDidAppear()"
ref = Database.database().reference() // sets the variable "ref" to connect to our Firebase database
list.removeAll() // Deletes all older data, so only data thats on the Firebase Database will be added to the "list" array
desc.removeAll() // Deletes all older data, so only data thats on the Firebase Database will be added to the "desc" array
let alert = UIAlertController(title: "Enter Details for Your Post", message: "", preferredStyle: UIAlertController.Style.alert)
let titleField = alert.textFields![0] as UITextField
let descField = alert.textFields![1] as UITextField
let key = ref?.child("task").childByAutoId().key
let post = ["uid": key, // Gets auto generated ID for database entry
"title": titleField.text, // Saves the title field to Firebase
"description": descField.text] // Saves the description field to Firebase
handle = ref?.child("task").observe(.childAdded, with: { (snapshot) in // looks for each title in the tasks'title directory in the Firebase database, so it may display them on the tableview
if let itemArray = snapshot.value as? [[String : Optional <String>]]
{
post.append(itemArray)
self.myTableView.reloadData()
}
}
)}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
myIndex = indexPath.row
performSegue(withIdentifier: "detailsegue", sender: self)
}
@IBAction func quickAdd(_ sender: UIButton) // Link to add button on FirstViewController
{
uploadToFirebase(title: "Post the task?", message: "Enter a title and description for your task")
}
func uploadToFirebase (title: String, message: String)
{
let alert = UIAlertController(title: "Enter Details for Your Post", message: "", preferredStyle: UIAlertController.Style.alert)
alert.addTextField(configurationHandler: { (titleField : UITextField!) in // Adds a textfield to the alert
titleField.placeholder = "Enter item"
})
alert.addTextField(configurationHandler: { (descField : UITextField!) in // Adds a textfield to the alert
descField.placeholder = "Enter Description"
})
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertAction.Style.default, handler: { // Adds cancel button to alert; voids whatever has been inputted
(action : UIAlertAction!) -> Void in })
let saveAction = UIAlertAction(title: "Save", style: UIAlertAction.Style.default, handler: { (action : UIAlertAction! ) in // Adds save button to alert; saves the tasks to Firebase if clicked
let titleField = alert.textFields![0] as UITextField
let descField = alert.textFields![1] as UITextField
if (titleField.text != "") // Checks to make sure titleField isn't empty
{
if (descField.text != "") // Checks to make sure descField isn't empty
{
let key = ref?.child("task").childByAutoId().key
let post = ["uid": key, // Gets auto generated ID for database entry
"title": titleField.text, // Saves the title field to Firebase
"description": descField.text] // Saves the description field to Firebase
ref?.child("task").child(key!).setValue(post) // Saves the task for Firebase, ties each post with a unique ID
}
}
})
alert.addAction(saveAction)
alert.addAction(cancelAction)
self.present(alert, animated: true, completion: nil) // Presents the alert on screen
}
}
这是我的Firebase数据库。子“任务”下的数据未出现在UITableView上
{
"task" : {
"-LT4Xtdo7Z0oyqHXHgif" : {
"description" : "4:02 desc",
"title" : "4:02 test",
"uid" : "-LT4Xtdo7Z0oyqHXHgif"
},
"-LU6eMyaKN9DZF-YYiLU" : {
"description" : "You Know!",
"title" : "HU",
"uid" : "-LU6eMyaKN9DZF-YYiLU"
},
答案 0 :(得分:0)
以以下格式创建模型文件
class ListModel: NSObject {
var UID:String?
var Title:String?
var Description:String?
}
在您的ViewController中
var Obj : ListModel?
var ListArr = [ListModel]()
let ref = Database.database().reference().child("tasks")
ref.observe(.childAdded, with: { (snapshot) in
print(snapshot)
guard let dictionary = snapshot.value as? [String : AnyObject]
else {
return
}
let Obj = ListModel()
Obj.UID = snapshot.key
Obj.Title= dictionary["title"] as? String
Obj.Description = dictionary["description"] as? String
self.ListArr.append(Obj)
//ReloadTable Here
tableView.reloadData()
}, withCancel: nil)