Две функции, которые получают данные из базы данных FireBase, и третья функция, которая выполняет некоторые вычисления - PullRequest
0 голосов
/ 04 января 2019

У меня есть две функции, которые успешно извлекают целые числа из Firebase.Я хотел бы третью функцию, которая делает некоторое простое вычитание из целых чисел, собранных в первых двух функциях.

Однако я очень новичок в этом, поэтому не могу заставить его работать правильно.

Вывод двух функций, которые собирают данные из Firebase:

let pointsRedeemedAsInt:Int = Int(Points_Redeem)!

и

let sumOfPointsCompleted = self.challengeList.reduce(0) {$0 + $1.Points}

Мне нужна третья функция, которая выглядит какthis:

let pointsBalance = sumOfPointsCompleted - pointsRedeemedAsInt

Однако третья функция не распознает sumOfPointsCompleted и pointsRedeemedAsInt.

// Первая функция:

 func loadPointsRedeemed() {


    databaseReference = Database.database().reference()

    let userID = Auth.auth().currentUser?.uid

    databaseReference.child("Users").child(userID!).observe(DataEventType.value, with: { (snapshot) in

        let value = snapshot.value as? NSDictionary

        // let Points_Earn = value?["Points_Earned"] as? String ?? ""
        let Points_Redeem = value?["Points_Redeemed"] as? String ?? ""


        // self.Points_Earned.text = Points_Earn
        self.Points_Redeemed.text = Points_Redeem

        let pointsRedeemedAsInt:Int = Int(Points_Redeem)!

        // Do any additional setup after loading the view.
    }

)}

// Вторая функция:

func LoadPointsCompleted() {

    self.challengeList.removeAll()

    databaseReference = Database.database().reference()

    let userID = Auth.auth().currentUser?.uid

    let refChallenges = Database.database().reference(withPath: "Challenges").child(userID!).queryOrdered(byChild: "Status").queryEqual(toValue: "Complete")

    refChallenges.observeSingleEvent(of: .value, with: { (snapshot) in

        //if the reference have some values
        if snapshot.childrenCount > 0 {

            //clearing the list
            self.challengeList.removeAll()

            //iterating through all the values
            for Challenges in snapshot.children.allObjects as! [DataSnapshot] {
                //getting values
                let challengeObject = Challenges.value as? [String: AnyObject]
                let Points = challengeObject?["Points"] as! Int

                //creating challenge object with model and fetched values
                let challenge = pointsModel(Points: (Points as Int?)!)

                //appending it to list
                self.challengeList.append(challenge)

                let sumOfPointsCompleted = self.challengeList.reduce(0) {$0 + $1.Points}

                let sumOfPointsCompletedString = String(sumOfPointsCompleted)
                self.Calc_Earned.text = sumOfPointsCompletedString
            }   
        }
    }   
    )}

// Третья функция (которая не работает):

 func BalanceOfPoints(){

    let balance = sum - pointsRedeemedAsInt

}

Ошибка:

Использование неразрешенных идентификаторов sum и pointsRedeemedAsInt

Кроме того, как мне убедиться, что все выполняется в правильном порядке?т. е. функция loadPointsCompleted должна сначала выполняться (и завершаться), затем следует функция loadPointsRedeemed и, наконец, функция BalanceOfPoints.

Ответы [ 2 ]

0 голосов
/ 31 января 2019

На самом деле проблема в том, что вы не учитываете, что получение данных из удаленных источников является асинхронным.Это означает, что вам нужно дождаться получения данных, прежде чем вызывать другие функции.

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

Измените свои функции следующим образом:

Первая функция

func loadPointsRedeemed(completion: @escaping (_:Int)->()){

databaseReference = Database.database().reference()

let userID = Auth.auth().currentUser?.uid

databaseReference.child("Users").child(userID!).observe(DataEventType.value, with: { (snapshot) in

    let value = snapshot.value as? NSDictionary

    // let Points_Earn = value?["Points_Earned"] as? String ?? ""
    let Points_Redeem = value?["Points_Redeemed"] as? String ?? ""


    // self.Points_Earned.text = Points_Earn
    self.Points_Redeemed.text = Points_Redeem

    let pointsRedeemedAsInt:Int = Int(Points_Redeem)!

    // Do any additional setup after loading the view.

    //Call your return back function called "completion"
    completion(pointsRedeemedAsInt)

}

)}

Вторая функция

