Halo semuanya! Baru-baru ini, ada kontes dari VKontakte Mobile Challenge, dan pekerjaan saya memenangkan hadiah. Pada instruksi tahap kedua, perlu dikembangkan umpan berita untuk perangkat seluler, dan kriteria evaluasi utamanya adalah pengguliran dan pengunduhan posting yang lancar. Ketika saya berpartisipasi, saya memutuskan bahwa terlepas dari hasil akhirnya, saya akan mencoba untuk menulis artikel tentang pendekatan untuk penerapan rekaman itu dan tentang emosi dan perasaan saya selama kontes. Yang saya lakukan. Di bawah kucing, tips dan trik untuk mengembangkan feed berita dalam mode mendongeng.

Tentang kontes
Pertama-tama, ada baiknya menceritakan sedikit tentang kompetisi. Seperti yang saya tahu, VKontakte setiap tahun menyelenggarakan acara semacam itu untuk pengembang seluler. Saya sendiri sudah berpartisipasi pada 2012 dan 2013. Tugas masing-masing adalah pengembangan filter obrolan dan gambar. Pada 2013, saya berhasil mencapai babak final dan memenangkan 100.000 rubel, yang menurut saya jumlah yang sangat baik selama 4 hari libur dari pekerjaan yang menarik.
Dan, melihat iklan di jejaring sosial, saya memutuskan bahwa saya perlu mencoba, karena yang paling keren adalah membuktikan kepada diri sendiri bahwa Anda masih dapat menulis kode berkualitas tinggi dalam waktu yang sangat singkat).
Ada 2 tahap dalam kompetisi: pada tahap pertama, diusulkan untuk lulus tes 30 pertanyaan, menyelesaikan 2 masalah olimpiade dan satu berkualitas tinggi (mis., Solusi adalah seperangkat pemikiran Anda dalam bentuk teks). Dalam putaran kedua 1000+ orang, hanya 112 yang berlalu (kita hanya berbicara tentang iOS, pada Android nilai yang sedikit lebih rendah) dan tahap utama dimulai - pengembangan aplikasi.
Pada penugasan, Anda harus membuat umpan berita, menulis integrasi dengan VK API sendiri, umpan seharusnya sangat lancar di semua perangkat, ada persyaratan tertentu untuk output konten (posting dengan gambar dan korsel, penghitung suka, berbagi, jumlah tampilan, serta kemampuan untuk meminimalkan dan menyebarkan pos dalam kondisi tertentu).
Tata letak ditata dalam Figma. Ini adalah pilihan yang baik untuk kompetisi - karena jumlah pengguna aktif, kompetisi langsung terasa (dan bahkan pingsan pada hari Sabtu, karena batas simultan 50 koneksi terlampaui).
Secara umum, penyelenggaraan kompetisi berjalan lancar kecuali untuk beberapa poin: segera setelah publikasi penugasan, tautan ke tata letak ternyata rusak, kemudian, seperti yang saya katakan di atas, pada hari Sabtu pintu masuk ke Figma diblokir (masalah ini diperbaiki dengan sangat cepat), yah, setelah acara, butuh waktu cukup lama mengharapkan hasil. Tetapi semua negatif memperlancar pos yang serupa:
Rencana dan Strategi Kemenangan
Blok yang sangat penting dan menarik jika Anda berpartisipasi dalam kompetisi atau ingin mencoba. Sebelum berpartisipasi, saya merekomendasikan semua orang untuk memikirkan tujuan apa yang Anda kejar dan hasil apa yang ingin Anda dapatkan di jalan keluar. Sebelum saya memulai kontes, saya memutuskan sendiri bahwa saya ingin memenangkannya (mis. Ambil hadiahnya). Dan untuk melakukan ini, Anda memerlukan strategi:
Berikut ini adalah formula untuk strategi kemenangan (bagi saya tampaknya universal dan sederhana, tetapi saya yakin sebagian besar peserta tidak mengikutinya):
- Baca tugas dengan sangat hati-hati . Setelah beberapa jam, bacalah lagi (saya masuk ke situasi beberapa kali ketika saya tidak melihat tugas pertama kali). Dan beberapa jam sebelum pengiriman sekali lagi untuk jaga-jaga.
- Tulis pertanyaan dan tanyakan pada panitia (biasanya persyaratan penugasan tidak memperhitungkan banyak situasi, atau diekspos dengan sangat dangkal). Saya melakukan hal itu, mendapatkan jawaban dengan gaya "pilihan Anda."
- Buat rencana proyek. Ya, partisipasi dalam kompetisi atau hackathon adalah proyek. Proyek ini memiliki tujuan, garis waktu, sumber daya, dan anggaran. Waktu sangat terbatas, dan tidak mungkin untuk memindahkan akhir perubahan. Orang tambahan tidak dapat diundang - kompetisi ini bukan kompetisi tim. Yang Anda miliki adalah orang-orang Anda sendiri. / jam. Segera tentukan berapa banyak yang akan Anda keluarkan (pikirkan dengan baik berapa yang akan digunakan untuk tidur, makanan, pengebirian, istirahat, dan ya, produktivitas Anda akan turun karena kelelahan dan saraf karena perasaan tidak berdaya di depan kerangka waktu yang tak terhindarkan).
- Rencana tersebut harus memiliki tugas, prioritas dan bobotnya (saya menggunakan perkiraan dari formulir 1, 2, 4, 8). Penilaian tersebut mencakup durasi, keengganan untuk memenuhinya, dan risiko potensial (kompleksitas, kondisi yang tidak dapat dipahami, tidak ada pengalaman dalam pengembangan tersebut, dll.). Selanjutnya, Anda menyusun rencana terperinci (atau tugas peta jalan) - pertama yang paling penting dan kompleks (biarkan mudah dan dapat dimengerti di akhir).
- Pilih beberapa interval atau tonggak besar (hari-hari hebat - kami punya 3 hari). Dan ketika Anda membaca masing-masing dari mereka, lihatlah rencana kerja Anda, uraikan tugas-tugasnya, sortirlah, dan yang paling penting, coret semua yang sudah Anda lakukan dengan senang hati.
Sekarang sarannya (saya lakukan hanya itu): hati-hati melihat bagaimana tugas dirumuskan, apakah itu mengandung kata-kata "wajib" dan "tambahan". Dan apa kriteria evaluasi untuk item dari "tambahan", yaitu apakah mereka akan mengesampingkan kurangnya persyaratan yang diterapkan dari bagian "wajib". Saya meragukannya. Karena itu, fokuslah pada bagian "wajib". Bagi saya sendiri, saya umumnya sengaja mencoret bagian "lanjutan" dan bahkan tidak bermaksud untuk memulainya. - Saat menerapkan, berhati-hatilah dengan detailnya . Misalnya, jika tugas memiliki banyak bentuk antarmuka, maka lakukan seperti yang ditampilkan pada tata letak. Perhatikan indentasi, font, bayangan, penspasian garis, dll. Ini tentu akan menambah poin Anda untuk akurasi dan konsistensi. Ngomong-ngomong, dalam Figma, tidak seperti Zeplin, ada ekspor pengaturan yang sangat luas, misalnya, Anda bisa mendapatkan NSAttributedString yang bagus.
Misi dibuka pada malam Kamis hingga Jumat. Jumat adalah hari kerja dan tidak ada peluang dan keinginan untuk terlibat dalam kompetisi di tempat kerja. Karena itu, setelah pulang kerja pada Jumat malam, saya pertama kali terlibat dalam perencanaan, evaluasi, dan menghitung berapa banyak waktu nyata yang bisa saya habiskan.
Rencana awal adalah sebagai berikut:
Hari | Waktu | Tugasnya |
Jumat | 4 jam | Otorisasi, memperoleh data untuk profil dan rekaman. |
Sabtu | 9 jam | Prototipe rekaman dengan tampilan kotak merah dari ketinggian yang berbeda, memuatnya di atas dengan menarik-untuk-menyegarkan dan memuat tanpa henti ke dalam sejarah, menyiapkan semua model dan layanan (bekerja dengan API, caching permintaan, caching gambar).
|
Minggu | 9 jam | Output dari data nyata (teks, gambar tunggal dan korsel), penghitung suka, tampilan dan penyetelan akhir oleh tata letak. |
Teknik Penerapan Tape
Hore! Tuan-tuan, pengembang, Anda telah menemukan blok yang tepat. Di sini kita akan berbicara tentang implementasi bagian utama dari tugas - umpan berita.
Secara umum, jika kita melepaskan, umpan berita hanya merupakan implementasi yang diterapkan, secara umum, kita akan berbicara tentang membuat daftar entitas heterogen (yaitu, masing-masing dapat memiliki tampilan sendiri, yang memerlukan perhitungan tambahan dan tinggi sendiri, yang dapat berubah secara dinamis bahkan setelah posting ditampilkan) , ditambah daftar dapat memperbarui melalui tarik-untuk-menyegarkan dan memuat data tanpa batas dari bawah.
Itu adalah masalah umum yang saya putuskan untuk dipecahkan sejak awal. Langkah pertama adalah menganalisis solusi yang ada. Anda harus fokus pada yang terkuat, jadi saya memilih 3 aplikasi untuk perbandingan: Vkontakte, Facebook, Instagram.
Jadi, saya ingin melakukan studi tentang 6 masalah paling akut dan kritis:
- Tarik-untuk-menyegarkan (tambahkan ke bagian atas daftar)
- Pemuatan riwayat yang lancar (tambahkan di akhir daftar)
- Pengguliran cepat (secara bergantian dengan jari kami mempercepat pita sebanyak gaya gesekan memungkinkan)
- Gulir ke atas (menumpuk berita besar dan klik pada bilah status)
- Apakah ada pengungkapan dinamis (peningkatan) pos dan apa animasinya
- Bagaimana rekaman itu bekerja dalam mode packet loss hampir lengkap (Pengembang -> Network Link Conditioner -> Very Bad Network)

