Vom Server bereitgestellte Animationen in iOS-Apps



Hallo allerseits! Vor ungefähr sechs Monaten haben wir eine der aufregendsten Funktionen von Badoo gestartet: Live-Streaming . Eine der Hauptfunktionen besteht darin, dass Zuschauer Geschenke an ihre Lieblings-Streamer senden können, um ihre Wertschätzung auszudrücken. Wir wollten die Geschenke so schick und ansprechend wie möglich gestalten, deshalb wurde beschlossen, einige davon wirklich lebendig zu machen, und damit meine ich animiert. Um die Menschen noch mehr zu motivieren, planten wir, das Badoo-Team, diese Geschenke und Animationen alle paar Wochen zu aktualisieren.

Als iOS-Ingenieur haben Sie vielleicht bereits die Herausforderung erraten, vor der wir hier standen: Die Notwendigkeit, neue Animationen hinzuzufügen und die alten zu entfernen, erforderte vom Kunden eine Menge Arbeit. Für jede Version benötigen wir sowohl das Android- als auch das iOS-Entwicklungsteam. In Kombination mit der Zeit, die App Store-Überprüfungen und -Bewilligungen häufig benötigen, kann es Tage dauern, bis jedes Update live geschaltet werden kann. Aber wir haben das Problem gelöst und ich werde Ihnen erklären, wie.

Lösungsübersicht


Zu diesem Zeitpunkt wussten wir bereits, wie man Adobe After Effects (AAE) -Animationen in das Format exportiert, das von unserer iOS-App mithilfe der Lottie-Bibliothek gelesen werden kann. Diesmal gingen wir jedoch noch einen Schritt weiter: Wir beschlossen, eine Art Animationsspeicherdienst zu erstellen, der über das Internet verfügbar ist. Mit anderen Worten, wir würden alle tatsächlichen Animationen auf dem Server speichern und sie bei Bedarf an die Client-Apps liefern:



So sieht die endgültige Lösung im iOS-Simulator auf dem Computer des Entwicklers aus:


In diesem Beitrag ist das Beispiel, das ich verwenden werde, eine sehr einfache Animation, die ich selbst erstellt habe. Es ist nicht so schick wie das von Badoo, aber es ist gut genug, um das Potenzial des beschriebenen Ansatzes zu demonstrieren.

Animationen exportieren


Das hier verwendete Adobe After Effects (AAE) -Projekt mit Animationen befindet sich zusammen mit anderen Quelldateien auf github . Nach dem Öffnen des AAE-Animationsprojekts in _raw/animations/Fancy/Fancy.aep sollte ein Fenster wie das folgende _raw/animations/Fancy/Fancy.aep :



An dieser Stelle werde ich nicht darauf eingehen, wie Animationen in AEE erstellt werden. Ich werde jedoch erläutern, wie bereits vorhandene Animationen aus AAE mithilfe des Bodymovin-Plugins in ein für iOS-Apps lesbares Format importiert werden.

Nachdem Sie sichergestellt haben, dass das Plugin installiert ist, öffnen Sie es, indem Sie im Menü die Option Fenster / Erweiterungen / Bodymovin auswählen:



Jetzt sollte das Bodymovin-Fenster angezeigt werden, in dem Sie die zu exportierende Animation auswählen, den Pfad der Ausgabedatei angeben und dann die Exporteinstellungen öffnen können:



Nachdem wir die Animationseinstellungen ausgewählt und geöffnet haben, können wir Bodymovin nun bitten, die Assets in die resultierende JSON-Datei einzubetten, indem wir die Option Assets / Include in json aktivieren:



Schließlich wird die ausgewählte Animationskomposition exportiert und durch Klicken auf die Schaltfläche Rendern in der angegebenen Datei gespeichert.

Speichern von Animationen auf dem Server


Nehmen wir an, wir haben unsere gerenderten Animations-JSON-Dateien über das Internet auf unseren bevorzugten Webserver verschoben. In unserem Fall habe ich sie der Einfachheit halber in das Github-Repository dieses Projekts hochgeladen. Die Animationen finden Sie hier:


Basis-URL: https://raw.githubusercontent.com/chupakabr/server-provided-animations/master/_raw/rendered-animations/

Animationsspezifische IDs:

  • clouds.json
  • fireworks.json

Hinweis: Suchen Sie nach einem in Swift geschriebenen Animationsanbieter-Webserver? Hier finden Sie die Lösung auf github und eine ausführliche Erklärung in diesem Artikel .
Zu diesem Zeitpunkt verfügen wir über einen voll funktionsfähigen Server für Animationsanbieter. Daher ist es an der Zeit, sich dem aufregendsten Teil zuzuwenden: der Präsentation der Animationen für unsere Benutzer.

Animationen abrufen und präsentieren


An dieser Stelle empfehle ich dringend, unser Beispiel-iOS-App-Projekt unter Client/ServerProvidedAnimation.xcworkspace da es bereits über alle erforderlichen Boilerplate-Codes und -Konfigurationen verfügt.

Laden von Animationsdaten


