iOS: Entwurfsmuster zum Auffüllen von asynchron abgerufenen Daten

7

Ich entwickle eine App, die Daten aus dem Internet holt und dem Benutzer anzeigt. Angenommen, die Daten sind Rezensionen eines Restaurants und eine Bewertung wird auf einer Ansicht angezeigt. Der Benutzer kann nach links oder rechts wischen, um zur vorherigen / nächsten Überprüfung zu gelangen. Die Daten werden asynchron abgerufen (ein Thread für jede Überprüfung).

Hier ist die Problemstellung - Nehmen wir an, dass 5 Bewertungen abgerufen wurden und der Benutzer sich derzeit die dritte ansieht. Jetzt wird die sechste Rezension abgerufen und ich möchte sie als vierte Rezension für den Benutzer anzeigen (da das Veröffentlichungsdatum der sechsten Rezension aktueller ist als die fünfte Rezension). Wie soll meine Modellklasse den View-Controller informieren?

Ich habe einige Optionen erwogen -

  1. Stellen Sie dem View-Controller ein Array zur Verfügung und senden Sie dann NSNotifications über neue Elemente, die zwischen dem Array an einem bestimmten Index eingefügt werden
  2. Verwenden Sie einen NSFetchedResultsController (das ist ein bisschen schwierig, weil ich es nicht mit einem Tabellenansicht-Controller verwende)
  3. Der View-Controller fragt immer nach der nächsten Überprüfung (aus dem Modell) und hat kein Array von Reviews damit

Gibt es in einem solchen Szenario etablierte Designmuster? Andere Vorschläge außer den 3 oben sind willkommen!

    
Akshay 25.02.2014, 06:27
quelle

4 Antworten

7

Verwenden Sie einfach ein NSFetchedResultsController . Bei Verwendung von NSIndexPath s ignoriere einfach section . Es ist im Grunde eine verherrlichte NSArray mit kostenlosen Benachrichtigungen.

Hier ist, wie ich denke, ich würde es tun:

  • Stellen Sie sicher, dass NSFetchRequest für Ihre NSFetchedResultsController nach Veröffentlichungsdatum sortiert ist.
  • Handle NSFetchedResultsControllerDelegate Methoden.
  • Wenn das NSFetchedResultsController aktualisiert wird, speichern Sie das aktuelle Objekt, laden Sie die Sammlungsansicht neu, und blättern Sie dann ohne Animation zu dem gespeicherten Objekt. Dies wird dem Benutzer angezeigt, als ob der aktuellen Seite nichts passiert wäre.
John Estropia 04.03.2014, 04:47
quelle
1

Obwohl es für jedes Programmierproblem kein perfektes Entwurfsmuster gibt, ist das nächste, was ich an Ihr Problem denken kann, eine Kombination aus den Command- und Observer-Mustern.

Ссылка

Das Beobachtermuster wird im NSNotification-Center verwendet.

Obwohl es unklar ist, warum Sie eine Überprüfung überspringen möchten, könnten Sie zwei Arrays haben, um sie beim Abrufen zu speichern. Der erste enthält alle Bewertungen, die Sie abgerufen haben. Die zweite enthält alle Bewertungen, die angezeigt werden.

Dann können Sie die letzte Überprüfung im abgerufenen Array abrufen, als wäre es ein Stack. Auf diese Weise wird immer der zuletzt geladene Inhalt für den Benutzer angezeigt.

    
TigerCoding 27.02.2014 14:12
quelle
1

Ich bin verwirrt, warum die Reihenfolge der Anzeige anders ist als die wahre Reihenfolge, dh warum die 6. Überprüfung vor der 5. steht, aber Sie haben nach Mustern gefragt, die helfen könnten.

Abgesehen von MVC und Beobachter, die in den anderen Antworten und Kommentaren enthalten sind, würde ich vorschlagen, lazy mit einem virtual proxy zu laden. Wenn Bewertungen abgerufen wurden, können Sie einfach ihren Proxy anzeigen (z. B. mit einer Nachricht "loading ...", bis sie vollständig im Speicher sind).

Siehe hier: Ссылка

    
Fuhrmanator 01.03.2014 05:55
quelle
1

Ich würde empfehlen, das Beobachtungsmuster zu verwenden, um Ihren Controller zu informieren, dass neue Daten abgerufen werden. Wenn Sie das Signal empfangen, kann Ihr View-Controller das Array der "Restaurantbewertung" aktualisieren (indem Sie entweder das alte hinzufügen und es anhand einiger Sortierdeskriptoren Ihres Geschmacksmusters neu anordnen oder indem Sie das DAO direkt abfragen). Nehmen wir an, Sie holen Ihre Daten aus dem Internet und füllen eine CoreData-Entität mit den Ergebnissen. Sobald Sie Ihre heruntergeladenen Daten erhalten haben, können Sie Ihre Kerndaten "Review" -Entität ausfüllen. Um die Änderung in den Core-Daten zu "hören", sollte sich Ihr Controller im Body viewDidLoad selbst als Beobachter für NSManagedObjectContextDidSaveNotification registrieren.

[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(updateInfo:) name:NSManagedObjectContextDidSaveNotification object:nil];

Dann können Sie in Ihrer updateInfo die Änderungen erhalten

- (void) updateInfo:(NSNotification *)notification { self.reviews = [self.managedObjectContext performRequest:myFetchRequest error:nil]; }

    
Florian Burel 05.03.2014 09:25
quelle