【Swift】Firebaseからデータを取得する際のfor文について

下記のコードはFirebaseにデータを保存するコードである。

//データベースの参照URL
let ref = Database.database().reference()

//Firebaseからデータを取り出す
ref.child("post").observeSingleEvent(of: .value) { (snap,error) in
    
        let snapData = snap.value as? [String:NSDictionary]
    
        if snapData == nil {
            return
        }
    
        for (_,post) in snapData! {
    
            if let username = post["username"] as? String {
            }
    
        }
    
}

 

上記の

for (_, post) in snapData! {
}

が何を表しているのかを説明していく。

 

 

[“userName”:”user1”, “userName”,”user2”]をchildByAutoId()の階層に保存したとする

post - fjaigejo3n3 - userName: “user1”

        - ooemtlm2   - userName: “user2”

 

 

もし最初に記述したコード通りなら、

//[String : String]型の辞書
snapData = [fjaigejo3n3 : ["userName": “user1”], ooemtlm23 : ["userName": “user2”]]

という構造になる。

 

そして、

for (_, post) in snapData! {

}

for (k, v) in snapData! {

}

なら、

  • ループ1回目:k = fjaigejo3n3, v = [“userName”: “user1”]
  • ループ2回目:k = ooemtlm23, v = [“userName”: “user2”]

つまり、

  • ループ1回目:_ = fjaigejo3n3, post = [“userName”: “user1”]
  • ループ2回目:_ = ooemtlm23, post = [“userName”: “user2”]

というように取り出される。

 

そして、

if let username = post["username"] as? String {
}

と書くことで、usernameに”userName”のキーに関連づけられた”user1”と”user2”を変数などに代入できる。

 

正直、階層名であるfjaigejo3n3とooemtlm23は使用しないので、for (_, post)と書くことで、不必要な階層名である2つを無視できる。

 

ただし、このforには、

  • 取り出すデータの順番がバラバラ

という欠点がある。

 

例えば、1,2,3,4、という4つの数字が、1,2,3,4、の順番でFirebaseに保存されているとする。

 

もしfor文で取り出せば、

  • 2,3,1,4
  • 4,1,3,2
  • 1,3,4,2

というバラバラな順番になってしまう。

 

このような事態を防ぐ方法は、下記の記事を参照くだされ。

nekokichi2yos2.hatenablog.com