Firebase:从嵌套的Childs中检索信息(Swift 3)

时间:2017-05-12 08:29:59

标签: ios json swift firebase swift3

我有以下Json结构:

{
  "users" : {
    "yebl4egdQAcKyO7fRx3" : {
      "Calls" : {
        "Call_1" : {
          "CallNumber" : "1",
          "CallStatus" : "activ",
          "CallTitle" : "Test",
          "username" : "Kurt"
        },
        "Call_2" : {
          "CallNumber" : "2",
          "CallStatus" : "activ",
          "CallTitle" : "kfkf",
          "username" : "Kurt"
        },
      },
      "Country" : "USA",
      "Date of Birth" : "19770101",
      "Gender" : "M",
      "email" : "kurt@küde.com",
      "username" : "Kurt"
    }
  }
}

现在,我尝试检索以下数据:

1)孩子内的通话次数"通话"。我尝试使用此代码执行此操作:

let databaseRef = FIRDatabase.database().reference()

        databaseRef.child("users").child("Calls").observe(.value, with: { snapshot in

            let CallCount = snapshot.childrenCount

            self.checkCall = Int(CallCount)

            print("check")
            print(self.checkCall)

        })

代码应该返回每个用户的呼叫数量。但是这段代码返回零。似乎我没有正确地解决我的观察,因为我的Json树是嵌套的。

2)我需要为所有用户取回一个单独呼叫的整个字典(假设示例中不只有一个):

    struct SingleCall {

        let callNumber: String!
        let callStatus: String!
        let callTitle : String!
        let username : String!
            }

 let databaseRef = FIRDatabase.database().reference()

        databaseRef.child("users").child("Calls").observe(.value, with: { snapshot in

            var newItems: [SingleCall] = []
            let enumerator = snapshot.children
            while let rest = enumerator.nextObject() as? FIRDataSnapshot {

                if self.Filter == (rest.value as? NSDictionary)!["Category"] as! String {

                    let callNumber        = (rest.value as? NSDictionary)!["CallNumber"] as! String

                    let callStatus        = (rest.value as? NSDictionary)!["CallStatus"] as! String

                    let callTitle        = (rest.value as? NSDictionary)!["CallTitle"] as! String

                    let username        = (rest.value as? NSDictionary)!["username"] as! String

                    newItems.append(SingleCall(callNumber: callNumber, callStatus: callStatus, callTitle: callTitle, username : username))

                }
            }
        })

这不起作用,因为我似乎没有正确地解决Childs以检索信息。我还在这里检查了几个条目,但无法帮助自己完成这些条目。我正在使用Swift 3进行编程,并且会喜欢该语言的解决方案。

1 个答案:

答案 0 :(得分:2)

因此,导致您不接听任何电话的主要问题是您错过了此行databaseRef.child("users").child("Calls")上的子路径,即用户uid。我已经使用上面的JSON使用Firebase对此进行了测试,并且可以正常使用。

import UIKit
import Firebase

class TestTableViewController: UITableViewController {

    var users = Array<User>()

    var filtered = Array<User>()

    var filter = "active"

    override func viewDidLoad() {
        super.viewDidLoad()

        let ref = FIRDatabase.database().reference().child("users")

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

            guard let data = snapshot.value as? Dictionary<String,Dictionary<String,Any>> else { return }

            for (uid, value) in data {

                if let user = User(uid: uid, dict: value) {

                    self.users.append(user)

                } else {

                    print("Incomplete User Data.")
                }
            }

            self.tableView.reloadData()
        })
    }

    func filterCalls(){

        self.filtered.removeAll()

        for user in users {

            let calls = user.calls.filter { $0.status == self.filter }

            var newUser = user

            newUser.calls = calls

            self.filtered.append(newUser)
        }
    }

    // MARK: - Table view data source

    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {

        return self.users[section].username
    }

    override func numberOfSections(in tableView: UITableView) -> Int {

        return self.users.count
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        if users.count > section {

            return self.users[section].calls.count
        }

        return 0
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

        // Configure the cell...

        cell.textLabel?.text = self.users[indexPath.section].calls[indexPath.row].title

        cell.detailTextLabel?.text = self.users[indexPath.section].calls[indexPath.row].number

        return cell
    }
}

struct User {

    var uid: String

    var country: String

    var dob: String

    var gender: String

    var email: String

    var username: String

    var calls: Array<Call>

    init?(uid: String, dict: Dictionary<String,Any>) {

        guard

            let country = dict["Country"] as? String,

            let dob = dict["Date of Birth"] as? String,

            let gender = dict["Gender"] as? String,

            let email = dict["email"] as? String,

            let username = dict["username"] as? String,

            let calls = dict["Calls"] as? Dictionary<String,Dictionary<String,String>>

        else {

            return nil
        }

        self.uid = uid

        self.country = country

        self.dob = dob

        self.gender = gender

        self.email = email

        self.username = username

        self.calls = Array<Call>()

        for (_, value) in calls {

            guard let call = Call(dict: value) else { continue }

            self.calls.append(call)
        }

        self.calls.sort { $0.number < $1.number }

        self.calls = self.calls.filter { $0.status == "active" } // This will filter the array so only the active calls are there.
    }
}

struct Call {

    var number: String

    var status: String

    var title: String

    var username: String

    init?(dict: Dictionary<String,String>) {

        guard

            let number = dict["CallNumber"],

            let status = dict["CallStatus"],

            let title = dict["CallTitle"],

            let username = dict["username"]

        else {

            return nil
        }

        self.number = number

        self.status = status

        self.title = title

        self.username = username
    }
}

这将使表格视图看起来像这样。

enter image description here