Mari kita lihat perpustakaan bukan dari sisi yang paling akrab bagi kita, yaitu, pengguna, tetapi dari sudut pandang pengembang perpustakaan pengembangan seluler. Mari kita bicara tentang pendekatan apa yang harus diikuti ketika mengembangkan perpustakaan Anda. Kami memulai, tentu saja, dengan merancang API yang ingin Anda gunakan sendiri, yang nyaman. Kami akan memikirkan apa yang perlu dipertimbangkan untuk membuat tidak hanya kode yang berfungsi, tetapi perpustakaan yang sangat bagus, dan sampai pada titik rilis rilis publik dewasa nyata.
Asya Sviridenko akan membantu kami dalam hal ini, yang akan membagikan pengalamannya yang luar biasa dalam mengembangkan perpustakaan seluler SpeechKit di
Yandex .
Materi ini akan berguna tidak hanya bagi mereka yang terlibat dalam pengembangan perpustakaan atau kerangka kerja, tetapi juga bagi mereka yang ingin memisahkan bagian dari aplikasi mereka ke dalam modul terpisah, dan kemudian menggunakannya kembali, atau, misalnya, membagikan kode mereka dengan seluruh komunitas pengembang dengan mempostingnya di akses publik.
Bagi semua orang, kisah ini akan diisi dengan kisah-kisah nyata dari kehidupan tim ponsel SpeechKit, jadi itu pasti menyenangkan.
Isi
- Menit bicara .
- Merancang API yang nyaman dan mudah dimengerti yang ingin Anda gunakan.
- Pengembangan . Apa yang ditambahkan ke kode sehingga tidak hanya berfungsi dan melakukan fungsionalitas, tetapi juga membantu pengguna Anda.
- Luncurkan - apa yang tidak boleh Anda lupakan ketika Anda meluncurkan roll.
Menit bicara
Saya tidak akan bertanya apakah Anda mendengar tentang SpeechKit, karena bahkan di dalam Yandex, tidak semua orang tahu apa itu SpeechKit.
SpeechKit adalah pintu ke semua teknologi bicara Yandex . Dengan menggunakan perpustakaan ini, Anda dapat mengintegrasikan teknologi bicara ke dalam aplikasi Anda: pengenalan dan sintesis suara, aktivasi suara.
Anda mungkin pernah mendengar tentang asisten suara Alice - dia hanya bekerja berdasarkan SpeechKit. SpeechKit sendiri tidak termasuk pengakuan atau sintesis, itu terjadi di server. Tetapi melalui perpustakaan kami bahwa semuanya dapat diintegrasikan ke dalam aplikasi.
Berikut ini biasanya muncul pertanyaan - jika segala sesuatu di server terjadi, apa yang dilakukan perpustakaan? Mengapa itu dibutuhkan?
Perpustakaan melakukan banyak hal:
- Sinkronisasi semua proses. Misalnya, menggunakan asisten suara, pengguna mengklik tombol, mengatakan sesuatu, menyela asisten, membuat permintaan - semuanya masuk ke perpustakaan. Bagi pengguna perpustakaan kami ini transparan, mereka tidak perlu khawatir tentang semua ini.
- Jaringan Karena semuanya terjadi di server, Anda perlu mendapatkan data dari sana, memprosesnya, dan memberikannya kepada pengguna. SpeechKit sekarang dapat pergi ke beberapa server yang berbeda dalam koneksi jaringan yang sama: satu terlibat dalam pengenalan, yang lain dalam alokasi makna, yang ketiga dalam pengenalan musik, dll. Ini semua tersembunyi di dalam perpustakaan, pengguna tidak perlu khawatir.
- Bekerja dengan sumber audio. Kami berurusan dengan pembicaraan manusia, dan bekerja dengan audio juga terjadi di dalam SpeechKit. Selain itu, kami tidak hanya dapat menulis dari perangkat standar, tetapi juga menerima data dari mana saja. Ini bisa berupa file atau stream - kita dapat bekerja dengan semua ini.
SpeechKit digunakan dalam tim internal. Sekarang telah terintegrasi oleh 16 tim Yandex. Dan kita bahkan tahu tentang beberapa tim eksternal yang melakukan ini juga.
Desain
Mari kita pikirkan tentang apa yang kita maksud dengan aplikasi yang nyaman. Biasanya, ini adalah UX yang bijaksana dan dapat dimengerti, solusi untuk masalah kita, operasi yang stabil, dll.
Ketika kita mengatakan bahwa sebuah perpustakaan itu nyaman, pertama-tama kita maksudkan bahwa ia memiliki API sehingga mudah digunakan. Bagaimana cara mencapai ini?
Prinsip dasar
Ini adalah beberapa aspek yang saya pelajari dari pengalaman saya dengan SpeechKit.
- Pertama-tama, ingatlah bahwa pengguna Anda adalah pengembang .
Di satu sisi, itu bagus, karena Anda tidak menjelaskan kepada pengguna biasa: "Anda tahu, backend ada bersama kami, dan karena itu tidak ada yang berhasil, dan kami baik-baik saja!" Anda bisa menjelaskannya kepada pengembang - Anda bisa menjelaskan banyak kepada pengembang!
Di sisi lain, Anda mendapatkan pengguna seperti itu yang pasti akan mengambil kesempatan untuk menemukan lubang dan menghancurkan sesuatu jika Anda meninggalkannya. Kita semua menggunakan perpustakaan dan mencoba untuk mendapatkan yang terbaik dari mereka. Mereka mengklaim bahwa mereka hanya melakukan ini, ini dan ini, dan kami berpikir, "Tidak, sekarang kami akan bermain-main sedikit di sini, kami akan meneruskannya dan semuanya akan seperti yang seharusnya."
Selain itu, fakta bahwa pengguna adalah pengembang berarti bahwa Anda akan selalu memiliki segunung kiat dan trik tentang cara mengembangkan dan cara membuat semuanya lebih baik.
Poin penting kedua sepenuhnya konsisten dengan poin pertama.
- Segala sesuatu yang tidak diizinkan di perpustakaan Anda harus dilarang,
sehingga tidak ada celah yang tidak diinginkan.
Jika pengguna Anda mulai melakukan sesuatu dengan perpustakaan yang tidak Anda harapkan, ini adalah jalur langsung ke bug, dan yang sulit di-debug. Cobalah untuk menggunakan semua yang diberikan bahasa dan teknologi yang Anda gunakan: publik / pribadi, final, usang, hanya baca. Kurangi ruang lingkup, larangan pewarisan dan penggunaan beberapa metode, tandai properti yang tidak dapat diubah - sediakan semua yang mungkin untuk mencegah sesuatu yang tidak dirancang untuk dilakukan oleh perpustakaan Anda.
- Jangan biarkan ambiguitas dalam penafsiran API perpustakaan Anda.
Jika kelas khusus ini dapat dibuat dengan satu cara, tolak semua yang lain. Jika properti ini tidak boleh nol, tentukan secara eksplisit. Di iOS ada nullable / nonnull, initializer yang ditunjuk, yang sama ada di Java dan Android. Gunakan semua ini agar pengguna dapat membuka file, membuka kelas Anda, membahasnya dan segera memahami apa yang bisa dilakukan dan apa yang tidak bisa dilakukan.
API Kasus SpeechKit
Menggunakan SpeechKit sebagai contoh, saya akan memberi tahu Anda bagaimana kami refactored versi 2 ke versi 3. Kami banyak mengubah API dan mencoba menggunakan semua prinsip ini.
Kebutuhan muncul karena
API itu kompleks dan "teoretis" . Ada komponen global di dalamnya yang harus disebut pertama - tidak disebut - semuanya tidak berfungsi. Pengaturan yang sangat aneh ditetapkan. API itu cukup "teoretis", karena SpeechKit awalnya adalah bagian dari Navigator, dan kemudian bagian ini dibawa ke perpustakaan. API pada dasarnya bekerja dengan kasing yang digunakan di Navigator.
Secara bertahap, jumlah pengguna bertambah, dan kami mulai memahami apa yang benar-benar mereka butuhkan: metode apa, panggilan balik, parameter. Mereka datang kepada kami dengan permintaan yang tidak diizinkan diterapkan oleh API. Ini diulangi berulang-ulang, dan menjadi jelas bahwa API tidak sesuai standar. Jadi kami terlibat dalam refactoring.
Proses refactoring itu lama (setengah tahun) dan menyakitkan (semua orang tidak bahagia) . Kesulitan utama adalah tidak mengambil segunung kode dan menulis ulang. Tidak mungkin hanya pergi untuk refactoring, tetapi perlu untuk mendukung semua versi aktif yang sedang digunakan. Kami tidak bisa hanya memberi tahu pengguna kami: "Kawan, ya, itu tidak berfungsi untuk Anda, ya, Anda memerlukan fitur ini - kami akan melakukan segalanya dalam versi 3, harap tunggu enam bulan!"
Akibatnya, refactoring memakan waktu lama, dan prosesnya menyakitkan, dan bagi pengguna juga. Karena pada akhirnya, kami mengubah API tanpa kompatibilitas ke belakang. Mereka mendatangi mereka dan berkata, "Ini SpeechKit baru yang indah, tolong ambil!" - mereka menjawab: "Tidak, kami tidak memiliki rencana untuk meningkatkan ke versi 3.0 Anda sama sekali." Misalnya, kami memiliki tim yang beralih ke versi ini dalam setahun. Karenanya, selama setahun kami mendukung versi sebelumnya untuk mereka.
Tetapi hasilnya sepadan. Kami
mendapat integrasi sederhana dan lebih sedikit bug . Inilah yang saya sebutkan dalam prinsip-prinsip desain dasar API. Jika Anda yakin bahwa API Anda digunakan dengan benar, pasti tidak ada masalah di bagian ini: semua kelas dipanggil dengan benar, semua parameter sudah benar. Menemukan bug jauh lebih mudah, lebih sedikit kasus di mana terjadi kesalahan.
Di bawah ini adalah contoh bagaimana kelas utama yang berhubungan dengan pengakuan terlihat sebelum refactoring.
Ini adalah kelas reguler yang diwarisi dari NSObject. Mari kita pertimbangkan masing-masing detailnya secara terpisah. Jelas bahwa kita dapat mewarisinya, mendefinisikan kembali beberapa metode di dalamnya - semua yang dapat dilakukan dengan NSObject.
Kemudian, saat membuat, dua baris (bahasa dan model) diteruskan ke sana. Apa baris-baris ini? Jika Anda lulus dalam bahasa "Halo, dunia", maka hasilnya akan berupa terjemahan, atau apa? Tidak terlalu jelas.
Selain itu, karena ini adalah penerus NSObject, kita dapat memanggil init, baru, dll. Apa yang akan terjadi Apakah akan berfungsi, atau akan menunggu beberapa parameter?
Tentu saja, saya tahu jawaban atas pertanyaan-pertanyaan ini, saya tahu kode ini. Tetapi orang-orang yang melihat ini untuk pertama kalinya tidak mengerti sama sekali mengapa ini semua. Bahkan metode dengan setter dan pengambil tidak terlihat sama sekali seperti apa di iOS. Metode start, cancel, cancelSync (dan yang hanya membatalkan - apakah itu aSync?) - apa yang akan terjadi jika mereka dipanggil bersama? Banyak pertanyaan pada kode ini.
Berikutnya adalah objek yang saya bicarakan (YSKInitializer), yang harus dimulai agar semuanya berfungsi - umumnya semacam sihir. Dapat dilihat bahwa kode ini ditulis oleh pengembang yang tidak menulis untuk iOS, tetapi terlibat dalam C ++.
Selanjutnya, pengaturan untuk pengenal ini ditetapkan melalui komponen global yang ditransfer ke objek global lain, dan pada kenyataannya tidak mungkin untuk membuat dua pengenal berbeda dengan set parameter yang berbeda. Dan ini mungkin salah satu kasus paling populer yang tidak mendukung API.
Daripada v3 lebih baik dari v2
Apa yang kita dapatkan ketika kita refactored dan beralih ke versi 3?
- API yang sepenuhnya asli.
Sekarang API iOS kami tampak seperti iOS-API, Android API tampak seperti Android.
Poin penting yang tidak segera kami sadari adalah bahwa pedoman platform jauh lebih penting daripada keseragaman API perpustakaan Anda.
Misalnya, kelas untuk Android dibuat menggunakan pembangun, karena ini adalah pola yang sangat dimengerti untuk pengembang Android. Di iOS, ini tidak begitu populer, jadi pendekatan yang berbeda digunakan: kami membuat objek dengan kelas pengaturan khusus.
Saya ingat bagaimana kami berdebat lama tentang hal ini. Tampaknya penting bagi kami bahwa pengembang mengambil kode kami di iOS atau Android, dan pertandingan akan menjadi 99%. Tapi ini tidak benar. Lebih baik, kode akan mirip dengan platform yang sedang dikembangkan.
- Inisialisasi sederhana dan intuitif .
Objek ini diperlukan - inilah pengaturannya, buat, transfer - untung! Artinya, tidak ada pengaturan global tersembunyi yang perlu ditransfer ke suatu tempat.
- Kurangnya komponen global.
Kami membuang komponen global yang membingungkan, takut, dan menimbulkan banyak pertanyaan bahkan di antara para pengembang perpustakaan ini, tidak hanya pengguna.
Sekarang kelas yang sama dalam versi baru terlihat seperti ini (itu masih Objective-C - Anda tidak dapat beralih ke Swift).
Ini adalah penerus NSObject, tetapi sekarang kami jelas berbicara tentang fakta bahwa Anda tidak dapat mewarisi darinya. Semua metode yang merupakan karakteristik dari objek ini ditransfer ke protokol khusus. Itu dibuat menggunakan pengaturan dan sumber audio. Sekarang semua pengaturan dirangkum dalam satu objek, yang ditransfer secara khusus di sini untuk mengatur pengaturan untuk pengenal tertentu.
Selain itu, kami menghapus pekerjaan dengan audio dari sini, yaitu, reconnaiser sekarang bukan komponen yang menulis audio. Komponen ini menangani masalah pengenalan, dan sumber apa pun dapat ditransfer di sini.
Metode pembuatan lain melalui baru atau melalui init dilarang, karena kelas ini memerlukan pengaturan default. Silakan, jika Anda ingin menggunakannya, buat setidaknya beberapa pengaturan default.
Hal utama adalah bahwa pengaturan yang ditransfer di sini tidak dapat diubah, yaitu, Anda tidak dapat mengubahnya dalam proses. Tidak perlu mencoba, ketika sesuatu dikenali, untuk mengganti model atau bahasa. Karenanya, kami tidak memberikan pengguna kesempatan untuk mengubah objek dengan pengaturan yang telah ditransfer.
Macros NS_ASSUME_NONNULL_BEGIN / NS_ASSUME_NONNULL_END untuk menekankan bahwa pengaturan ini tidak boleh nol: audioSource tidak boleh nol - semuanya harus memiliki nilai tertentu agar dapat berfungsi.
Seperti yang saya katakan, mulai dan membatalkan metode (cancelSync kiri) pindah ke protokol terpisah. Ada tempat-tempat di perpustakaan di mana Anda dapat menggunakan bukan pengintai kami, tetapi yang lain. Sebagai contoh, kami menggunakan Apple asli, yang mengimplementasikan protokol ini dan ke dalamnya dapat mentransfer komponen kami.
Pengaturan di sini adalah NSCopying sehingga kami dapat menyalinnya, dan mereka tidak dapat diubah dalam proses. Di init, parameter yang diperlukan adalah bahasa, model, dan NS_DESIGNATED_INITIALIZER. Ini bukan sepotong kode yang identik dengan metode usang, tetapi idenya jelas. Ini adalah parameter yang diperlukan dengan pengaturan yang dibuat. Mereka harus, dan harus bukan nol.
Sisa dari set adalah sekitar 20 pengaturan pengenal diatur di sini. Bahkan pengaturan bahasa atau model juga merupakan kelas terpisah yang tidak memungkinkan kita untuk menyampaikan sesuatu yang abstrak, yang dengannya kita tidak dapat bekerja. Yaitu, kami dengan jelas mengatakan: βTolong jangan beri kami sesuatu yang kami tidak tahu bagaimana bekerja dengannya. Kompiler tidak akan membiarkan Anda melakukan ini. "
Jadi, kami berbicara tentang apa yang dapat Anda lakukan dengan API. Perkembangannya juga memiliki nuansa tersendiri.
Pengembangan
Pertama-tama, perpustakaan harus melakukan apa yang Anda tulis - untuk menjalankan fungsinya dengan baik. Tetapi Anda dapat membuat kode Anda perpustakaan yang sangat bagus. Saya mengusulkan beberapa komentar yang saya kumpulkan selama pengembangan SpeechKit.
Kode ini bukan hanya untuk Anda sendiri
Sangat penting untuk
mengumpulkan informasi Debug , karena Anda tidak ingin pengguna mengatakan bahwa layanan mereka tidak berfungsi karena perpustakaan Anda.
IOS memiliki tingkat informasi debug yang menunjukkan informasi apa yang perlu dikumpulkan. Secara default, ia akan mengumpulkan semua yang dapat ditemukannya: semua panggilan, semua nilai. Ini bagus, tetapi ini adalah jumlah data yang sangat besar. Pengaturan -gline-tables-only memungkinkan Anda mengumpulkan informasi tentang panggilan fungsi. Ini lebih dari cukup untuk menemukan masalah dan memperbaikinya.
Ini termasuk dalam pengaturan Xcode (Pengaturan Bangun), dan disebut tingkat informasi debug. Misalnya, dengan mengaktifkan pengaturan ini, kami mengurangi ukuran file biner SpeechKit dari 600 MB menjadi 90 MB. Ini bukan informasi yang sangat penting dan kami hanya membuangnya.
Hal penting kedua adalah
menyembunyikan karakter pribadi . Anda semua tahu bahwa setiap kali Anda mengunggah perpustakaan ke iTunes, Anda berisiko mendapat peringatan baru bahwa Anda menggunakan sesuatu yang salah, bukan menambahkan sesuatu. Karena itu, jika Anda menggunakan perpustakaan yang Apple anggap pribadi, pastikan untuk menyembunyikannya. Ini tidak berarti apa-apa bagi Anda, Anda juga dapat bekerja dengannya, tetapi segera setelah pengguna Anda mencoba mengunggah aplikasi dengan perpustakaan Anda ke iTunes, mereka akan menerima kesalahan. Tidak semua orang akan meminta Anda untuk memperbaikinya, sebagian besar hanya akan menolak untuk menggunakan solusi Anda.
Hindari konflik karakter : tambahkan awalan untuk semua yang Anda miliki, ke kelas Anda, ke kategori. Jika perpustakaan memiliki kategori UIColor + HEX, pastikan bahwa pengguna Anda memiliki kategori yang sama persis, dan ketika mereka mengintegrasikan perpustakaan Anda, mereka akan menerima konflik karakter. Dan lagi, tidak semua orang ingin memberi tahu Anda dan mengatakannya.
Pertanyaan lain adalah ketika Anda sendiri menggunakan perpustakaan pihak ketiga di perpustakaan Anda. Ada beberapa nuansa yang patut diingat. Pertama, jika Anda menggunakan sesuatu yang muncul dalam versi yang lebih lama dari perpustakaan Anda, jangan lupa untuk menggunakan
Weak Linking (Xcode -> Build Phases -> Tautan Biner Dengan Perpustakaan -> Status dihidupkan). Ini memungkinkan Anda untuk tidak jatuh jika tiba-tiba perpustakaan ini tidak jatuh.
Dokumentasi Apple merinci cara kerjanya. Tetapi tautan lemah tidak berarti bahwa perpustakaan tidak akan memuat jika tidak digunakan. Artinya, jika waktu mulai aplikasi penting bagi pengguna Anda, dan Anda mungkin tidak memerlukan bagian perpustakaan Anda yang menggunakan perpustakaan pihak ketiga dan membutuhkan waktu untuk memulai, penautan yang lemah tidak akan membantu Anda. Dengan itu, perpustakaan masih memuat apakah itu digunakan atau tidak.
Jika Anda ingin memuat ke dalam runtime, ini akan membantu menghilangkan masalah tautan saat startup, maka Anda perlu menggunakan dlopen dan pemuatan dinamis. Ini membutuhkan banyak keributan, dan Anda harus terlebih dahulu memahami apakah ini masuk akal. Facebook memiliki
kode yang agak
menarik sebagai contoh bagaimana mereka terhubung secara dinamis.
Terakhir -
cobalah untuk tidak menggunakan entitas global di dalamnya . Setiap platform memiliki beberapa komponen global. Dianjurkan untuk tidak menyeret mereka ke perpustakaan Anda. Ini tampak jelas karena ini adalah objek global, dan pengguna perpustakaan Anda dapat mengambil dan mengonfigurasinya sesuka mereka. Anda menggunakannya di perpustakaan Anda, Anda perlu entah bagaimana menyimpan statusnya, mengkonfigurasi ulang, lalu memulihkan keadaan. Ada banyak nuansa, dan ada tempat untuk membuat kesalahan. Ingat ini dan coba hindari.
Misalnya, di SpeechKit, sebelum versi ketiga, kami bekerja dengan audio di dalam perpustakaan, dan kami secara eksplisit mengatur dan mengaktifkan sesi audio. Sesi audio di iOS adalah hal yang dimiliki setiap aplikasi - jangan katakan Anda tidak memilikinya. Ini dibuat pada awalnya, bertanggung jawab atas interaksi aplikasi dan daemon media sistem, dan mengatakan apa yang ingin dilakukan aplikasi Anda dengan audio. Ini adalah objek tunggal dalam arti kata yang sesungguhnya. Kami dengan tenang mengambilnya, mengaturnya sesuai kebutuhan kami, tetapi ini mengarah pada fakta bahwa pengguna memiliki masalah kecil seperti mengubah volume suara. Metode lain sesi audio, yang bertanggung jawab untuk pengaturan pengaturan, cukup lama. Dibutuhkan sekitar 200 ms, dan ini adalah penurunan yang terlihat pada aktivasi atau penonaktifan.
Di versi ketiga, saya dengan senang hati mengeluarkan sesi audio dari perpustakaan. Setelah itu, hampir semua pengguna dari semua layanan yang memiliki SpeechKit terintegrasi mengatakan mereka sangat tidak bahagia. Sekarang mereka harus tahu bahwa ada semacam sesi audio yang perlu dikonfigurasi khusus untuk SpeechKit kami.
Kesimpulan dari ini adalah ini: semua sama, cobalah untuk tidak menggunakan entitas global, tetapi bersiaplah untuk kenyataan bahwa pengguna Anda tidak akan selalu senang dengan keputusan Anda.
Kami membuatnya nyaman bagi pengguna
Bagaimana lagi Anda bisa membantu pengguna Anda?
- Tambahkan log: level berbeda, inklusi dinamis .
Cara termudah adalah melampirkan file, untuk keberadaan mode mega debug diluncurkan. Sangat membantu untuk melakukan debugging dalam situasi di mana pengguna Anda memiliki pengguna yang memiliki kesalahan, dan Anda perlu memahami apa yang sebenarnya terjadi.
- Mendukung semua versi OS pengguna.
Ingat bahwa ketika Anda berbicara tentang dukungan versi di pustaka, itu tidak sama dengan dukungan versi di aplikasi reguler. Dalam aplikasi reguler, kami melihat statistik yang, misalnya, hanya 2% dari pengguna kami menggunakan iOS 8, dan itu berarti Anda dapat berhenti mendukung iOS 8. Di perpustakaan, tidak demikian, di sini menolak versi OS berarti sepenuhnya mengabaikan pengguna Anda dan semua penggunanya. Ini mungkin setengah dari pengguna Anda pada prinsipnya.
Oleh karena itu, Anda perlu memantau versi mana yang digunakan oleh aplikasi yang menggunakan perpustakaan Anda, dan berdasarkan ini, Anda harus sudah menyimpulkan apakah Anda mendukung sesuatu atau tidak. Kami tidak meninggalkan iOS 7 untuk waktu yang sangat lama. Sepertinya bagi saya sudah ada orang yang meninggalkan iOS 8 dan siap untuk meninggalkan iOS 9. Kami masih mendukung iOS 7 karena kami memiliki browser yang hingga saat terakhir menjaga semua pengguna dan kami bekerja erat dengannya dan tidak dapat meninggalkannya dalam situasi seperti itu.
Sekali lagi, pengguna Anda tidak akan mengatakan: "Mari kita matikan fungsionalitas ini pada versi yang tidak mendukungnya," tidak, mereka hanya akan menghapus pustaka Anda dan menemukan satu yang mendukung seluruh rangkaian versi.
- Tambahkan selisih minimal di versi baru.
Ini sangat "tidak terlalu" untuk pengembang perpustakaan. Saya ingin merilis semua yang siap untuk dirilis. Anda membuat fitur, memperbaiki bug - sekarang kami akan meletakkan seluruh paket dan meluncurkannya ke rilis. Rilis juga merupakan proses. Ini tidak demikian untuk pengguna Anda. Ketika mereka sedang dalam proses menguji produk mereka dan mempersiapkannya untuk rilis, mereka tidak ingin menerima dari Anda sebuah perakitan dengan fitur-fitur baru yang memerlukan pengujian tambahan.
Kami benar-benar memiliki kasing ketika kami memutar kembali beberapa rilis, membaginya menjadi beberapa bagian dan meluncurkannya menjadi beberapa bagian. Kemudian tim-tim di mana kami menerapkan perubahan dapat mengambil versi persisnya di mana ada perubahan kecil, dan tidak semuanya sekaligus.
Ini sebenarnya tidak terlalu nyaman untuk pengembangan, tetapi peningkatan minimal dalam versi akan membuat pengguna Anda sedikit lebih bahagia.
Tidak pernah ada terlalu banyak tes
Ini berlaku untuk aplikasi reguler dan perpustakaan. Tetapi dalam kasus perpustakaan lagi ada fitur.
Autotests , tentu saja, diperlukan, tetapi selain itu sangat bagus untuk memiliki
aplikasi tes untuk perpustakaan Anda. Ini akan membantu Anda mengintegrasikan apa yang Anda tulis sendiri dan memahami masalah atau jebakan apa yang mungkin timbul. Anda dapat merasakan sendiri apa itu pengguna Anda.
Jika perpustakaan Anda entah bagaimana berinteraksi dengan jaringan, termasuk enkripsi, setidaknya ada sesuatu yang berkaitan dengan data dan keamanan, berikan kepada penjaga
keamanan untuk
verifikasi . Anda benar-benar tidak ingin menjadi perpustakaan di mana mereka menemukan kerentanan - itu adalah stigma seumur hidup. Hampir semua perusahaan besar memiliki seluruh departemen yang berurusan dengan memeriksa produk untuk keselamatan - berikan kepada mereka. Jika Anda tidak memilikinya, ada
audit eksternal . Jika Anda tidak mampu membeli eksternal, temukan tes pada jaringan, jalankan, pastikan perpustakaan Anda tidak mengizinkan kebocoran data pengguna.
Hal terakhir yang sangat penting dalam pengujian adalah dari awal mencoba menambahkan
pengukuran segala sesuatu yang mungkin : waktu, konsumsi daya, segala sesuatu yang khas untuk perpustakaan khusus Anda. Anda masih harus melakukan ini pada akhirnya, jadi mengapa tidak memikirkan pengukuran dari awal.
Ini tidak melindungi terhadap perubahan dan dari kebutuhan untuk mempercepat perpustakaan, tetapi membantu untuk mencari tahu apa yang salah. Jika Anda memiliki grafik, ini akan membantu dalam pemantauan waktu-nyata dari fungsionalitas apa yang menambahkan penundaan waktu atau peningkatan konsumsi daya.
Hampir tidak pernah ada waktu untuk ini, karena ini bukan fungsi perpustakaan, ini bukan tujuan Anda mengembangkannya. Tapi inilah yang membantu Anda mempertahankannya dalam kondisi baik dan dalam kualitas yang baik.
Di sini Anda dapat membaca bagaimana kami di Yandex mengukur konsumsi energi perangkat seluler. Tentang pengukuran waktu adalah cerita lucu. Sebagai pengembang perpustakaan, sulit bagi kami untuk mengukur perilaku dalam kasus tertentu, karena tidak semua skrip SpeechKit digunakan oleh semua tim. Sampai saat ini, kami menggunakan aplikasi pengujian kami. Kasus penggunaan khusus ditulis, misalnya, pengenal atau komponen untuk sintesis ucapan, setiap langkah direkam dan log disimpan, dan sebagai hasilnya, grafik keren dibuat.
Semuanya akan baik-baik saja, tetapi kami bekerja dengan audio, dan untuk memeriksa semuanya, dalam kasus tertentu trek audio benar-benar diputar. Selain itu, perlu untuk melakukan banyak pengukuran, sehingga mereka meninggalkan tes untuk malam: meletakkan speaker, meletakkan beberapa jenis perangkat di sebelahnya, dan memulai file audio. Di pagi hari semuanya mati, malam berikutnya berulang, dan sekali lagi. Sama sekali bukan tentang beberapa makhluk ajaib yang berjalan di sekitar kantor - hanya petugas kebersihan yang takut. Benar-benar ada teks yang sangat aneh yang dibaca pada interval waktu tertentu.
Akibatnya, diputuskan untuk membuat bangku tes lokal, yang kami sebut Kabinet. Ini adalah kabinet alami, hanya kedap suara. Ini berisi banyak perangkat, seluruh pertanian dengan perangkat, yang masing-masing dapat diluncurkan berkali-kali selama hari kerja, karena tidak akan merugikan siapa pun.
Luncurkan
Akhirnya kita sampai pada bagian penting terakhir - ini adalah peluncurannya. Kode ditulis, API yang baik dirancang untuk membuatnya nyaman bagi pengguna. Bagaimana sekarang untuk melepaskan semua ini menjadi rilis.
Saya akan mulai dengan rilis lokal untuk pengguna di dalam Yandex. Skema di sini sama dengan pengembangan aplikasi reguler: rilis reguler, bulanan atau mingguan.

