我的应用有大约500个用户。在一个屏幕中,我正在加载学生用户供教师选择。学生名单(400)需要20多秒才能填充。我想知道是否有更有效的方法来填充数据。要填充的数据是uid,first,last,email。
这是我获取学生用户的功能。
var filteredUsers = [User]()
var users = [User]()
fileprivate func fetchFollowingUserIds() {
let ref = Database.database().reference().child("session1AllStudents")
ref.observeSingleEvent(of: .value, with: { (snapshot) in
guard let userIdsDictionary = snapshot.value as? [String: Any] else { return }
print(userIdsDictionary)
userIdsDictionary.forEach({ (key, value) in
HUD.show(.labeledProgress(title: "Finding Students", subtitle: nil))
Database.fetchStudentUsersWithUID(uid: key, completion: { (user) in
self.users.append(user)
print(self.users)
self.users.sort(by: { (u1, u2) -> Bool in
return u1.lastName.compare(u2.lastName) == .orderedAscending
})
self.filteredUsers = self.users
print(self.filteredUsers.count)
self.collectionView?.reloadData()
HUD.hide()
})
})
}) { (err) in
print("Failed to fetch following userids:", err)
}
}
extension Database {
static func fetchStudentUsersWithUID(uid: String, completion: @escaping (User) -> ()) {
Database.database().reference().child("studentUsers").child(uid).observeSingleEvent(of: .value, with: { (snapshot) in
guard let userDictionary = snapshot.value as? [String: Any] else { return }
let user = User(uid: uid, dictionary: userDictionary)
completion(user)
}) { (err) in
print("Failed to fetch user for posts:", err)
}
}
}
数据库" session1AllStudents"是所有仍然可以选择的学生的列表,并且具有UID:true key:value pair。
然后我从#34; studentUsers"获取学生信息。来自列表中的UID。
- 更新 -
在查看评论后我使用了以下内容。
func fetchRemainingStudents() {
let ref = Database.database().reference()
ref.child("session1AllStudents").observeSingleEvent(of: .value, with: { (snapshot) in
HUD.show(.labeledProgress(title: "Finding Students", subtitle: nil))
for snap in snapshot.children {
let studentsSnap = snap as! DataSnapshot
let studentsKey = studentsSnap.key
let studentDict = snapshot.value as! [String: Any]
var aStudent = User(uid: studentsKey, dictionary: studentDict)
let userRef = ref.child("studentUsers").child(studentsKey)
userRef.observeSingleEvent(of: .value, with: { snapshot in
let userDict = snapshot.value as! [String:AnyObject]
let firstName = userDict["firstName"] as! String
let lastName = userDict["lastName"] as! String
let email = userDict["email"] as! String
aStudent.firstName = firstName
aStudent.lastName = lastName
aStudent.email = email
self.users.append(aStudent)
self.filteredUsers = self.users
print(self.filteredUsers.count)
self.users.sort(by: { (u1, u2) -> Bool in
return u1.lastName.compare(u2.lastName) == .orderedAscending
})
HUD.hide()
self.collectionView?.reloadData()
})
}
})
}
这有助于加快数据加载速度。也许只有1-2秒。
答案 0 :(得分:1)
您已经更新了代码并获得了更好的性能,但您可以进一步修改它。
我精心设计并测试了下面的代码,将1000个用户从1000个列表中拉出来。总时间为.487秒。
首先我们从一个StudentClass和一个数组开始存储它们。例如,该数组可以用作tableView的dataSource。
class StudentClass {
var key = ""
var firstName = ""
var lastName = ""
var email = ""
init(snap: DataSnapshot) {
let dict = snap.value as! [String: Any]
self.key = snap.key
self.firstName = dict["first_name"] as! String
self.lastName = dict["last_name"] as! String
self.email = dict["email"] as! String
}
}
var studentArray = [StudentClass]()
然后我们有代码来读取将填充数组的学生ID。然后,我们使用该数组从Firebase获取学生,创建学生对象并填充studentArray
func fetchStudents() {
let studentIdRef = self.ref.child("student_ids")
let userRef = self.ref.child("users")
studentIdRef.observeSingleEvent(of: .value, with: { snapshot in
var keyArray = [String]()
for child in snapshot.children {
let snap = child as! DataSnapshot
keyArray.append(snap.key)
}
let lastElement = keyArray.count - 1
for (index, key) in keyArray.enumerated() {
let thisUserRef = userRef.child(key)
thisUserRef.observeSingleEvent(of: .value, with: { userSnap in
let student = StudentClass(snap: userSnap)
self.studentArray.append(student)
if index == lastElement {
print("reload tableView")
}
})
}
})
加快速度的一种方法是在读入所有数据之前不更新UI。我们可能正在使用后台线程,但在这种情况下,它发生得如此之快,可能不需要。< / p>
在获取每个学生对象的for循环中,进行测试以查看我们是否已完成读取所有学生对象,如果是,则在所有数据具有时更新ui(例如tableView.reloadData())已经装好了。