2017-08-14 2 views
0

Ich habe eine einfache UITableView mit mehreren Zeilen erstellt, die von Firebase geladen werden. In viewWillAppear verbinde ich Beobachter und bevölke das Array mit Daten. Das Problem tritt auf, wenn die Ansicht bereits geladen ist, aber der asynchrone Firebase-Rückruf noch nicht aufgerufen wurde - Tabelle wird als leer angezeigt. Die Tabelle wird nach dem Rückruf aktualisiert und sieht wie erwartet aus, aber die Verzögerung ist immer noch spürbar. Ich habe den Offline-Modus konfiguriert und erwarte, dass der Handler des Beobachters sofort aufgerufen wird, aber nicht.UITableView wird als leer angezeigt, bevor Daten aus Firebase geladen werden.

Was ist der richtige Weg, damit umzugehen? Warteraum sieht nicht wie die beste Option aus, weil es nur 100ms oder so ist und Daten sind bereits auf dem Gerät und ich habe nur 8 Zeilen. Gibt es eine Lösung? Vielen Dank!

Code Beachten Sie:

-(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; } 
+0

haben Sie dataSource und Delegate im Storyboard zugewiesen? –

+0

und teilen Sie Ihren Code, damit wir uns einen Überblick verschaffen und Ihre Situation besser verstehen können. –

+0

Danke für die Frage, ich habe es in ViewDidLoad zugewiesen –

Antwort

0

Ihre UITableview wird immer auf viewDidLoad geladen, da es bei Ersteinrichtung tableView leer keine Daten in Ihnen Array sein würde.

Wenn Sie Ihre tableView nicht laden möchten, bis Sie Daten abrufen, können Sie Ihre datasource und delegate zuordnen, nachdem Sie Ihre Datensätze abgerufen haben. (In Ihrem Abschlussblock der Firebase-Methode)

Sie können Loader anzeigen, bis Ihre Daten abgerufen werden.

+0

Vielen Dank für den Vorschlag! Die Daten sind bereits geladen, weil alles im Flugmodus funktioniert. Ich habe den Offline-Speicher aktiviert. Ich habe gerade versucht, Datenquelle zuzuweisen und zu delegieren, wenn Daten bereits dem Array hinzugefügt wurden - TableView wird weiterhin leider ohne Daten angezeigt. Ich möchte keinen Ladeindikator hinzufügen, da Daten bereits vorhanden sind. –

0

Nach der Neuinstallation Ihrer App, Offensichtlich wird es eine Verzögerung sein, um die Daten von Firebase zu holen. Sobald Sie alle Daten abgerufen haben, müssen Sie sie in Ihrer lokalen Datenbank speichern.

Ab dem zweiten Mal, zeigen Sie die Daten aus Ihrer lokalen DB und gleichzeitig holen Sie die Firebase DB auch. (Wenn Sie die inneren Schlüsselwerte des Abrufpfads nicht aktualisieren/löschen, kann die Abrufabfrage der Firebase-DB basierend auf den lokalen Daten optimiert werden).

Wenn Sie die lokalen DB-Daten in ArrayOfAreas speichern. Sie können den Beobachtungsblock wie folgt ändern:

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]; 

Wenn Sie die Firebase-Offline-Funktion verwenden, versuchen Sie es unten. (es kann keine perfekte Lösung sein)

aufrufen [FIRDatabase database].goOffline in viewDidLoad oder app starten. Sobald der Beobachterblock ausgeführt wurde, [FIRDatabase database].goOnline.

+0

Vielen Dank für die Antwort! Wie könnte ich die Daten von lokalen db zeigen? –

+0

Es scheint, dass Sie Kerndaten verwenden. aber ich habe keinen Code gefunden, der den Kontext speichert. es braucht viel Zeit, um es zu erklären. Wenn Sie interessiert sind, ping mich auf [email protected] –

+1

Ich verwende CoreData nicht tatsächlich, ich initialisiere CoreData NSManagerObject und fülle es mit Snapshot. Ich speichere nichtContext usw. Um Daten offline verfügbar zu machen benutze ich [FIRDatabase database] .persistenceEnabled = YES; –

Verwandte Themen