
Vor sechs Monaten haben wir eine der beeindruckendsten Funktionen von Badoo vorgestellt - das
Live-Streaming . Unter anderem können Benutzer ihren Lieblings-Streamern in Form von Geschenken ihren Dank aussprechen. Wir wollten diese Geschenke so hell und attraktiv wie möglich gestalten und beschlossen, sie wiederzubeleben - mit anderen Worten, zu animieren. Und um es noch interessanter zu machen, wollten wir alle paar Wochen Geschenke und Animationen aktualisieren.
iOS-Ingenieure müssen erraten haben, um welches Arbeitsvolumen es sich handelt: Um alte und neue Animationen zu löschen, müssen viele Aktionen auf der Clientseite ausgeführt werden. Zu diesem Zweck müssen Android- und iOS-Teams an jeder Version beteiligt sein. Zusammen mit der Zeit, die erforderlich ist, um das Update im App Store zu genehmigen, bedeutet dies, dass der Start jeder Version mit aktualisierten Animationen mehrere Tage dauern kann. Wir haben es jedoch geschafft, dieses Problem zu lösen, und jetzt werde ich Ihnen sagen, wie.
Lösungsarchitektur
Zu diesem Zeitpunkt wussten wir bereits, wie man
Adobe After Effects-Animationen (im Folgenden: AAE) in einem Format exportiert, das unsere iOS-Anwendung mithilfe der Lottie-Bibliothek verstanden hat. Diesmal gingen wir etwas weiter: Wir beschlossen, alle relevanten Animationen auf dem Server zu speichern und bei Bedarf herunterzuladen.

Ein Beispiel für eine echte Animation in unserer Anwendung, die auf diese Weise erhalten wurde:
In diesem Beitrag werde ich jedoch als Beispiel eine einfache Animation nehmen, die ich selbst erstellt habe. Es ist nicht so kreativ wie in Badoo, aber es ist durchaus geeignet, unseren Ansatz zu demonstrieren.
Animationen exportieren
Das von mir verwendete AAE-Projekt kann zusammen mit
anderen Quellen auf GitHub gefunden werden .
_raw/animations/Fancy/Fancy.aep
Sie das Projekt unter
_raw/animations/Fancy/Fancy.aep
, wird ein Fenster
_raw/animations/Fancy/Fancy.aep
:

Jetzt spreche ich nicht über das Erstellen von Animationen in AAE, sondern darüber, wie vorhandene Animationen aus AAE mithilfe des
Bodymovin- Plugins in ein für eine iOS-Anwendung geeignetes Format importiert werden.
Öffnen Sie das Plugin nach der Installation, indem Sie
im Menü Fenster / Erweiterungen / Bodymovin auswählen:

Das Bodymovin-Fenster wird angezeigt, in dem Sie die zu exportierende Animation, einen Ordner zum Speichern der resultierenden Datei und das Öffnen der Exporteinstellungen auswählen können:

In den Animationseinstellungen können wir Bodymovin bitten, Ressourcen in die JSON-Datei aufzunehmen, indem wir
Assets / Include in json auswählen:

Durch Drücken der Schaltfläche Rendern exportieren wir die ausgewählte animierte Komposition und speichern sie in einer Datei.
Speichern von Animationen auf dem Server
Angenommen, wir laden gerenderte animierte JSON-Dateien auf einen Webserver hoch. In unserem Fall habe ich sie der Einfachheit halber in das Projekt-Repository auf GitHub gestellt. Animationen finden Sie hier:
Basislink
https://raw.githubusercontent.com/chupakabr/server-provided-animations/master/_raw/rendered-animations/Animations-IDs:
clouds.json
fireworks.json
Hinweis: Suchen Sie einen Swift-Webserver für Animationen? Die Lösung finden Sie hier . Eine ausführliche Erläuterung finden Sie in diesem Artikel .
Wir haben also einen funktionierenden Server mit Animationen, also ist es Zeit, mit dem aufregendsten Teil fortzufahren: dem Rendern von Animationen auf dem Bildschirm.
Animationsanzeige
Jetzt rate ich Ihnen, ein
Demo- Projekt für
unsere iOS-Anwendung zu öffnen, da es den gesamten erforderlichen Code und die erforderlichen Einstellungen enthält.
Animationen herunterladen
Da die REST-API zum Empfangen von Daten bereits bereit ist, ist es an der Zeit, das Protokoll des Datenanbieters einzuführen und seine Implementierung hinzuzufügen, die Daten vom Server herunterlädt:
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 Datenproviderklasse können wir auf Anfrage Animationen im JSON-Format vom Server herunterladen und zum Rendern auf der Benutzeroberfläche im Speicher speichern. Angenommen, wir folgen dem MVVM-Muster - dann ist es einfach, es in der
ViewModel
Entität wie folgt zu verwenden:
// ... 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 } } // ...
ViewModel
aktualisiert die Eigenschaft der ausgewählten Animation, wenn die richtige HTTP-Antwort von einem Server mit einem nicht leeren JSON-Objekt empfangen wird. Diese Daten werden von der Präsentationsebene verwendet, um die Animation anzuzeigen.
Präsentationsschicht
Jetzt können wir mit dem
ViewModel
auf die Animationsdaten zugreifen und diese auf der Benutzeroberfläche anzeigen, indem wir den integrierten
ViewModel
, 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() } }
Wenn Sie auf eine Schaltfläche klicken, wird die LOTAnimationView-Instanz mit den neuesten Daten aus dem
ViewModel
aktualisiert.
So sieht es aus:
Das ist alles. Jetzt zeigt die Anwendung die von unserer REST-API heruntergeladene Animation an
(vom Server).
Tipps & Einschränkungen
Tricks:
- AAE unterstützt die meisten Objekttypen, einschließlich Raster- und Vektorbilder.
- Mit Bodymovin können Sie alle Ressourcen mit Base64 in die endgültige JSON-Datei einbetten. Auf diese Weise können Sie vermeiden, Ressourcen auf der Clientseite separat zu laden.
- Sie können entweder direkt in einem Vektor in AAE zeichnen oder einfach Vektorbilder im Adobe Illustrator-Format importieren.
Leider konnte ich keine SVG-Dateien in AAE importieren (ich habe es versucht!).
In diesem
interessanten Artikel meines Kollegen
Radoslaw Sesiva erfahren Sie mehr über Tricks und das Lösen möglicher Probleme.
Fazit
Was bringt uns das Herunterladen von Animationen vom Server? Der offensichtlichste Vorteil dieses Ansatzes ist die Möglichkeit, alle Teilnehmer am Animationsaktualisierungsprozess gemeinsam zu nutzen. Mit anderen Worten, um eine neue coole Animation zu veröffentlichen, müssen Designer dem Serverteam lediglich die entsprechende JSON-Datei zur Verfügung stellen. Um die Animation auf dem Client zu entfernen, entfernen Sie sie einfach vom Server. Einfach und schnell.
Es ist auch sehr cool, dass dieselben Funktionen auf allen unterstützten Plattformen (iOS, Android, Web) implementiert werden können, ohne dass das Client-Server-Protokoll, der Servercode und die Animationsdateien direkt auf dem Client geändert werden müssen.
Das ist alles Vielen Dank für Ihre Aufmerksamkeit!
Nützliche Links