我有以下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进行编程,并且会喜欢该语言的解决方案。
答案 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
}
}
这将使表格视图看起来像这样。