Da die REST-API-Endpunkte zum Abrufen von Animationsdaten jetzt aktiv sind, ist es an der Zeit, das Datenproviderprotokoll einzuführen und seine Serverimplementierung hinzuzufügen:

 import Lottie protocol AnimationsProviderProtocol { typealias Completion = (_ animation: LOTComposition?) -> Void func loadAnimation(byId id: String, completion: @escaping Completion) } final class ServerAnimationProvider: AnimationsProviderProtocol { private let endpoint: URL init(endpoint: URL) { self.endpoint = endpoint } func loadAnimation(byId id: String, completion: @escaping Completion) { let path = "/\(id).json" guard let animationUrl = URL(string: path, relativeTo: self.endpoint) else { completion(nil) return } URLSession.shared.invalidateAndCancel() let task = URLSession.shared.dataTask(with: animationUrl) { (data, response, error) in guard error == nil, let data = data, let json = self.parseJson(from: data) else { completion(nil) return } let animation = LOTComposition(json: json) completion(animation) } task.resume() } private func parseJson(from data: Data?) -> [AnyHashable : Any]? { guard let data = data else { return nil } do { let json = try JSONSerialization.jsonObject(with: data, options: []) as? [AnyHashable : Any] return json } catch { return nil } } } 

Mit dieser Datenprovider-Klasse können wir Animationen im JSON-Format bei Bedarf vom Server laden und sie zum Rendern auf der Benutzeroberfläche im Speicher halten. Angenommen, wir folgen dem MVVM-Muster, kann es auf folgende Weise problemlos in der ViewModel Entität verwendet werden:

  // ... private let animationProvider: AnimationsProviderProtocol private(set) var animationModel: LOTComposition? // … func loadAnimation(byId animationId: String) {     self.animationProvider.loadAnimation(byId: animationId) { [weak self] (animationModel) in         self?.animationModel = animationModel     } } // ... 

Das ViewModel aktualisiert die ausgewählte Animationsdateneigenschaft, wenn es eine gültige HTTP-Antwort vom Server mit einem nicht leeren JSON-Objekt empfängt. Diese Daten werden von der Präsentationsebene verwendet, um das Rendern der Animation zu planen.

Präsentationsschicht


Jetzt können wir mit unserem ViewModel auf die Animationsdaten zugreifen und diese über die Benutzeroberfläche im Aktionshandler "on tap" anzeigen, der an die Schaltfläche angehängt ist:

 class ViewController: UIViewController {   // ...   @IBOutlet weak var animationContainer: UIView!   override func viewDidLoad() {       super.viewDidLoad()       // ...       self.animationView = {           let view = LOTAnimationView(frame: self.animationContainer.bounds)           self.animationContainer.addSubview(view)           return view       }()   }   @IBAction func onPlayAnimationAction(_ sender: Any) {       self.animationView.stop()       self.animationView.sceneModel = self.viewModel.animationModel       self.animationView.play()   } } 

Grundsätzlich haben wir hier einen Schaltflächenhandler, der eine Aktualisierung der LOTAnimationView-Instanz mit den neuesten Animationsdaten aus dem ViewModel auslöst.

So sieht das Endergebnis aus:


Das ist so ziemlich alles. Animationen werden jetzt vom vorbereiteten REST-API-Endpunkt geladen und bei Bedarf auf dem Client gerendert.

Tipps & Einschränkungen


Tipps und Tricks:

  • AAE ermöglicht die Verwendung der meisten Asset-Typen, einschließlich Raster- und Vektorgrafiken.
  • Bodymovin ermöglicht das Einbetten aller Assets in eine JSON-Ausgabeanimationsdatei (mit Base64-Codierung). Dies bedeutet, dass das Laden separater Assets auf der Clientseite vermieden werden kann.
  • Für die Animationen haben Sie die Wahl, direkt in AAE in den Vektor zu zeichnen oder einfach Adobe Illustrator-Vektorgrafiken zu importieren.

Leider ist es noch nicht möglich, SVG-Vektorgrafiken in AAE zu importieren (ich habe es versucht!).

Weitere Tricks und mögliche Probleme finden Sie in diesem erstaunlichen Artikel meines Kollegen Radoslaw Cieciwa .

Schlussfolgerungen


Was bringt uns die Verwendung von vom Server bereitgestellten Animationen? Der offensichtlichste Vorteil dieses Ansatzes ist die Möglichkeit, alle Beteiligten des Aktualisierungsflusses für Animationen zu entkoppeln. Mit anderen Worten, um eine schicke neue Animation zu veröffentlichen, müssen Designer lediglich die JSON-Darstellung der Animation dem Serverteam zur Verfügung stellen. Und um eine zu entfernen, muss das Serverteam nur diese bestimmte Animation aus dem Erkennungsdienst entfernen. Keine Zeitverschwendung!

Eine weitere coole Sache ist, dass dieselbe Funktionalität auf allen unterstützten Client-Plattformen (iOS, Android, Web usw.) implementiert werden kann, ohne dass die vorhandenen Serverfunktionen oder Rohanimationen angepasst werden müssen.

Das wars für heute! Danke fürs Lesen

Ressourcen


Source: https://habr.com/ru/post/de439370/


All Articles