Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/120.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在Swift 3中附加到Firebase闭包内的数组_Ios_Swift_Firebase_Firebase Realtime Database - Fatal编程技术网

Ios 在Swift 3中附加到Firebase闭包内的数组

Ios 在Swift 3中附加到Firebase闭包内的数组,ios,swift,firebase,firebase-realtime-database,Ios,Swift,Firebase,Firebase Realtime Database,我正试图附加到Firebase闭包中的数组, 我在闭包的外部声明了数组var CanJoinArray=[String](),但是当我尝试附加到闭包内部的数组时:self.CanJoinArray.append(“hello”)并在闭包外部打印它,print(CanJoinArray)它不打印。但是,当我在(inside)闭包内打印数组时,它可以追加和打印。我怎样才能解决这个问题?谢谢 ref.observeSingleEvent(of: .value, with: { (FIRDataSnap

我正试图附加到Firebase闭包中的数组, 我在闭包的外部声明了数组
var CanJoinArray=[String]()
,但是当我尝试附加到闭包内部的数组时:
self.CanJoinArray.append(“hello”)
并在闭包外部打印它,
print(CanJoinArray)
它不打印。但是,当我在(inside)闭包内打印数组时,它可以追加和打印。我怎样才能解决这个问题?谢谢

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
    })
}

把打印报表往上挪一步也许

 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

})
self.myArray.enumerated()中(ux,元素)的
{
self.ref.child(element).child(“Players”).observeSingleEvent(of:.值,带:{(管理单元))的
如果Snap.childrenCount小于2{
self.CanJoinArray.append(“hello”)
}
否则{
打印(“无法加入大厅\(元素)…已满!”)
}
})
打印(CanJoinArray)
}
你在这里
})

你可以朝几个方向走

您似乎希望维护可用大厅的列表,可用性由大厅中的玩家数量决定。在这种情况下,0或1名玩家表示可用,如果2名或更多玩家表示已满

想到的第一个选项是通过在大厅中添加一个is_available节点来更改结构。当一名玩家加入该大厅时,将其uid添加到玩家子项,如果是第二名玩家,则将“是否可用”更新为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,因为其他两个lobby各有两名玩家

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

这是“所有”大厅节点和“可用”大厅节点

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)
    }
})

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

你是说“如果”的说法吗?不确定什么是“in”语句。是的,对不起。。。我的意思是如果声明请发布一个简短的代码示例,显示problem@simonWasHere就这么做了。myArray和CanJoinArray之间的连接是什么?不起作用。它仍然没有显示任何已添加到阵列的内容如何将其移到原始代码下方的完成范围之外?如果我这样做,它将是空的。您在这里的轨道是正确的。将
print(CanJoinArray)
语句移动到回调中(再多排两行),它就会工作。@FrankvanPuffelen它会打印CanJoinArray我在MyArray中有元素的次数每件事都可以工作,唯一的小问题是:我使用未指定的索引得到此警告
。考虑在您的安全规则中添加“.Noxon”:“IsAsOffice”以获得更好的性能 @ AdMeleleZeReo索引数据可以显著提高查询性能-但是您必须提前计划使用什么样的查询。阅读一些非常好的例子和用例。如果您只是在测试或入门,您可以忽略该消息,但当您开始使用应用程序或使用更大的数据集时,它会变得更加重要。好的。另一个问题:每当我创建一个新的大厅时,我也会这样做:
self.ref.child(“Available_Lobbies”).setValue([self.uuid:true])
,但是,每次我创建一个新的大厅时,它都会重写旧的大厅。@adameliezerov Right。它所做的正是您告诉它要做的:写入节点rootref/Available\u Lobbies/uid:true。所以这段代码不是创建一个新的大厅,而是写入一个特定的大厅。如果要创建新的大厅,应该使用.childByAutoId创建大厅键(我的答案中的大厅0、大厅1等)。childByAutoId在调用时生成一个唯一的键,该键非常适合节点键。如果你仍然有问题,这实际上是一个单独的问题。这里有很多参考资料和例子。那么我如何获得自动识别码呢?
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)
    }
})