Secara umum, semua aplikasi berperilaku baik, tetapi saya masih melihat beberapa masalah.
Lihat, misalnya, bagaimana perilaku tarik-untuk-menyegarkan pada VKontakte jika Anda tidak melepaskan jari Anda selama pembaruan dan dengan lembut menarik pita ke atas (lihat gif di sebelah kiri).
Apakah Anda juga melihat lompatan ini?
Instagram dan Facebook tidak menunjukkan perilaku seperti itu.
Dan ada juga perbedaan mencolok dalam pengungkapan pos. Untuk Facebook dan Instagram, ini terjadi dengan animasi yang halus, dan VKontakte cukup memperbarui ukurannya dengan mengklik.



Jadi tugas kita adalah membuat gulir yang lancar, mengunduh posting, dan juga mengungkapkan dengan animasi.
Langkah pertama adalah memilih konsep dan membuat prototipe pada kotak merah (saya bertanya-tanya mengapa saya selalu secara intuitif memilih merah untuk prototipe. Apakah ini yang terjadi pada semua orang?).
Gagasan utama saya dalam meningkatkan produktivitas adalah meninggalkan semua lonceng dan peluit yang diperkenalkan Apple selama bertahun-tahun dan benar-benar mundur ke pengembangan untuk iOS 3. Dan ini berarti:
- Penolakan dari AutoLayout (ya, itu lambat, jangan percaya - saya bisa membuktikannya di komentar)
- Penolakan untuk secara otomatis menghitung tinggi sel tabel
Akibatnya, konsep berikut ini dipilih:
Mari kita sedikit lebih detail.
Di utas utama, kami memperbarui antarmuka, memproses tindakan pengguna (gulir ke bawah dan tarik untuk menyegarkan, klik pada posting untuk meningkatkannya) dan memicu model layanan untuk menerima dan menyiapkan data.
Panggilan API . Semuanya sederhana di sini - NSURLSession dengan NSURLCache yang dikonfigurasi. Penting bahwa ketika memuat riwayat, kami menggunakan cache, dan ketika menarik untuk menyegarkan kami menonaktifkannya. Persis seperti ini perilaku saya memata-matai VK dan Facebook.
Parsing dan membuat model . Berikut ini adalah logika untuk memproses permintaan tertentu, melempar kesalahan dan mengembalikan model transportasi dengan data.
Perhitungan model presentasi . Langkah paling penting untuk mengoptimalkan kinerja. Di sini model transport ditransformasikan menjadi entitas dengan postfix PostModel. ViewModel menyimpan data yang disiapkan sepenuhnya untuk tampilan - AttributedString, tinggi sel terhitung (untuk 2 negara: diciutkan dan diperluas), nama lengkap sebagai string, string tanggal (sudah dikonversi dari DateFormatter).
Hanya setelah itu data kembali ke aliran utama. Menerapkan logika seperti itu di Swift sangat mudah dan sederhana. Kami membuat struktur ViewModel. Struktur ketika ditransfer ke aliran baru disalin.
Konsep luar biasa siap, sekarang mari kita bicara tentang mekanisme output itu sendiri.
Pertama, Anda harus memilih untuk mengimplementasikan rekaman itu pada - UITableView atau UICollectionView (pasti tidak akan ada cukup waktu yang dialokasikan untuk implementasi Anda). Jelas, UITableView cocok untuk menampilkan keluaran, tetapi saya sangat khawatir jika akan ada masalah dengan memperbesar daftar dari atas, bawah, dan juga meningkatkan sel konten. Oleh karena itu, saya memutuskan untuk beralih dari yang sederhana ke kompleks - yaitu jika UITableView tidak memiliki masalah, kami tinggalkan.
Hal pertama yang saya putuskan adalah memutuskan tarik-untuk-menyegarkan. Untuk menerapkan pola ini, ada UIRefreshControl. Suatu kali, sekitar 5-6 tahun yang lalu, saya menulis implementasi saya menggunakan UIActivityIndicator dan mengubah contentInset of the table. Jadi, tolong jangan lakukan itu sekarang! UIRefreshControl memiliki antarmuka ringkas yang nyaman dan mengambil awan kruk, yang tentunya harus Anda buat. Menggunakannya sangat sederhana:

