2017-10-17 5 views
0

Je suis en train de développer une application lorsque j'essaie de trouver des utilisateurs en les récupérant dans la base de données Firebase lors d'une recherche dans une barre de recherche. Je mets tous les pseudonymes de mes utilisateurs dans un tableau et les affiche dans tableView lorsque le texte tapé correspond aux surnoms des utilisateurs avec l'auto-complétion. Je suis capable de le faire. Mais maintenant j'essaye d'afficher la page de profil d'utilisateur si je recherche un utilisateur, je choisis est nom dans la vue de table puis tape son surnom sur le tableView alors il ouvre un autre ViewController et devrait afficher les informations de l'utilisateur choisi mais il montre juste la page par défaut sans aucune information personnalisée sur l'utilisateur sélectionné.Comment transmettre des données de Firebase iOS d'un TableViewController à un autre ViewController

je vous montre mon code actuel:

class UserTableViewController: UITableViewController, UISearchResultsUpdating { 

var userTab = [String]() 
var userEmpty = ["No user"] 
var filteredUsers = [String]() 

var searchController: UISearchController! 
var resultsController = UITableViewController() 

var name: String! 

var ref: DatabaseReference! 
var dictDetails: [String:AnyObject]? 

override func viewDidLoad() { 
    super.viewDidLoad() 

    self.resultsController.tableView.dataSource = self 
    self.resultsController.tableView.delegate = self 

    ref = Database.database().reference() 

    ref.child("users").queryOrdered(byChild: "pseudo").observeSingleEvent(of: .value, with: { (snapshot) in 
     self.userTab = [] 
     if (snapshot.value is NSNull) { 
      print("No data found") 
     } else { 
      for child in snapshot.children { 
       let userSnap = child as! DataSnapshot 
       let uid = userSnap.key 
       let userDict = userSnap.value as! [String: AnyObject] 
       let pseudo = userDict["pseudo"] as! String 
       let total = snapshot.childrenCount 
       self.userTab.append(pseudo) 
       self.resultsController.tableView.reloadData() 
       continue 
      } 
     } 
    }) 

    self.searchController = UISearchController(searchResultsController: self.resultsController) 
    self.tableView.tableHeaderView = self.searchController.searchBar 
    self.searchController.searchResultsUpdater = self 
    self.searchController.dimsBackgroundDuringPresentation = false 
    self.definesPresentationContext = true 
} 

func updateSearchResults(for searchController: UISearchController) { 
    self.filteredUsers = self.userTab.filter { (user:String) -> Bool in 
     if user.lowercased().contains(self.searchController.searchBar.text!.lowercased()) { 
      return true 
     } else { 
      return false 
     } 
    } 
    self.resultsController.tableView.reloadData() 
} 

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    if segue.identifier == "userProfil" { 
     if let indexPath = self.tableView.indexPathForSelectedRow { 
      let data = userTab[indexPath.row] as! [String: AnyObject] 
      let pseudo = data["pseudo"] as? String 
      let controller = segue.destination as! UserViewController 
      controller.pseudo = pseudo! 
     } 
    } 
} 

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    if tableView == self.tableView { 
     return self.userTab.count 
    } else { 
     return self.filteredUsers.count 
    } 
} 

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = UITableViewCell() 
    if tableView == self.tableView { 
     cell.textLabel?.text = self.userTab[indexPath.row] 
    } else { 
     cell.textLabel?.text = self.filteredUsers[indexPath.row] 
    } 
    return cell 
} 

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
    performSegue(withIdentifier: "userProfil", sender: nil) 
} 
} 

Et pour l'autre contrôleur de vue:

class UserViewController: UIViewController { 
@IBOutlet weak var name: UILabel! 
var pseudo: String = "" 
var dictionary: [String:AnyObject]? 
var ref: DatabaseReference! 

override func viewDidLoad() { 
    super.viewDidLoad() 
    ref = Database.database().reference() 
    ref.child("users").queryOrdered(byChild: pseudo).observeSingleEvent(of: .value, with: { (snapshot) in 
     if let dictionary = snapshot.value as? [String: AnyObject] { 
      self.name.text = dictionary["pseudo"] as? String 
     } 
    }) 
} 
} 

