【问题标题】:UITableView shows up as blank before data is loaded from Firebase在从 Firebase 加载数据之前,UITableView 显示为空白
【发布时间】:2017-08-14 07:31:22
【问题描述】:

我创建了简单的 UITableView,其中包含从 Firebase 加载的几行。 在 viewWillAppear 上,我连接观察者并用数据填充数组。 当视图已加载但仍未调用异步 Firebase 回调时会出现问题 - 表显示为空白。 回调后表格刷新,看起来像预期的那样,但延迟仍然很明显。 我已经配置了离线模式,并期望应该立即调用观察者的处理程序,但事实并非如此。

处理这个问题的正确方法是什么? 等待栏看起来不是最好的选择,因为它只有 100 毫秒左右,而且数据已经在设备上,而我只有 8 行。 有什么解决办法吗? 谢谢!

观察代码:

-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];

refHandle = [areasRef observeEventType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
    [self.arrayOfAreas removeAllObjects];

    for (FIRDataSnapshot* areaSnapshot in snapshot.children){
        Area *area = [[Area alloc] init];
        [area retrieveFromSnapshot:areaSnapshot];

        [self.arrayOfAreas addObject:area];
    } [self.tableView reloadData];
}]; }

viewDidLoad:

- (void)viewDidLoad {
[super viewDidLoad];
self.ref = [[FIRDatabase database] reference];

FIRUser *currentUser = [FIRAuth auth].currentUser;

areasRef = [[[_ref child:@"users"] child:currentUser.uid] child:@"areas"];

self.tableView.dataSource = self;
self.tableView.delegate = self;
self.tableView.tableFooterView = [[UIView alloc]init];
self.arrayOfAreas = [NSMutableArray new];
self.tableView.allowsMultipleSelectionDuringEditing = NO; }

【问题讨论】:

  • 你在 Storyboard 中分配了 dataSource 和 delegate 了吗?
  • 并分享您的代码,以便我们查看并更好地了解您的情况。
  • 感谢提问,我已经在viewDidLoad中分配了
  • @Dev_Tandel 我添加了 viewDidLoad 并观察代码示例
  • 在主线程上重新加载。您还可以使用 ActivityIndi​​cator 让用户感觉数据正在加载,因为有时您的互联网连接不佳也会导致延迟。

标签: ios uitableview firebase firebase-realtime-database


【解决方案1】:

全新安装您的应用后, 显然,从 firebase 获取数据会有延迟。 获取所有数据后,您必须将其保存在本地数据库中。

从第二次开始,显示本地数据库中的数据并同时获取 firebase 数据库。 (如果您不对获取路径的内部键值进行更新/删除,则可以根据本地数据优化firebase DB获取查询)。

如果您将本地 DB 数据保存到 arrayOfAreas。您可以按如下方式更改观察块

NSMutableArray *arrayTemp = [[NSMutableArray alloc]init];

for (FIRDataSnapshot* areaSnapshot in snapshot.children){
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Area" inManagedObjectContext:[CoreData sharedData].context];
    Area *area = [[Area alloc] initWithEntity:entity insertIntoManagedObjectContext:nil];

    [area retrieveFromSnapshot:areaSnapshot];

    [arrayTemp addObject:area];
} 

/**
if you are fetching all datas again
*/
self.arrayOfAreas = arrayTemp;
[self.tableView reloadData];

/**
if you are fetching only the datas that are newly added (datas that are not existing in local DB)
*/
[self.arrayOfAreas addObjectsFromArray: arrayTemp];
[self.tableView reloadData];

如果您正在使用 firebase 离线功能,请尝试以下方式。 (这可能不是一个完美的解决方案)

在 viewDidLoad 或应用启动中调用 [FIRDatabase database].goOffline。 一旦执行了观察者块,[FIRDatabase database].goOnline

【讨论】:

  • 感谢您的回答!如何显示本地数据库中的数据?
  • 看来您正在使用核心数据。但我没有找到任何保存上下文的代码。解释需要很多时间。如果你有兴趣在 shebinkoshyios@gmail.com 上联系我
  • 我实际上并没有在那里使用 CoreData,我只是初始化 CoreData 的 NSManagerObject 并用快照填充它。我不保存上下文等。为了使数据离线可用,我使用 [FIRDatabase database].persistenceEnabled = YES;
  • 我已经更新了代码示例——现在没有CoreData,问题是一样的。
  • 刚试过 goOffline / goOnline - 不幸的是延迟是一样的
【解决方案2】:

您的UITableview 正在加载到viewDidLoad,因为最初您的数组中没有数据,您的tableView 是空白的。

如果您不希望在检索数据之前加载您的tableView,那么您可以在完成获取记录后分配您的datasourcedelegate。 (在 Firebase 方法的完成块中)

您可以显示加载程序,直到您的数据被检索到。

【讨论】:

  • 感谢您的建议!数据已经加载,因为一切都在飞行模式下工作,我打开了离线存储。我刚刚尝试在数据已添加到数组时分配数据源和委托 - 不幸的是,TableView 仍然显示没有数据。我不想添加加载指示器,因为数据已经存在。
猜你喜欢
  • 2014-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-30
  • 2020-04-07
  • 1970-01-01
  • 2021-05-01
  • 2017-10-29
相关资源
最近更新 更多