Проблемы с загрузкой из firebase в tableview - PullRequest
0 голосов
/ 01 мая 2018

Цель моего приложения - найти ближайших игроков Warhammer 40k. Координаты пользователей сохраняются в ветке Locations, которая имеет 4 дочерних ветки; «Начинающий», «Хороший», «Адепт», «Элит» .

После получения ключей (которые представляют собой пользовательские идентификаторы) для близлежащих координат система должна получить информацию о пользователях с помощью списка ключей (называемого distanceArray). После этого эта информация должна отображаться в tableView.

Предполагается, что информация, которая должна отображаться о ближайших игроках: Изображение профиля, Имя, Средний рейтинг и количество оценок (Они хранятся в другой ветке) и Расстояние от вас.

  1. Когда я запускаю fetchNearbyLocations в viewDidLoad(), я не получаю никаких результатов в array с именем distanceArray. Я не получаю никаких результатов, пока я не перезагрузил tableView 2 раза. Как мне выбрать всех пользователей в начале?

  2. Когда я использую настроенную мной кнопку перезагрузки, я получаю несколько копий уже присутствующих пользователей.

Важный код:

СТРУКТУРА И НАСТРОЙКА

var ref: DatabaseReference!
    var GeoRef: GeoFire!
    var users = [userList]()
    var distanceArray = [tempDistance]()
    let uid = Auth.auth().currentUser?.uid
    var dbPath: String = "Beginner"

    struct userList {
        var name: String?
        var databaseKey: String?
        var imageUrl: String?
        var distance: Double = 0
        var avgRating: Double?
        var ratingCount: Int?
    }

    struct tempDistance {
        var uid: String?
        var distanceToPrint: Double = 0
    }




    func fetchUsers() {
        users.removeAll()
        for item in distanceArray{

        var name: String?
        var databaseKey: String?
        var imageUrl: String?
        var distance: Double?
        var avgRating: Double?
        var ratingCount: Int?

        checkName(userID: item.uid!, completion: { (success) -> Void in
            if success{
                let nameRef = self.ref.child("userInfo").child(item.uid!)
                nameRef.observeSingleEvent(of: .value) { (snapshot) in

                    let dictionary = snapshot.value as? [String: AnyObject]
                    name = (dictionary!["Name"] as? String)!
                    imageUrl = (dictionary!["profileImage"] as? String)!
                    databaseKey = item.uid!
                    distance = item.distanceToPrint
                    self.users.append(userList(name: name, databaseKey: databaseKey, imageUrl: imageUrl, distance: distance!, avgRating: avgRating, ratingCount: ratingCount))

                    self.tableView.reloadData()

                    }
                    //Add retrieval for avgRating, and ratingCount
                    self.checkRatings(userID: item.uid!, completion: { (success) -> Void in
                        if success{
                            let avgRatingRef = self.ref.child("avgScore").child(item.uid!)
                            avgRatingRef.observeSingleEvent(of: .value) { (snapshot) in
                                if let dictionary = snapshot.value as? [String: AnyObject]{
                                    avgRating = (dictionary["Score"] as? Double)!
                                    ratingCount = (dictionary["Count"] as? Int)!
                                }
                                print("append 1")
                                self.users.append(userList(name: name, databaseKey: databaseKey, imageUrl: imageUrl, distance: distance, avgRating: avgRating, ratingCount: ratingCount))
                            }

                        } else {
                            avgRating = 0
                            ratingCount = 0
                            print("append 2")
                            self.users.append(userList(name: name, databaseKey: databaseKey, imageUrl: imageUrl, distance: distance, avgRating: avgRating, ratingCount: ratingCount))
                        }
                    })
                } else {
                    print("NAME AND IMAGE HAS NOT BEEN SET")
                }
            })
        }
    }

func fetchNearbyLocations (userID: String, dbPath: String) {

    var keys = [String]()
    var myLoc = CLLocation()
        (self.GeoRef.getLocationForKey(userID, withCallback: { (location, error) in
        if (error != nil) {
            print("An error occured in fetchNearbyLocations: \(String(describing: error?.localizedDescription))")
        }
        else if (location != nil) {
            myLoc = location!
            //sets the radius - at 100 km
            let circleQuery = self.GeoRef.query(at: myLoc, withRadius: 100.0)

            circleQuery.observe(.keyEntered, with: { (key: String, location: CLLocation!) in
                let distanceFromUser = myLoc.distance(from: location)
                print("DISTANCE: \(distanceFromUser)")
                keys.append(key)
                self.distanceArray.append(tempDistance(uid: key, distanceToPrint: distanceFromUser))
                    print(self.distanceArray)
            })
        }
    }))

}
//Reloads the arrays, acts as a refresh
@objc func reloadArray() {
    fetchNearbyLocations(userID: uid!, dbPath: dbPath)
    fetchUsers()
    print(users)
    print(distanceArray)
    self.tableView.reloadData()
    refreshControl.endRefreshing()
}


//sets the GeoRef to the needed value depending on the sorting
@objc func changeGeoRef() {

    switch skillSortControl.selectedSegmentIndex {
    case 0:
        dbPath = "Beginner"
    case 1:
        dbPath = "Good"
    case 2:
        dbPath = "Adept"
    case 3:
        dbPath = "Elite"
    default:
        dbPath = "Beginner"
    }
    reloadArray()
    GeoRef = GeoFire(firebaseRef: ref.child("Locations").child(dbPath))
}

// БЛОКИ ЗАВЕРШЕНИЯ

// CompletionBlock, чтобы проверить, есть ли у пользователя идентификатор пользователя

func checkName(userID: String, completion: @escaping ((_ success: Bool) -> Void)){
    self.ref.child("userInfo").observeSingleEvent(of: .value, with: { (snapshot) in

        if snapshot.hasChild(userID){
            completion(snapshot.hasChild(userID))
            print("USERINFO EXISTS ")
            //return true
        }else{
            print("NO USERDATA EXISTS")
            completion(false)
            //return false
        }
        //return result
    }
)}

    //completion block to check if user has any score, or rating
    func checkRatings(userID: String, completion: @escaping ((_ success: Bool) -> Void)){
        self.ref.child("avgScore").observeSingleEvent(of: .value, with: { (snapshot) in

            if snapshot.hasChild(userID){
                completion(snapshot.hasChild(userID))
                print("THERE EXISTS SOME RATINGS")
                //return true
            }else{
                print("THERE IS NO RATING DATA, SETTING TO DEFAULT 0")
                completion(false)
                //return false
            }
            //return result
        }
    )}

// Функции табличного представления

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return users.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "searchProfileCell") as! SearchCell

    cell.nameLabel.text = users[indexPath.row].name

    let distanceInKm = users[indexPath.row].distance / 1000
    let distanceStr = String(format: "%.1f", distanceInKm)
    cell.distanceLabel.text = "\(distanceStr) km"

    //sets the profile images to be round
    cell.profileImage.layer.borderWidth = 1
    cell.profileImage.layer.masksToBounds = false
    cell.profileImage.layer.cornerRadius = cell.profileImage.frame.height/2
    cell.profileImage.clipsToBounds = true
    cell.profileImage.layer.borderColor = UIColor.black.cgColor
    return cell
}

1 Ответ

0 голосов
/ 01 мая 2018

Запросы Firebase являются асинхронными. Это означает, что вы должны перезагрузить Tableview после того, как запрос завершен и получен ответ от Firebase. Самый простой способ сделать это - позвонить self.tableView.reloadData() в func fetchNearbyLocations (userID: String, dbPath: String)

...