Namun, ketika menggunakannya, menjadi jelas dari mana masalah yang ditunjukkan di atas untuk klien VK tumbuh. Tampaknya mereka ada di komponen itu sendiri. Saya dengan cepat mencoba mencari apa yang bisa menjadi alasan dan apa solusinya.
Kiat internet mengatakan (ini atau
itu ):
- periksa ketika memanggil endRefreshing apakah kontrol sekarang diperbarui (isRefreshing)
- gunakan persis UITableViewController (karena dalam kasus ini metode private magic disebut)
Saya mencoba ini dan itu - saya tidak memiliki efek positif. Saya kesal, tetapi memutuskan untuk tidak membuang waktu dan melanjutkan. Ngomong-ngomong, jika seseorang tahu cara mengatasi masalah ini - silakan tulis di komentar.
Langkah selanjutnya adalah mengimplementasikan pemuatan data dari bawah.
Pada awalnya saya tidak menjadi sangat keren - ketika memuat dari bawah ada kelambatan yang mengerikan (tampaknya saya melompati contentSize dari tabel):
Dan ini adalah neraka :-) Dengan hasil ini, Anda pasti tidak bisa menang. Tapi pencarian cepat memberi saya petunjuk hebat yang saya lupa:

Dan voila:
Tetap memutuskan bagaimana menghidupkan tinggi sel.
Gagasan pertama yang muncul di benak saya adalah berlari di sepanjang Sel yang terlihat dan menambah ketinggian di blok animasi. Tetapi bahkan pada tahap analisis, ide ini harus dibuang - masalahnya adalah perlu mensinkronisasi ketinggian yang ditentukan dalam UITableViewDataSource dan melakukan sesuatu dengan contentSize (dan ini sangat direkomendasikan oleh Apple).
Pikiran kedua yang muncul di benak ternyata benar - UITableView memiliki metode insert / reload / delete yang dapat dieksekusi di blok animasi:

