Swift:使用firebase

时间:2017-04-11 04:52:23

标签: ios swift uitableview firebase firebase-realtime-database

我创建一个应用程序只是为了学习这门语言。基本上我正试图制作一个应用程序,允许你打赌CSGO团队将获胜的假钱。所以现在我在应用程序的一部分,允许用户创建一个赌注。然后用户可以看到他可以接受另一个用户下注的所有赌注。我以前做过这一切,但我注意到了一个bug,所以我决定修复它。问题是它现在崩溃了。

我需要该应用程序转到另一个屏幕,允许您在团队中下注。然后单击该框并设置您希望在该特定团队上下注多少。然后,当您点击底部的提交Button时,它会将用户信息和投注信息上传到Firebase Database。然后它将返回上一个屏幕,显示尚未填充的所有投注。所以他也应该这样。

问题是,当我使用POPView控制器返回上一个显示投注的视图控制器时,它为表视图提供了一个索引超出范围的错误。奇怪的是,如果我将方法getBetsFor移动到viewDidLoad而不是视图会出现,那么它的工作正常。问题是它会出现故障并且不会显示用户刚刚做出的赌注。

我知道我的代码很可怕我曾尝试将其中的一部分放入MVC格式,但我的代码没有进一步说明。

下面的代码是从Firebase Database获取赌注的代码,然后将该数据放入对象数组中,然后将对象显示在TableView

  //
//  BetView.swift
//  EDraft
//
//  Created by Devin Tripp on 3/20/17.
//  Copyright © 2017 Devin Tripp. All rights reserved.
//

import UIKit
import Foundation
import Firebase


class BetView: UIViewController, UITableViewDelegate, UITableViewDataSource{
    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var teamOne: UILabel!
    @IBOutlet weak var teamTwo: UILabel!
    let datRef = FIRDatabase.database().reference(fromURL: "https://edraft-77b47.firebaseio.com/")


    var userMoney = String()

    let getData = GatherData()

    var testies: String?

    var teamTOne = String()
    var teamTTwo = String()

    let screenSize: CGRect = UIScreen.main.bounds

    let navBar: UINavigationBar = UINavigationBar(frame: CGRect(x: 0, y: 60, width: UIScreen.main.bounds.width, height: 50))
    var navItem = UINavigationItem(title: "Money: ")


    let doneItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.add, target: nil, action: #selector(sayHello(sender:)))


    let backItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.done, target: nil, action: #selector(goBack(sender:)))


    override func viewWillAppear(_ animated: Bool) {
        self.getData.betObjects.removeAll()
        self.getData.getBetsFor(completion: { (result) in
            if result == true {
                //show the spinning wheel thing
                self.tableView.reloadData()
            } else {
                // error
            }

        })
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.addSubview(navBar)
        self.tableView.separatorStyle = .none

        navItem.rightBarButtonItem = doneItem
        navItem.leftBarButtonItem = backItem
        navBar.setItems([navItem], animated: false)

        teamOne.text = teamTOne
        teamTwo.text = teamTTwo


        /*
        getData.getBetsFor(completion: { (result) in
            if result == true {




                self.tableView.reloadData()
            } else {

            }

        })
        */

        getData.getMoneyFromUser(username: self.getData.userName, completion: { (money) in

            if money == true {
                let usermoney = String(self.getData.userMoney)
                //update the UI
                self.navItem.title = "$" + usermoney
                print(self.getData.userMoney)
            } else {
                print("no money found")
            }



        })

    }




    func tableView(_ tableView: UITableView, shouldUpdateFocusIn context: UITableViewFocusUpdateContext) -> Bool {
        return true
    }