func loadPointsCompleted(completion: @escaping (_:Int)->()){

self.challengeList.removeAll()

databaseReference = Database.database().reference()

let userID = Auth.auth().currentUser?.uid

let refChallenges = Database.database().reference(withPath: "Challenges").child(userID!).queryOrdered(byChild: "Status").queryEqual(toValue: "Complete")

refChallenges.observeSingleEvent(of: .value, with: { (snapshot) in

    //if the reference have some values
    if snapshot.childrenCount > 0 {

        //clearing the list
        self.challengeList.removeAll()

        //iterating through all the values
        for Challenges in snapshot.children.allObjects as! [DataSnapshot] {
            //getting values
            let challengeObject = Challenges.value as? [String: AnyObject]
            let Points = challengeObject?["Points"] as! Int

            //creating challenge object with model and fetched values
            let challenge = pointsModel(Points: (Points as Int?)!)

            //appending it to list
            self.challengeList.append(challenge)

        }   

        let sumOfPointsCompleted = self.challengeList.reduce(0) {$0 + $1.Points}

        let sumOfPointsCompletedString = String(sumOfPointsCompleted)
        self.Calc_Earned.text = sumOfPointsCompletedString

        completion(sumOfPointsCompleted)

    }
}   
)}

Третья функция

 func balanceOfPoints(completion: @escaping (_:Int)->()) {
   loadPointsCompleted{(sum) in
        //HERE YOU CAN USE THE RESULT OF loadPointsCompleted
        //I CALLED IT sum

    loadPointsRedeemed{ (pointsRedeemedAsInt) in
          // HERE YOU CAN USE THE RESULT OF loadPointsRedeemed
           //I CALLED IT pointsRedeemedAsInt
          let balance = sum - pointsRedeemedAsInt
          completion(balance)
     }       
 }

}

Для вызова функции баланса в любом месте:

       balanceOfPoints{ (balance) in
           // Whatever you want with balance
       }

Если вы измените представление (например, установите текст метки), обязательно используйте функции в главном потоке.

0 голосов
/ 04 января 2019

Проблема в том, что вы пытаетесь получить доступ к переменным вне области действия BalanceOfPoints().

Попробуйте вернуть значения, которые вы хотите использовать в уравнении, из первых двух функций, loadPointsRedeemed() и LoadPointsCompleted().Это можно сделать так:

Первая функция

func loadPointsRedeemed() -> Int {

    databaseReference = Database.database().reference()

    let userID = Auth.auth().currentUser?.uid

    databaseReference.child("Users").child(userID!).observe(DataEventType.value, with: { (snapshot) in

        let value = snapshot.value as? NSDictionary

        // let Points_Earn = value?["Points_Earned"] as? String ?? ""
        let Points_Redeem = value?["Points_Redeemed"] as? String ?? ""


        // self.Points_Earned.text = Points_Earn
        self.Points_Redeemed.text = Points_Redeem

        let pointsRedeemedAsInt:Int = Int(Points_Redeem)!

        // Do any additional setup after loading the view.

        return pointsRedeemedAsInt

    }

)}

Вторая функция

func loadPointsCompleted() -> Int {

    self.challengeList.removeAll()

    databaseReference = Database.database().reference()

    let userID = Auth.auth().currentUser?.uid

    let refChallenges = Database.database().reference(withPath: "Challenges").child(userID!).queryOrdered(byChild: "Status").queryEqual(toValue: "Complete")

    refChallenges.observeSingleEvent(of: .value, with: { (snapshot) in

        //if the reference have some values
        if snapshot.childrenCount > 0 {

            //clearing the list
            self.challengeList.removeAll()

            //iterating through all the values
            for Challenges in snapshot.children.allObjects as! [DataSnapshot] {
                //getting values
                let challengeObject = Challenges.value as? [String: AnyObject]
                let Points = challengeObject?["Points"] as! Int

                //creating challenge object with model and fetched values
                let challenge = pointsModel(Points: (Points as Int?)!)

                //appending it to list
                self.challengeList.append(challenge)

            }   

            let sumOfPointsCompleted = self.challengeList.reduce(0) {$0 + $1.Points}

            let sumOfPointsCompletedString = String(sumOfPointsCompleted)
            self.Calc_Earned.text = sumOfPointsCompletedString

            return sumOfPointsCompleted

        }
    }   
)}

Третья функция

func balanceOfPoints() -> Int {

    let sum = loadPointsCompleted()
    let pointsRedeemedAsInt = loadPointsRedeemed()

    let balance = sum - pointsRedeemedAsInt

    return balance

}

Теперь, где бы вы ни вызывали функции loadPointsRedeemed() и loadPointsCompleted(), замените эти вызовы на balanceOfPoints.

Обратите внимание на основные изменения, которые я внес вваш код добавляет возвращаемые значения в ваши функции, чтобы их можно было использовать в других областях вашего кода.Ознакомьтесь с документацией Swift Functions , чтобы узнать больше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...