从FireBase数据库获取数据的两个函数,以及执行一些计算的第三个函数

时间:2019-01-04 00:46:13

标签: ios swift firebase firebase-realtime-database

我有两个函数可以从Firebase成功检索整数。我想要第三个函数,该函数从前两个函数中收集的整数中进行一些简单的减法。

但是,我对此很陌生,因此无法使其正常工作。

从Firebase收集数据的两个函数的输出为:

let pointsRedeemedAsInt:Int = Int(Points_Redeem)!

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

我想要的是第三个函数,如下所示:

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 :(得分:1)

实际上,问题是您没有考虑从远程源检索数据是异步的。 这意味着您必须在调用其他函数之前等待数据被检索。

要获得此结果,应将Swift闭包(其他语言的回调)与完成处理程序一起使用。选中this documentation

以这种方式更改功能:

第一个功能

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
       }

如果要更改视图(例如,设置一些标签文本),请确保使用主线程中的功能。

答案 1 :(得分:0)

问题是您正在尝试访问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 Documentation了解更多信息。