我正在尝试,并且已经有一段时间了,我将帖子排序为Firebase中的最新帖子。我知道Firebase在使用childByAutoId()创建时会自动执行此操作,但我认为这可能是我将数据调用到UITableView中的方式。
以下是将数据加载到我的数组中的代码:
阵列:
var posts = [[String : AnyObject]]()
功能'loadData()':
let uid = Auth.auth().currentUser?.uid
Database.database().reference().child("userinfo").child(uid!).observeSingleEvent(of: .value, with: { (snapshot) in
let value = snapshot.value as? NSDictionary
let userFilter = value?["discover_filter"] as! String
if userFilter == "__" {
Database.database().reference().child("posts").queryLimited(toLast: 50).observeSingleEvent(of: .value, with: { (snapshot) in
self.posts.removeAll()
if let postsDictionary = snapshot.value as? [String: AnyObject] {
for post in postsDictionary {
self.posts.append(post.value as! [String : AnyObject])
}
DispatchQueue.main.async {
self.postsTableView.reloadData()
}
}
})
}else {
Database.database().reference().child("posts").queryOrdered(byChild: "combinedstring").queryEqual(toValue: userFilter).queryLimited(toLast: 50).observeSingleEvent(of: .value, with: { (snapshot) in
self.posts.removeAll()
if let postsDictionary = snapshot.value as? [String: AnyObject] {
for post in postsDictionary {
self.posts.append(post.value as! [String : AnyObject])
}
DispatchQueue.main.async {
self.postsTableView.reloadData()
}
}
})
}
})
我自己试图解决这个问题,但是我无法解决这个问题,我尝试了很多不同的方法,但得出的结论是我只需要帮助 - 我很新,并且只是学习Swift的6个月了(我自己作为我学位项目的一部分)。
如果还有其他要求,请告诉我。
提前谢谢!
Firebase JSON结构:
"posts" : {
"-LAxSTwPhGO9NStRFGK3" : {
"activity" : "lol",
"combinedstring" : "League of Legends_PC_Beginner",
"communication" : "Mic",
"console" : "PC",
"description" : "Description...",
"game" : "League of Legends",
"gameimage" : "League of Legends.jpg",
"key" : "-LAxSTwPhGO9NStRFGK3",
"lfglfm" : "Looking for Group",
"skill" : "Beginner",
"timestamp" : 1524670787479,
"uid" : "TgtlcIcd29gN2GEHLOO1QvGhAQA2",
"username" : "danielrjjones"
},
"-LAxSbp8ilXUVY7yFG_C" : {
"activity" : "lol",
"combinedstring" : "Fifa 17_Xbox One_Beginner",
"communication" : "Mic",
"console" : "Xbox One",
"description" : "Description...",
"game" : "Fifa 17",
"gameimage" : "Fifa 17.jpg",
"key" : "-LAxSbp8ilXUVY7yFG_C",
"lfglfm" : "Looking for Members",
"skill" : "Beginner",
"timestamp" : 1524670823883,
"uid" : "TgtlcIcd29gN2GEHLOO1QvGhAQA2",
"username" : "danielrjjones"
}
}
用于创建帖子的代码:
import UIKit
import Firebase
import FirebaseDatabase
class CreatePostViewController: UIViewController, UITextFieldDelegate, UIPickerViewDataSource, UIPickerViewDelegate {
@IBOutlet weak var gameTextField: UITextField!
@IBOutlet weak var activityTextField: UITextField!
@IBOutlet weak var consoleTextField: UITextField!
@IBOutlet weak var skillTextField: UITextField!
@IBOutlet weak var communicationTextField: UITextField!
@IBOutlet weak var lfglfmTextField: UITextField!
@IBOutlet weak var rulesTextView: UITextView!
@IBOutlet weak var descriptionTextView: UITextView!
@IBOutlet weak var createButton: UIButton!
var gameValue = String()
var console = ["Select Console", "Nintendo DS", "Nintendo Switch", "PC", "PS Vita", "Playstation 3", "Playstation 4", "Xbox 360", "Xbox One"]
var skill = ["Select Playing Type", "Beginner", "Experienced", "Veteran", "Pro"]
var communication = ["Select Communication","Mic", "No Mic"]
var lfglfm = ["Select LFG/LFM", "Looking for Group", "Looking for Members"]
var itemSelected = ""
var gameimage = ""
var combinedString = ""
weak var pickerView: UIPickerView?
weak var textField: UITextField?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
//allow tap on screen to remove text field input from screen
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:))))
//UIPICKER
let pickerView = UIPickerView()
pickerView.delegate = self
pickerView.dataSource = self
gameTextField.delegate = self
consoleTextField.delegate = self
skillTextField.delegate = self
communicationTextField.delegate = self
lfglfmTextField.delegate = self
//set pickerview for other text fields
pickerView.showsSelectionIndicator = true
let toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.default
toolBar.isTranslucent = true
toolBar.tintColor = UIColor(red:0.00, green:0.45, blue:1.00, alpha:1.0)
toolBar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.plain, target: self, action: #selector(CreatePostViewController.donePicker))
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.plain, target: self, action: #selector(CreatePostViewController.donePicker))
toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
toolBar.isUserInteractionEnabled = true
gameTextField.inputView = pickerView
gameTextField.inputAccessoryView = toolBar
consoleTextField.inputView = pickerView
consoleTextField.inputAccessoryView = toolBar
skillTextField.inputView = pickerView
skillTextField.inputAccessoryView = toolBar
communicationTextField.inputView = pickerView
communicationTextField.inputAccessoryView = toolBar
lfglfmTextField.inputView = pickerView
lfglfmTextField.inputAccessoryView = toolBar
// pickerview = pickerview
self.pickerView = pickerView
//extra styling
let navImg = UIImage(named: "nav-bar")
navigationController?.navigationBar.setBackgroundImage(navImg, for: .default)
//createButton.colourBorder()
}
override func viewDidAppear(_ animated: Bool) {
gameTextField.text = gameValue
gameTextField.resignFirstResponder()
}
@objc func donePicker() {
textField?.resignFirstResponder()
self.view.endEditing(true)
}
//pickerview code
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField == gameTextField {
return
}else {
self.pickerView?.reloadAllComponents()
}
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if consoleTextField.isFirstResponder{
return console.count
}else if skillTextField.isFirstResponder{
return skill.count
}else if communicationTextField.isFirstResponder{
return communication.count
}else if lfglfmTextField.isFirstResponder{
return lfglfm.count
}
return 0
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if consoleTextField.isFirstResponder{
return console[row]
}else if skillTextField.isFirstResponder{
return skill[row]
}else if communicationTextField.isFirstResponder{
return communication[row]
}else if lfglfmTextField.isFirstResponder{
return lfglfm[row]
}
return nil
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if consoleTextField.isFirstResponder{
let itemselected = console[row]
consoleTextField.text = itemselected
}else if skillTextField.isFirstResponder{
let itemselected = skill[row]
skillTextField.text = itemselected
}else if communicationTextField.isFirstResponder{
let itemselected = communication[row]
communicationTextField.text = itemselected
}else if lfglfmTextField.isFirstResponder{
let itemselected = lfglfm[row]
lfglfmTextField.text = itemselected
}
}
@IBAction func createPostTapped(_ sender: UIButton) {
if gameTextField.text == "" || consoleTextField.text == "" || skillTextField.text == "" || communicationTextField.text == "" || lfglfmTextField.text == "" {
let alert = UIAlertController(title: "Oops...", message: "You must fill out all fields to create a post. Please try again!", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
} else if consoleTextField.text == "Select Console" || skillTextField.text == "Select Playing Type" || communicationTextField.text == "Select Communication" || lfglfmTextField.text == "Select LFG/LFM" {
let alert = UIAlertController(title: "Oh no!", message: "Please select a value to create a post.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
} else {
if let uid = Auth.auth().currentUser?.uid {
Database.database().reference().child("usernames").child(uid).observeSingleEvent(of: .value, with: {
(snapshot) in
if let userDictionary = snapshot.value as? [String: AnyObject] {
for user in userDictionary {
if let username = user.value as? String {
if let game = self.gameTextField.text {
if let activity = self.activityTextField.text {
if let console = self.consoleTextField.text {
if let skill = self.skillTextField.text {
if let communication = self.communicationTextField.text {
if let lfglfm = self.lfglfmTextField.text {
if let description = self.descriptionTextView.text {
let gameimage = "\(self.gameTextField.text!).jpg"
let combinedString = "\(self.gameTextField.text!)_\(self.consoleTextField.text as! String)_\(self.skillTextField.text as! String)"
let timeStamp = ServerValue.timestamp() as! [String:Any]
let refer = Database.database().reference().child("posts").childByAutoId()
let ref = refer.key
let postObject: Dictionary<String, Any> = [
"uid" : uid,
"username" : username,
"game" : game,
"activity" : activity,
"console" : console,
"skill" : skill,
"communication" : communication,
"lfglfm" : lfglfm,
"description" : description,
"gameimage" : gameimage,
"combinedstring" : combinedString,
"timestamp" : timeStamp,
"key" : ref,
]
refer.setValue(postObject)
//Database.database().reference().child("posts").childByAutoId().setValue(postObject)
let alert = UIAlertController(title: "Success!", message: "Your post was added successfully.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in
//code will run when ok button is pressed
let vc = self.storyboard?.instantiateViewController(withIdentifier: "LoggedInVC")
self.present(vc!, animated: true, completion: nil)
}))
self.present(alert, animated: true, completion: nil)
}
}
}
}
}
}
}
}
}
}
})
}
}
}
}
答案 0 :(得分:0)
(根据对答案的评论)解决方案是为每个&#34; post&#34;添加类型编号的特定字段(例如,称为timestamp
)并分配值创建时间戳的乘以-1
时间戳的建议值是纪元时间,请参阅Get Unix Epoch Time in Swift。
然后根据此字段值对您进行排序,例如:
Database.database().reference().child("posts").queryOrdered(byChild: "timestamp")...
通过这种方式,最新的帖子将首先出现
答案 1 :(得分:0)
这应该有效:
Database.database().reference().child("posts").queryOrderedByKey().queryLimited(toLast: 50).observeSingleEvent(of: .value, with: { (snapshot: DataSnapshot) in
self.posts.removeAll()
for child in snapshot.children.allObjects as [DataSnapshot] {
self.posts.append(child.value as? [String: AnyObject])
}
DispatchQueue.main.async {
self.postsTableView.reloadData()
}
})
的变化:
queryOrderedByKey()
以明确我们希望按键排序结果。snapshot.children
,因为过早转换为[String: AnyObject]
会丢失订购信息。