
Hai semuanya! Sekitar enam bulan lalu kami meluncurkan salah satu fitur paling menarik di Badoo:
Streaming Langsung . Salah satu fungsi utamanya adalah bahwa pemirsa dapat mengirim hadiah ke pita favorit mereka untuk menyatakan penghargaan mereka. Kami ingin membuat hadiah semewah dan semenarik mungkin, jadi diputuskan untuk membuat beberapa di antaranya benar-benar hidup, dan maksud saya ini adalah animasi. Dan untuk lebih melibatkan orang, kami, tim Badoo, berencana untuk memperbarui hadiah dan animasi itu setiap beberapa minggu.
Sebagai seorang insinyur iOS, Anda mungkin sudah menebak tantangan yang kami hadapi di sini: kebutuhan untuk menambahkan animasi baru dan menghapus yang lama akan membutuhkan banyak pekerjaan dari sisi klien. Kami membutuhkan tim pengembangan Android dan iOS untuk setiap rilis - yang, jika dikombinasikan dengan jumlah waktu yang dibutuhkan oleh ulasan dan persetujuan App Store, akan berarti mungkin beberapa hari sebelum setiap pembaruan dapat ditayangkan. Tetapi kami telah memecahkan masalahnya, dan saya akan menjelaskan kepada Anda caranya.
Ikhtisar solusi
Pada tahap ini, kami sudah tahu cara
mengekspor animasi Adobe After Effects (AAE) ke dalam format yang dapat dibaca oleh aplikasi iOS kami menggunakan perpustakaan Lottie. Namun kali ini, kami melangkah lebih jauh: kami memutuskan untuk membuat semacam layanan penyimpanan animasi, tersedia melalui internet. Dengan kata lain, kami akan menyimpan semua animasi aktual di server dan mengirimkannya ke aplikasi klien sesuai permintaan:

Berikut ini solusi akhir yang terlihat di simulator iOS pada mesin pengembang:
Namun, dalam posting ini, contoh yang akan saya gunakan adalah animasi yang sangat sederhana yang saya buat sendiri. Ini tidak semewah yang Badoo, tapi cukup bagus untuk menunjukkan potensi pendekatan yang dijelaskan.
Mengekspor animasi
Proyek animasi Adobe After Effects (AAE) yang saya gunakan di sini dapat ditemukan bersama dengan
file sumber lain
di github . Jadi, setelah membuka proyek animasi AAE yang terletak di
_raw/animations/Fancy/Fancy.aep
, Anda akan melihat jendela seperti ini:

Pada titik ini, saya tidak akan membahas bagaimana animasi dibuat di AEE, tetapi yang akan saya jelaskan adalah bagaimana mengimpor animasi yang sudah ada dari AAE ke dalam format yang dapat dibaca aplikasi iOS menggunakan
plugin Bodymovin .
Setelah memastikan plugin terinstal, buka dengan memilih opsi
Window / Extensions / Bodymovin di menu:

Sekarang Anda akan melihat jendela Bodymovin di mana Anda dapat memilih animasi yang ingin Anda ekspor, tentukan path file output dan kemudian buka pengaturan ekspor:

Setelah memilih dan membuka pengaturan animasi, kami sekarang dapat meminta Bodymovin untuk menanamkan aset ke dalam file JSON yang dihasilkan dengan mencentang opsi
Aset / Sertakan dalam json :