Prosesnya terdiri dari tahapan-tahapan yang biasa, tetapi ketika mengembangkan perpustakaan, masing-masing poin ini memiliki karakteristiknya sendiri.
Perencanaan
Bagi saya, ini adalah bagian yang paling menyakitkan, karena perpustakaan memiliki beberapa tim produk. Dalam aplikasi reguler, ada satu manajer produk yang menetapkan tugas yang diprioritaskan oleh tim dan mulai dilakukan satu per satu.
Jika ada beberapa tim produk, maka masing-masing dari mereka menerima permintaan yang harus diproses secara real time. Saya akan memberikan saran: jika ada seseorang yang tahu bagaimana menangani banyak tugas yang datang pada satu saat, cobalah untuk menjemputnya di tim Anda. Karena harus ada seseorang di antara semua manajer eksternal dan pengembangan - orang yang akan mengambil fungsi untuk memprioritaskan tugas.
SpeechKit , , , . , , - . , β . , n . , . , , - .
, , : , , . Agile- .
, , , β . , . !
Scrum . , , , . . Β« Β», .
Scrum , , , β β , . . β , - . , ? , : Β«, , , Β». , , - , , Scrum . ! , .
. , , . , . , , , , . , . .
, β , - . , , , , . , . : Β« 4, 3 β Β». , . - , , ,
, .
β
. Continuous Integration , , ,
.
, . .
1.
.β
. - - , , , . .
. , β , , , , . , , - .
2.
., , , β , , , , , !
. ,
. , , -, .
β
. SpeechKit . , , β , - . β , - .
,
. , 4 2, , . , -, , .
β
. , , , .
. .
, -, .
. , , , help , .

. : -, GitHub, , . β , β . , , .
, , - , , ..
, , :
- . , . - , , .
- . , . , OpenSource , , , , .
- . , . , , . . SpeechKit .
Ringkasan
Yandex.SpeachKit GitHub
iOS ,
Android ,
Mobile SDK.
AppsConf β β 22 23 2019 , , .
. , , .