从Firebase Swift中检索信息的好方法

我的朋友和我正在研究一个关于swift的IOS项目(新的)Firebase集成。 我们能够写入Firebase数据库,但在检索数据时遇到了问题。

我们有一个tableView控制器,我们希望从Firebase数据库填充该表。 我们的数据库组织如下:

root | - Movies |__ -Wjdkfdmlksdf (unique ID made by Firebase) | |_Actors |_A1 = ajkdfnadfdf |_A2 = podifpadsfipasdip |_Title = "Mission Impossible" |_DirectedBy = "Christopher McQuarrie" -Actors |_ -ajkdfnadfdf (unique ID made by Firebase) |_name : "Tom Cruise" |_Birthday: xx/yy/zz 

在项目中,我们创建了一个文件/类,它具有写入和从firebase检索的方法。 如果我们想要从Firebase检索特定视图控制器的信息,我们只需从该类调用特定方法。

例如,这是该类中的方法之一:

 func getListOfAllMovieIDs() -> [String] { let ref = FIRDatabase.database().reference(); var ListOfMovieIDS = [String](); ref.child("Movies").observeSingleEventOfType(.Value, withBlock: { (snapshot) in let postDict = snapshot.value as! [String : AnyObject] for (MID, _) in postDict { ListOfMovieIDS.append(MID); } }) { (error) in print(error.localizedDescription) } return listOfMoviesIDS } 

我们在tableViewControllerviewDidLoad()中调用我刚才描述的这个方法。 但是,该方法什么都不返回。 我们还调用了另一种方法,例如获取actor的唯一IDS列表,也不返回任何内容。 有什么建议吗?

Firebase异步加载数据。 因此,您不是发送请求并等待响应,而是发送请求,然后在某个时刻将通知响应。

如果在代码中放置一些位置很好的日志记录语句,则可以很容易地看到这一点

 func getListOfAllMovieIDs() { let ref = FIRDatabase.database().reference(); print("Before listener"); ref.child("Movies").observeSingleEventOfType(.Value, withBlock: { (snapshot) in print("Inside block"); }) print("After listener"); } 

print语句的顺序如下:

听众之前

听众之后

内部块

因此,当您的function退出时,数据尚未可用。 这不是一个错误,而是一个非常有意的选择。 通过允许代码继续,应用程序将保持对您的用户的响应。 大多数现代互联网都使用这种模式,所以通常最好接受它(虽然最初的问题很棘手)。

解决方案通常是重新编写代码。 而不是说“首先我们加载数据,然后我们做xyz”,说它“我们开始加载数据,一旦我们得到它,我们做xyz”。 这就是Firebase数据加载方法占用块的原因:这包含一旦数据可用就应该发生的“xyz”。

一个很好的副作用是,这个逻辑也适用于最初加载后可能更新的数据。 当您使用objectEventOfType() ,您可以轻松处理“开始同步数据,每当我们获取数据时执行xyz”并具有处理实时更新的应用程序的情况。

尝试使用下面的方法,因为当你使用observeSingleEventOfType方法时; 返回初始数据后立即取消该块。 这可能是您无法在回调块中看到结果的原因。

 ref.observeEventType(.Value, withBlock: { snapshot in println(snapshot.value) }, withCancelBlock: { error in println(error.description) })