    func updateBet(_ index: Int, completion: @escaping (_ something: Bool) -> Void) {
        let userID = FIRAuth.auth()?.currentUser?.uid
        datRef.child("User").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
            // Get user value
            let value = snapshot.value as? NSDictionary
            let username = value?["username"] as? String
            self.getData.userName = username!
            // ...


            self.datRef.child("Bets").observe(.childAdded, with: { snapshot in
                //
                // this is the unique identifier of the bet.  eg, -Kfx81GvUxoHpmmMwJ9P
                guard let dict = snapshot.value as? [String: AnyHashable] else {
                    print("failed to get dictionary from Bets.\(self.getData.userName)")
                    return
                }
                let values = ["OpposingUsername": self.getData.userName,"Show": "no"]
                //var val = self.getData.betObjects[index]
                //val.opposingUserName = self.getData.userName
            self.datRef.child("Bets").child(self.getData.tieBetToUser[index]).observeSingleEvent(of: .value, with: { (snapshot) in

                    let anothaValue = snapshot.value as? NSDictionary
                    let user = anothaValue?["Username"] as? String

                    if user == self.getData.userName {
                        // let the user know he cannot bet his own bet
                        completion(false)
                    } else {
                        self.datRef.child("Bets").child(self.getData.tieBetToUser[index]).updateChildValues(values)
                        completion(true)
                    }


                })



            })


        }) { (error) in
            print(error.localizedDescription)
        }


    }

    func getOpoosingUserNames(_ username: String,_ index: Int, completion: @escaping (_ result: Bool) -> Void ) {
        let userID = FIRAuth.auth()?.currentUser?.uid
        datRef.child("User").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
            // Get user value
            let value = snapshot.value as? NSDictionary
            let username = value?["username"] as? String ?? ""


            self.datRef.child("Bets").child(self.getData.tieBetToUser[index]).observeSingleEvent(of: .value, with: { snapshot in
                let thisValue = snapshot.value as? NSDictionary
                if let thisUserName = thisValue?["Username"] as? String {

                    self.getData.opposingUserName  = thisUserName
                    completion(true)


                } else {
                    completion(false)
                }

            })
        }) { (error) in
            print(error.localizedDescription)
        }
    }




    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        //if makeEmpty == true {
        //    return 0
        //} else {
        print(self.getData.betObjects.count)
            return self.getData.betObjects.count
        //}
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = self.tableView.dequeueReusableCell(withIdentifier: "cellB", for: indexPath) as! CellB
        print(self.getData.betObjects[indexPath.row].userName)
        cell.userNameLabel?.text = getData.betObjects[indexPath.row].userName
        cell.amountOfBet?.text = getData.betObjects[indexPath.row].betAmount


        return cell

    }


    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let alertController = UIAlertController(title: "Accept Bet", message: "Match the bet of " + getData.amountBets[indexPath.row], preferredStyle: .alert)

        let okButton = UIAlertAction(title: "No", style: .default, handler: { (action) -> Void in
            print("Ok button tapped")
        })

        let yesButton = UIAlertAction(title: "Yes", style: .default, handler: { (action) -> Void in
            // let them know to wait a second or the bet won't go through
            var waitController = UIAlertController(title: "Please Wait", message: "Your bet is being processed", preferredStyle: .alert)

            self.present(waitController, animated: true, completion: nil)
            //take away the usersMoney
            self.takeAwayMoney(self.getData.amountBets[indexPath.row],index: indexPath.row, completion: { (result) in

                if result == true {
                    self.updateBet(indexPath.row, completion: { (result) in


                        if result == true {
                            self.getOpoosingUserNames(self.getData.userName, indexPath.row, completion: { (anothaResult) in

                                if anothaResult == true {
                                    self.dismiss(animated: true, completion: {
                                        let successController = UIAlertController(title: "Success", message: "You have made a bet with " + self.getData.opposingUserName, preferredStyle: .alert)
                                        let okButt = UIAlertAction(title: "Ok", style: .default, handler: nil)
                                        successController.addAction(okButt)
                                        self.present(successController, animated: true, completion: nil)
                                        //lastly delete the opposing UserName

                                        let pathIndex = IndexPath(item: indexPath.row, section: 0)
                                        self.getData.betObjects.remove(at: indexPath.row)
                                        self.tableView.deleteRows(at: [pathIndex], with: .fade)
                                        self.tableView.reloadData()
                                        print("Second")
                                    })

                                    self.getData.getMoneyFromUser(username: self.getData.userName, completion: { (money) in

                                        if money == true {
                                            self.userMoney = String(self.getData.userMoney)
                                            //update the UI
                                            self.navItem.title = "$" + self.userMoney



                                            print(self.userMoney)
                                        } else {
                                            print("no money found")
                                        }



                                    })
                                } else {

                                }
                                //wait for the first view to load in case it uploads to fast


                            })

                        } else {
                            self.dismiss(animated: true, completion: {
                                let cannotBet = UIAlertController(title: "Failed", message: "You cannot bet with yourself dummy", preferredStyle: .alert)
                                let okButt = UIAlertAction(title: "Ok", style: .default, handler: nil)
                                cannotBet.addAction(okButt)
                                self.present(cannotBet, animated: true, completion: nil)
                            })
                        }


                    })



                } else {
                    // user doesn't have money
                    //display a alert that lets the user know hes broke
                    print("this should print once")
                    self.dismiss(animated: true, completion: {
                        let brokeController = UIAlertController(title: "Failed", message: "Reason: You don't have enough money!", preferredStyle: .alert)
                        let okButt = UIAlertAction(title: "Ok", style: .default, handler: nil)
                        brokeController.addAction(okButt)
                        self.present(brokeController, animated: true, completion: nil)
                    })
                }
                var getResult = ""
                print("You have taken away the users money")

                    print("you made it this far almost there")
                    //let delayInSeconds = 3.0 // 1
                    //DispatchQueue.main.asyncAfter(deadline: .now() + delayInSeconds) { // 2
            })


        return
        })

        alertController.addAction(okButton)
        alertController.addAction(yesButton)
        present(alertController, animated: true, completion: nil)
    }

    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if(editingStyle == UITableViewCellEditingStyle.delete) {
            self.getData.betObjects.remove(at: indexPath.row)
        }
    }


    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        //let indexPath = self.tableView.indexPathForSelectedRow!
        //var DestViewController : addBets = segue.destination as! addBets
        //DestViewController.teamOne = self.teamOne.text!
        //DestViewController.teamOne = self.teamTTwo

        if segue.identifier == "gotobetview" {
            if let destination = segue.destination as? addBets {

                destination.teamOne = self.teamOne.text!
                destination.teamTwo = self.teamTwo.text!
            }
        }




    }

    func takeAwayMoney(_ howMuch: String, index: Int, completion: @escaping (Bool)-> ()) -> Void{
        if let notMuch = Int(howMuch) {

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

            datRef.child("User").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
                // Get user value
                let value = snapshot.value as? NSDictionary
                let money = value?["money"] as? String ?? ""

                //convert money to int
                if let conMoney = Int(money) {
                    var conMoreMoney = conMoney
                    if conMoreMoney < notMuch {

                        print(" You don't have enough money")
                        completion(false)
                        return
                    } else {
                        conMoreMoney -= notMuch
                        let values = ["money": String(conMoreMoney)]

                        //update the users money
                        self.datRef.child("User").child(userID!).updateChildValues(values)
                        completion(true)
                    }

                }
                // ...
            }) { (error) in
                print(error.localizedDescription)
            }
        }
    }

    func getUserName() -> String {
        let userID = FIRAuth.auth()?.currentUser?.uid
        var useruser: String!
        datRef.child("User").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
            // Get user value
            let value = snapshot.value as? NSDictionary
            let username = value?["username"] as? String ?? ""

            self.getData.userName = username
            useruser = username

            // ...
        }) { (error) in
            print(error.localizedDescription)
        }

        return useruser
    }




    func sayHello(sender: UIBarButtonItem) {
        let userInput = self.teamOne.text

        var userInputArray: [String] = []
        userInputArray.append(self.teamOne.text!)
        userInputArray.append(self.teamTwo.text!)
        performSegue(withIdentifier: "gotobetview", sender: userInputArray)





        //let storyboard = UIStoryboard(name: "Main", bundle: nil)
        //let homeView = storyboard.instantiateViewController(withIdentifier: "addBets")
        //self.present(homeView, animated: true, completion: nil)
    }

    func goBack(sender: UIBarButtonItem) {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let backView = storyboard.instantiateViewController(withIdentifier: "tabview")
        self.present(backView, animated: true, completion: nil)
    }

}

由于我无法再发布代码,我将在github上更新项目并在此处发布链接。

https://github.com/devintrippprojects/EDraft

如果您下载项目,您可以随时创建自己的帐户,您将以100美元开始,或者您可以使用主要测试帐户,电子邮件是 k@k.com 密码是 KKKKKK

我将发布数据库的外观以及明天应用程序的外观,感谢您度过一个美好的夜晚。

1 个答案:

答案 0 :(得分:1)

我下载并运行了你的项目。

这里的问题似乎是你应该在删除所有数据源时重新加载tableView。

改变这个:

    self.getData.betObjects.removeAll()
    self.getData.getBetsFor(completion: { (result) in
        if result == true {
            //show the spinning wheel thing
            self.tableView.reloadData()
        } else {
            // error
        }

    })

到此:

    self.getData.betObjects.removeAll()
    self.tableView.reloadData()
    self.getData.getBetsFor(completion: { (result) in
        if result == true {
            //show the spinning wheel thing
            self.tableView.reloadData()
        } else {
            // error
        }

    })

额外的一行:

self.tableView.reloadData()