Comment puis-je faire cela?

+0

Que déballez-vous les résultats? lorsque vous placez le point d'arrêt à l'intérieur du rappel, vous pouvez imprimer des données à partir de Firebase? –

+0

Ok, je résous mon problème, je peux poster la solution ici –

Répondre

0

J'ai résolu ce problème moi-même, je poste le code si cela peut aider quelqu'un d'autre.

je vous montre mon code actuel (premier contrôleur de vue est UserTableViewController):

class UserTableViewController: UITableViewController, UISearchResultsUpdating { 

var userTab = [String]() 
var userEmpty = ["No user"] 
var filteredUsers = [String]() 

var searchController: UISearchController! 
var resultsController = UITableViewController() 

var name: String! 
var ref: DatabaseReference! 

override func viewDidLoad() { 
    super.viewDidLoad() 

    self.resultsController.tableView.dataSource = self 
    self.resultsController.tableView.delegate = self 

    ref = Database.database().reference() 

    ref.child("users").queryOrdered(byChild: "pseudo").observeSingleEvent(of: .value, with: { (snapshot) in 
     self.userTab = [] 
     if (snapshot.value is NSNull) { 
      print("No data found") 
     } else { 
      for child in snapshot.children { 
       let userSnap = child as! DataSnapshot 
       let uid = userSnap.key 
       let userDict = userSnap.value as! [String: AnyObject] 
       let pseudo = userDict["pseudo"] as! String 
       let total = snapshot.childrenCount 
       self.userTab.append(pseudo) 
       self.resultsController.tableView.reloadData() 
       continue 
      } 
     } 
    }) 

    self.searchController = UISearchController(searchResultsController: self.resultsController) 
    self.tableView.tableHeaderView = self.searchController.searchBar 
    self.searchController.searchResultsUpdater = self 
    self.searchController.dimsBackgroundDuringPresentation = false 
    self.definesPresentationContext = true 
} 

func updateSearchResults(for searchController: UISearchController) { 
    self.filteredUsers = self.userTab.filter { (user:String) -> Bool in 
     if user.lowercased().contains(self.searchController.searchBar.text!.lowercased()) { 
      return true 
     } else { 
      return false 
     } 
    } 
    self.resultsController.tableView.reloadData() 
} 

// I change the content of this function 
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    if segue.identifier == "userProfil" { 
     let userViewController = segue.destination as! UserViewController 
     userViewController.pseudo = self.name! // "name" is a String variable declared at the beginning, "pseudo" is a variable declared in the UserViewController 
    } 
} 

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    if tableView == self.tableView { 
     return self.userTab.count 
    } else { 
     return self.filteredUsers.count 
    } 
} 

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = UITableViewCell() 
    if tableView == self.tableView { 
     cell.textLabel?.text = self.userTab[indexPath.row] 
    } else { 
     cell.textLabel?.text = self.filteredUsers[indexPath.row] 
    } 
    return cell 
} 

// This function is the most important because after search a user in search bar, it display it in table view cell then you choose it so you go the UserViewController where you can see the username write on this user profile page, you got to write the performSegue at the end of this function if not it can't work because if you put the performSegue at the beginning it won't find the right username because the prepare for segue function will call before and we don't want our "name" variable is nil 
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
    let post = filteredUsers[indexPath.row] as! String 
    self.name = post 
    print("name : \(name!)") // You can see in the console the name of the user you choose 
    performSegue(withIdentifier: "userProfil", sender: nil) 
} 
} 

Et pour l'autre contrôleur de vue (UserViewController):

class UserViewController: UIViewController { 
@IBOutlet weak var name: UILabel! 
var pseudo = "" 

override func viewDidLoad() { 
    super.viewDidLoad() 

    name.text = pseudo // Here name is a Label, so I put the "pseudo" variable for display it in the "name" Label and it can show the right nickname of user you choose in the search bar 
} 
} 

L'espoir peut aider quelqu'un d'autre. Maintenant, j'essaie d'afficher son image de profil utilisateur dans la même page.