Jangan lupa bahwa pada heightForRowAt kita juga perlu menambahkan ketinggian baru:

Segalanya tampak, tetapi tidak cukup! Dalam animasi penyebaran pos, ada satu titik halus. Cari teks di Intagram atau Facebook - teks itu segera muncul dengan meningkatnya ketinggian. Apa yang harus dilakukan Jadikan baris demi baris? Jika Anda mencapai level NSTextContainer, maka mungkin peluang serupa akan muncul. Tetapi bagi saya sepertinya bukan ide yang buruk (untuk saat itu) untuk menampilkan semua teks sekaligus. Cukup atur clipToBounds ke superView, di mana UILabel akan ditemukan, menampilkan teks kami. Dan pendekatannya berhasil! Oh, animasi ini sangat menginspirasi saya dan angin kedua dibuka. Bagaimanapun, tidak ada animasi seperti itu di klien asli VK. Jadi dia harus menambahkan peluang untuk menang :-)
Detail yang tersisa dalam implementasi rekaman itu tidak begitu menarik. Tetapi Anda dapat menanyakannya di komentar. Dan tidak ada yang salah dengan meletakkan kode. Ini dia -
github.com/katleta3000/vkmobilechallenge . Saya minta maaf karena saya tidak menyisir dan ada Angka Ajaib di beberapa tempat (tapi ini adalah kontes kecepatan, saya harus mengorbankan sesuatu). Ngomong-ngomong, Anda bisa melompat pada komit di sana (namanya cukup jelas).
Anda dapat melihat hasilnya di sini -
www.youtube.com/watch?v=Md8YiJxSW1M&feature=youtu.be (kualitasnya tentu saja sangat buruk, tetapi lebih baik daripada di gif untuk menunjukkan gulir yang benar-benar mulus)
Statistik, Hasil, Kesimpulan
Setiap saat kontes bekerja pada timer. 20 setengah jam waktu pengkodean murni keluar. Waktu pelacakan membantu dalam 2 hal: seperti yang Anda ingat, ada perkiraan dalam unit abstrak, sehingga pada pertengahan hari terakhir sudah ada statistik pelacakan yang baik dan mungkin untuk merencanakan tugas akhir yang tersisa jauh lebih akurat. Dan, kedua, adalah mungkin untuk mengidentifikasi dan membuktikan pola "konsentrasi dalam satu duduk". Setiap dimensi adalah iterasi baru, jadi ternyata saya memiliki 68 iterasi penulisan kode. Jika Anda rata-rata, Anda akan mendapatkan 18,5 menit. Tetapi pada kenyataannya, pada hari pertama iterasi, ada rata-rata 25 menit, dan pada akhir hari kedua, masing-masing 7 menit :-) Anda mulai menjadi gila, menjadi sangat gugup, lelah dan kinerja menurun. Data seperti itu akan membantu dengan baik lain kali.
Secara pribadi, saya menggunakan program
Hourly (Anda dapat mengunduh dan mencobanya) - sederhana dan menyelesaikan tugas yang diperlukan (dan bahkan mengembangkannya sendiri):
Dari bonus yang bagus - untuk setiap puzzle yang tertutup, Anda akan melihat layar meyakinkan yang sangat bagus seperti ini:
Sangat lucu bahwa pada saat penyelesaian tugas "VK Mobile Challenge" muncul layar berikut kepada saya:
Dan ya! Dan begitulah yang terjadi :-) Kami melanjutkan ke hasil.
Jangan menarik Peach untuk yang mewah. Peach, yang tidak tahu, adalah nama kucing - karakter utama VK. Merchandise hadiah yang sangat keren:
Saya mengambil tempat ke-4 dan mendapat 175k rubel. (Ya, dan Anda mungkin sudah membakar gambar di Habra-kat). Dan ya, saya tentu senang. Saya mencapai tujuan saya :-) Dan ini tidak diragukan lagi sangat menyenangkan.
Pada akhirnya, saya ingin mengucapkan terima kasih kepada
vkontakte - lagipula, kompetisi itu keren dan terorganisir dengan baik. Dan saya merekomendasikan semua pembaca untuk mengambil bagian dalam tantangan dan hackathon - ini adalah cara yang bagus untuk menantang diri sendiri dan bersaing dengan pengembang top di seluruh dunia (baik, atau setidaknya komunitas berbahasa Rusia).