
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