2017-10-09 5 views
0

私のアプリは約500人のユーザーを持っています。あるスクリーンでは、教師が選択する学生のユーザーを読み込んでいます。生徒のリスト(400)は、20秒以上かけて移住しています。私は、データをより効率的に埋め込む方法があるのだろうかと思います。作成するデータは、uid、最初、最後、電子メールです。ユーザーデータのSwift Firebaseロングロード時間

生徒のユーザーを取得する機能は次のとおりです。

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持っている:真のキー:値のペアを。

次に、「studentUsers」の学生情報がリストのUIDから取得されています。

--UPDATED--

私はコメントを見た後、次を使用していました。

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秒未満で何千ものノードをロードできるはずです。問題の一部である可能性のある問題のコードには、いくつかの問題があります。並べ替え、並べ替え、配列を再読み込みするたびにループを介してtableViewを読み込みます。 – Jay

+0

@Jay私はこれをより効率的にすることができるいくつかの場所で私を助けてくれますか? –

+0

答えを確認したのかどうかわかりませんが、パフォーマンスを向上させるために少し更新しました。 – Jay

答えて

1

あなたは既にコードを更新してより良い性能を得ていますが、さらに修正することができます。

以下のコードを作成し、1000人のリストから500人のユーザーを引き抜いてテストしました。合計時間は.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あなたが読んで、すべてのデータを持ってまで、UIを更新しないことです物事をスピードアップする方法の

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(tableView.reloadData()など)が読み込まれました。

関連する問題