Akhirnya, komposisi animasi yang dipilih diekspor dan disimpan ke file yang ditentukan dengan mengklik tombol
Render .
Menyimpan animasi di server
Mari kita asumsikan kita telah memindahkan file JSON animasi yang diberikan ke server web pilihan kita melalui Internet. Dalam kasus kami, demi kesederhanaan, saya telah mengunggahnya ke repositori github proyek ini. Animasi tersedia di sini:
URL Basis:
https://raw.githubusercontent.com/chupakabr/server-provided-animations/master/_raw/rendered-animations/ID khusus animasi:
clouds.json
fireworks.json
Catatan: Mencari server web penyedia animasi yang ditulis dalam Swift? Temukan solusinya di sini di github dan penjelasan terperinci di artikel ini .
Pada titik ini, kami memiliki server penyedia animasi yang berfungsi penuh, jadi inilah saatnya untuk beralih ke bagian yang paling menarik: menyajikan animasi kepada pengguna kami.
Mengambil dan menyajikan animasi
Pada titik ini saya sangat menyarankan untuk membuka contoh proyek aplikasi iOS kami yang berlokasi di
Client/ServerProvidedAnimation.xcworkspace
karena sudah memiliki semua kode dan konfigurasi boilerplate yang diperlukan.
Memuat data animasi
Mengingat bahwa titik akhir REST API untuk memperoleh data animasi sekarang sedang berjalan, saatnya untuk memperkenalkan protokol penyedia data dan menambahkan implementasi servernya:
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 } } }
Kelas penyedia data ini memungkinkan kami memuat animasi dari server dalam format JSON sesuai permintaan dan menyimpannya di memori untuk dirender di UI. Dengan asumsi kita mengikuti pola MVVM, ini dapat dengan mudah digunakan dalam entitas
ViewModel
dengan cara berikut:
// ... 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
memperbarui properti data animasi yang dipilih ketika menerima respons HTTP yang valid dari server dengan objek JSON yang tidak kosong di dalamnya. Data ini digunakan oleh lapisan presentasi untuk menjadwalkan pembuatan animasi.
Lapisan presentasi
Sekarang kita bisa menggunakan ViewModel untuk mengakses data animasi dan menyajikannya melalui UI di action handler "on tap" yang dilampirkan pada tombol:
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() } }
Pada dasarnya, yang kita miliki di sini adalah penangan tombol yang memicu pembaruan contoh LOTAnimationView dengan data animasi terbaru yang berasal dari
ViewModel
.
Seperti apa hasil akhirnya:
Cukup banyak. Animasi sekarang sedang dimuat dari titik akhir REST API yang disiapkan dan diberikan pada klien sesuai permintaan.
Kiat & Keterbatasan
Kiat dan trik:
- AAE memungkinkan penggunaan sebagian besar jenis aset termasuk grafik raster dan vektor;
- Bodymovin memungkinkan untuk menanamkan semua aset ke dalam file animasi JSON keluaran (menggunakan pengkodean base64) - ini berarti kita dapat menghindari pemisah aset yang terpisah di sisi klien;
- Untuk animasi, Anda memiliki pilihan antara menggambar langsung ke vektor di AAE, atau hanya mengimpor grafik vektor Adobe Illustrator.
Sayangnya, impor vektor vektor SVG ke AAE belum dimungkinkan (saya sudah mencoba!).
Lebih banyak trik dan masalah potensial dijelaskan dalam
artikel menakjubkan yang ditulis oleh kolega saya
Radoslaw Cieciwa .
Kesimpulan
Jadi, apa yang diberikan oleh animasi yang diberikan server kepada kita? Manfaat paling nyata dari pendekatan ini adalah kemampuan untuk memisahkan semua pemangku kepentingan dari aliran pembaruan animasi. Dengan kata lain, untuk merilis animasi baru yang mewah, yang harus dilakukan oleh semua desainer adalah memberikan representasi JSON animasi kepada tim server. Dan untuk menghapus satu, tim server hanya perlu menghapus animasi tertentu dari layanan penemuan. Tidak ada waktu yang terbuang!
Hal keren lainnya adalah fungsionalitas yang sama dapat diterapkan pada semua platform klien yang didukung (iOS, Android, Web, ..) tanpa harus menyesuaikan fungsionalitas server yang ada atau animasi mentah.
Itu untuk hari ini! Terima kasih sudah membaca
Sumber daya