附加到Swift 3中Firebase Closure内的数组

时间:2017-02-27 12:54:39

标签: ios swift firebase firebase-realtime-database

我正在尝试追加Firebase闭包内的数组, 我在闭包var CanJoinArray = [String]()之外声明了数组但是当我尝试追加闭包内的数组时self.CanJoinArray.append("hello")并将其打印到闭包之外,print (CanJoinArray)它不会打印。但是,当我在(内部)闭包内打印数组时,它可以追加并打印。我怎么解决这个问题?谢谢!

ref.observeSingleEvent(of: .value, with: { (FIRDataSnap) in
        for child in FIRDataSnap.children.allObjects {
            let key = (child as AnyObject).key as String
            self.myArray.append(key)
        }

        for (_, element) in self.myArray.enumerated() {
            self.ref.child(element).child("Players").observeSingleEvent(of: .value, with: { (Snap) in
                if Snap.childrenCount < 2 {
                    self.CanJoinArray.append("hello")
                }
                else {
                    print("Can't join lobby\(element)... Full!")
                }
                print(CanJoinArray) //this does work
            })
        }
       print (CanJoinArray) //this doesn't work
    })
}

数据库结构:

{
 "Lobbies" : {
    "RANDOMUUID" : {
       "LobbyName" : {
          "LobbyName" : ""
       },
       "Players" : {
          "user1" : "USERUID#"
       }
    }
 },
 "Users" : {
    "USERUID#" : {
      "DisplayName" : "user1"
    }
  }
}

2 个答案:

答案 0 :(得分:0)

只需将打印语句移动一个,

 for (_, element) in self.myArray.enumerated() {

        self.ref.child(element).child("Players").observeSingleEvent(of: .value, with: { (Snap) in

            if Snap.childrenCount < 2 {
                self.CanJoinArray.append("hello")

            }
            else {
                print("Can't join lobby\(element)... Full!")

            }


        })

      print (CanJoinArray)

    }

  you were here

})

答案 1 :(得分:0)

你可以去几个方向......

您似乎想要维护一个可用的大厅列表,并且可用性取决于大厅中的玩家数量。在这种情况下,0或1个玩家意味着它可用,如果2个或更多意味着它已满。

首先想到的选项是通过在大厅中添加is_available节点来更改结构。当玩家加入该大厅时,将他们的uid添加到玩家孩子,如果是第二个玩家,则将is_available更新为false。结构看起来像这样:

Lobbies
  lobby_id_0
    lobby_name: "lobby 5"
    is_available: false
    players
      uid_0: true
      uid_1: true
  lobby_id_1
    lobby_name: "lobby 12"
    is_available: true
    players
      uid_2: true
  lobby_id_2
    lobby_name: "some lobby"
    is_available: false
    players
      uid_3: true
      uid_4: true

代码是一个查询:

let lobbiesRef = rootRef.child("Lobbies")
let queryRef = lobbiesRef.queryOrdered(byChild: "is_available").queryEqual(toValue: true)
queryRef.observeSingleEvent(of: .value, with: { (snapshot) in

    for child in snapshot.children {
       let snap = child as! FIRDataSnapshot
       let lobbyDict = snap.value as! [String: Any]
       let lobbyKey = snap.key
       self.availableLobbyArray.append(lobbyKey)
    }
})

这会将lobby_id_1添加到数组中,因为其他两个游说者都有两个玩家。

第二种解决方案是保留第二个节点,列出可用的大厅。

这是All_Lobbies节点和Available_Lobbies节点

All_Lobbies
   lobby_id_0
     lobby_name: "lobby 5"
     players
         uid_0: true
         uid_1: true
   lobby_id_1
     lobby_name: "lobby 12"
     players
        uid_2: true

Available_Lobbies
   lobby_id_1: true

有点相同的概念;当玩家加入lobby_id_1并且它是两个玩家(因此它已满)时,只需从Available_Lobbies节点中移除该大厅。

要查看哪些可用的代码:

let availableLobbiesRef = rootRef.child("Available_Lobbies")
availableLobbiesRef.observeSingleEvent(of: .value, with: { (snapshot) in

    for child in snapshot.children {
       let snap = child as! FIRDataSnapshot
       let lobbyKey = snap.key
       self.availableLobbyArray.append(lobbyKey)
    }
})

这种结构的优点是双重的。我们完全消除了查询,因为只有可用的大厅存储在该节点中。查询比观察更“重”并占用更多资源。第二件事是,如果有1百万可用的数据,我们加载的数据要少得多!