Sejarah panjang buku panduan - bagaimana saya menulis layanan untuk jalur pendakian yang cerdas selama 5 tahun

Banyak yang memiliki satu atau lebih proyek rumah mereka. Ini adalah utilitas kecil, karya eksperimental, sampel teknologi baru, "pembunuh" Facebook dan banyak lagi. Khususnya, proyek semacam itu jarang dilakukan untuk waktu yang lama.


Dalam artikel tersebut saya akan membagikan pengalaman saya dan memberi tahu Anda bagaimana selama 5 tahun saya sesekali mengerjakan pengembangan buku panduan cerdas untuk St. Petersburg, bagaimana saya berhasil tidak meninggalkan bisnis ini, bagaimana sikap terhadap proyek berubah dan apa yang terjadi pada akhirnya.



Banyak solusi teknis dan sepeda yang diragukan dijelaskan di bawah ini, tetapi jangan kaget - hampir semuanya dibenarkan untuk tujuan dan sumber daya yang tersedia pada waktu itu (= biasanya pengetahuan dan waktu saya)

Ide


Di setiap kota wisata besar ada ratusan panduan, baik dan tidak terlalu baik, di mana rute utama dicat, poin utama dan banyak informasi bermanfaat lainnya ditunjukkan.
Tetapi rute di sana konstan dan terbatas, dan pemandangan biasanya hanya yang paling penting, seperti "apa yang akan dilihat dalam 3 hari."


Karena itu, muncul ide membangun rute yang cerdas. Pengguna memilih titik A dan B dan tidak menerima rute terpendek klasik, tetapi sesuatu yang dekat dengannya, tetapi melewati tempat wisata terdekat.


Penonton panduan semacam itu tidak hanya turis, tetapi juga penduduk lokal yang ingin mendiversifikasi rute khas mereka ke rumah / pekerjaan / toko (dan ada ulasan seperti itu di app!) Atau hanya lebih baik untuk mengetahui kota.


TL; DR
Intinya adalah aplikasi Android Wander , yang sekarang hanya berfungsi untuk St. Petersburg.


Babak 1: Prototipe


Gagasan itu muncul kembali di universitas pada tahun 2014, saya bahkan tidak yakin bahwa gagasan itu pada mulanya adalah milik saya, pada beberapa hal perlu dibedakan menjadi kelompok, membuat proyek dan menyelesaikannya sebagai makalah. Mereka jatuh dan menghasilkan ide proyek, dan kemudian nama TravelPath dimulai.


Seharusnya layanan web, saya tahu sedikit tentang PHP, jadi saya memilih PHP.
Itu perlu untuk memecahkan beberapa masalah:


1. Basis Atraksi
Di sini kami bertemu dengan OpenStreetMap , ternyata ini adalah proyek paling keren yang cocok untuk kami. OSM adalah proyek peta komunitas berbasis komunitas dan nirlaba. Seperti Wikipedia, hanya tentang peta.
Unduh peta dalam format xml St. Petersburg - ada daftar sumber daya tempat Anda dapat melakukan ini.
Saat itu, saya ingat, memetakan file dengan berat lebih dari 1 GB, sehingga pengurai streaming ditulis yang memilih objek dari kategori yang dipilih sebelumnya - monumen, taman, gereja, museum.
OSM memiliki dokumentasi lengkap tentang tag, atribut, dan semua yang Anda butuhkan di sini , berkat itu tidak akan sulit untuk mengetahui cara mendapatkan data yang Anda butuhkan dari kartu.


Data kartografi dibuat oleh penggemar, oleh karena itu tidak di mana-mana dan tidak selalu objek memiliki tag yang diperlukan, beberapa tempat memiliki kesalahan, masalah. Namun untuk kota-kota besar, datanya berkualitas cukup tinggi.


Jika saya benar menggali kode lama saya, maka saya menggunakan tag berikut untuk mengambil objek:


  • building makna cathedral , chapel , church sudah menjadi kategori church
  • amenity dengan nilai fountain jatuh ke monument
  • tourism dengan nilai artwork dan viewpoint pergi ke monument , zoo dan museum ke museum , dan theme_park to park
  • historic dengan boundary_stone , castle , memorial , monument masuk ke kategori monument
  • leisure dengan nilai di park secara alami berakhir di park

Kami menempatkan semua objek yang diterima ke dalam database dengan koordinat dan bersukacita! Lebih dari 1.200 poin telah dirilis di St. Petersburg.


2. Membangun rute
Itu tidak dimaksudkan untuk menerapkan sistem yang kompleks sebagai bagian dari kursus, dan pengetahuan teknis pada waktu itu langka, jadi kami memutuskan untuk membagi konstruksi rute menjadi dua bagian: pilihan objek dalam rute dan konstruksi rute itu sendiri. Sebagian, ini menentukan nasib masa depan, karena nanti saya tidak ingin mengubah skema ini.


Konstruksi rute antara titik-titik yang dipilih diberikan oleh Google Maps API, yang membuat rute mobil cukup baik, tetapi pada saat itu tidak tahu cara berjalan, setidaknya di Rusia.


Pilihan objek harus dilaksanakan sendiri. Ternyata skema aplikasi berikut:



Kerugian utama dari pendekatan ini adalah pemilihan titik di rute tanpa memperhitungkan peta, hanya berdasarkan koordinat GPS. Dan secara keseluruhan, ini bekerja dengan cukup baik, terutama di mana ada jalan sering. Masalah langka terlihat di sepanjang sungai dengan jembatan langka, misalnya.


Selanjutnya, kami datang dengan algoritma untuk memilih titik di rute. Di satu sisi, perlu bahwa rute tidak mengalihkan banyak ke samping, tetapi di sisi lain masih memilih beberapa titik di lingkungan yang diberikan.


Bukan pernyataan masalah yang sangat jelas, algoritma yang sama keluar, sesuatu yang mirip dengan A * ( wiki ): diyakini bahwa dari setiap titik ada transisi ke masing-masing. Selain itu, dalam A *, harga pergi ke simpul n saat mencari rute AB biasanya dinyatakan sebagai berikut: f(n) = g(An) + h(nB) , di mana g(x,y) adalah panjang jalur dari x ke y, dan h(x,y) adalah perkiraan heuristik jarak dari x ke y. Harga saya sama - f(n) = h(x,n) + h(n,y) * q , di mana q adalah konstanta kurang dari 1. Dengan mengubah nilai q, Anda dapat memengaruhi jumlah titik dalam rute.


Kami menerapkan algoritme dan, tepuk tangan, semuanya berfungsi, kencangkan antarmuka, beli domain, unggah ke hosting, tulis laporan dan birokrasi lainnya, dan bersukacitalah! Itu terlihat seperti ini (dan tidak banyak berubah setelah):



Total: Saya mendapat prototipe ide keren, berkenalan dengan OSM, Google API, bekerja sebagai tim, mendapat kredit di universitas, dan itu juga menarik.


Babak 2: Versi web lengkap pertama


Saya sangat menyukai ide itu dan saya memutuskan untuk mengembangkannya lebih lanjut, tetapi sudah satu. Dan segera jelas apa yang diperlukan pertama-tama: pada saat itu Google Maps belum dapat membangun rute berjalan, hanya yang mobil sedang dibangun. Dan seluruh ide dari aplikasi ini terutama tentang berjalan, yang berarti Anda harus dapat membangun rute di sepanjang lorong-lorong taman yang teduh, trotoar pejalan kaki, jembatan dan banyak lagi.


Itu pada tahun 2015, dan saya terus bekerja di TravelPath, mengambil koreksi dari kesalahan fatal ini - saya mulai membangun cara saya sendiri.


Saya tidak mengubah teknologi, PHP + MySQL . Tentu saja, saya segera menyadari bahwa ini bukan tumpukan teknis terbaik untuk tugas seperti itu (membangun rute dalam PHP? Serius?).
Tetapi saya terbatas waktu dan tidak siap untuk beralih ke tumpukan yang lebih masuk akal, dan kedua, sampai sekarang proyek ditulis "di atas meja" - Saya ingin menggunakan aplikasi seperti itu dari perangkat seluler, dan pada tahun-tahun itu hanya berarti pengembangan asli. Artinya, ketidakmampuannya dalam bentuk versi web sudah jelas, meskipun ada beberapa upaya untuk membuat antarmuka adaptif.


Tugas-tugas berikut muncul:


1. Memperoleh grafik kota
Di sini OSM yang sama menyelamatkan kita. Sekali lagi, unduh grafik dalam format xml, parsing, pilih hanya jenis jalan yang diperlukan dan kagumi jumlah data - pada saat itu lebih dari 3 juta simpul dan tepi 500k keluar. Gagasan pertama adalah bahwa grafik mungkin tidak berhubungan.
Halaman, wilayah tertutup, hal-hal yang tidak dapat dipahami tidak terlalu menarik untuk membangun rute, jadi kami memilih beberapa titik, berkeliling di seluruh grafik dari itu, menandai simpul yang dilewati dan mendapatkan bagian yang terhubung dari grafik.
Secara total, lebih dari 600 ribu puncak dan 150 ribu tepi keluar.
Disimpan diterima dalam database dan dibiarkan sampai waktu yang lebih baik.


2. Membangun rute
Ada data, semuanya diserahkan kepada yang kecil: buat rute di atasnya. Kami tidak harus menciptakan sesuatu yang baru - ingat jalannya algoritma, baca artikel dengan hati-hati tentang bekerja dengan grafik, ambil algoritma A *, terapkan dalam PHP dan bersukacitalah frustrasi oleh betapa lambatnya semuanya bekerja.


Ada banyak data, oleh karena itu, ketika menyusun grafik, kami tidak menggunakan yang lengkap, tetapi kami hanya membaca sebagian saja - semua yang jatuh ke dalam persegi panjang diperoleh dari semua titik yang dipilih dalam rute.



(bingkai merah = ~ grafik seperti itu dibaca untuk membangun jalan)


Sama dengan poin kandidat untuk rute - kami memperhitungkan tidak semuanya, tetapi hanya yang antara awal dan akhir + nilai kecil.
Setelah memilih ukuran persegi panjang ini (konstanta yang digunakan untuk meningkatkannya), kami mencoba menjamin bahwa kami membaca ukuran data minimum yang disyaratkan.
Ada juga ide memecah kota menjadi kotak, membangun rute pertama dengan kotak, dan kemudian membaca grafik di dalam kotak ini dan mencari jalan hanya di sepanjang itu. Dan Anda dapat pra-menghitung jalur antara semua kotak tetangga. Atau bahkan lebih - untuk menghitung dan menyimpan jalur di antara semua pemandangan. Kemudian on the fly tetap membangun hanya jalur dari awal ke objek pertama, dan dari objek terakhir ke garis finish.
Tetapi tangan tidak mencapai realisasi sepeda seperti itu.


3. Routing dalam jumlah waktu yang wajar
Segera menjadi jelas bahwa bottleneck adalah penyimpanan dan bekerja dengan data - algoritma pencarian itu sendiri tidak terlalu dipercepat. Dan tolok ukur pada lutut mengkonfirmasi bahwa sebagian besar waktu dihabiskan membaca dari database dan manipulasi serupa.
Apa yang harus dilakukan dalam kasus seperti itu? Jangan simpan grafik ini. Tapi saya punya cara khusus, MySQL dan tidak lebih, tetapi masalahnya harus diselesaikan.


  1. Yang pertama - data dinormalisasi, yang nyaman saat parsing, tetapi membaca puluhan ribu catatan dan bahkan dari dua tabel itu menyakitkan. Solusi yang jelas adalah membuat satu dari dua tabel (untuk simpul dan tepi), hanya untuk tepi, di mana di setiap rekaman koordinat dari kedua simpul dan id mereka.
  2. Kami menghitung terlebih dahulu simpul terdekat dari grafik ke pemandangan, dan tidak melakukannya dengan cepat setiap saat.
  3. Sejumlah besar waktu dihabiskan untuk mencari titik grafik terdekat dengan pengguna yang diberikan. Untuk mempercepat ini, saya membagi seluruh grafik menjadi sektor-sektor kecil, menggunakan rumus koordinat yang Anda dapat langsung mendapatkan id sektor, dan kemudian pilih hanya titik di dalam sektor, dan bukan di seluruh grafik, yang jauh lebih cepat.

Setelah semua manipulasi, kami mendapatkan konstruksi rute berjalan yang wajar di St. Petersburg dalam waktu 2 detik, yang terdengar bagus - ini adalah waktu tunggu yang dapat diterima bagi pengguna.
Skema terakhir keluar seperti ini:



Total: Saya berkenalan dengan data OSM bahkan lebih baik, dalam praktiknya saya memecahkan masalah grafik (kasus ketika algoritma grafik akhirnya berguna), menulis tolok ukur pertama saya.


Babak 3: Versi web normal pertama


Di sinilah pikiran pertama tentang proyek sebagai produk yang mungkin berguna bagi seseorang, dan bukan tentang kerajinan di atas meja.
Jadi, Anda perlu menyelesaikan dua masalah paling penting:


  1. Segera jelas bahwa membangun rute seperti yang saya lakukan pada paragraf terakhir salah.
  2. Panduan di peramban mungkin tidak nyaman bagi siapa pun - Anda ingin berjalan-jalan di kota, melihat ke aplikasi yang nyaman di mana Anda dapat membaca apa yang istimewa di sekitar dan seterusnya. Singkatnya, setidaknya - Anda memerlukan antarmuka adaptif yang keren, dan dalam cara yang baik aplikasi seluler.

Tetapi pada tahap ini, saya memutuskan untuk hanya berurusan dengan poin pertama. Kami mempelajari Internet tentang hal ini dan di sini sekali lagi OSM membantu, atau lebih tepatnya proyek yang lahir berkat mereka - OSRM .
Berdasarkan data peta dari OSM, Open Source Routing Machine dapat membangun berbagai rute dalam waktu yang baik. Ya, dan proyek sumber terbuka dengan dokumentasi yang baik yang dapat Anda instal di server dan digunakan.
Sebagai bonus, ia juga memiliki API yang cukup nyaman.
Dan antaresm sudah menulis tentang OSRM pada habr yang membantu saya saat itu. Benar, banyak air telah mengalir dan artikelnya sudah usang. Tetapi banyak terima kasih kepada penulis! Dokumentasi aktual dan cukup bagus ada di sini .
Setelah instalasi berhasil, kami membuang, hampir tanpa penyesalan, semua kode kami tentang rute dan mulai mengikuti rute di api OSRM, dan diagram terakhirnya seperti ini:



Kami bahkan tidak menyentuh bagian klien - pada bagiannya, API layanan kami tidak berubah dengan cara apa pun.


Total : Saya berpikir tentang penggunaan aplikasi yang sebenarnya oleh orang lain, ternyata arsitektur yang normal dan rute yang baik. Versi web masih tersedia, meskipun belum berubah sejak saat itu. https://travelpath.ru/


Babak 4: Aplikasi Android


Terlepas dari solusi untuk masalah masa lalu, masih jelas bahwa proyek ini masih tidak berguna untuk semua orang kecuali saya. Karena Anda memerlukan antarmuka normal dan, yang paling penting, aplikasi seluler, bukan versi peramban. Sekarang teknologinya telah maju dan, mungkin, sudah dimungkinkan untuk membuat aplikasi browser yang berfungsi baik untuk klien seluler, tetapi tidak pada 2015-2016. Yang berarti kemungkinan yang sangat sempit untuk menggunakan proyek dalam bentuk versi web - untuk duduk di rumah, pilih tempat yang menarik untuk dikunjungi terlebih dahulu. Karena itu, jika kita berbicara tentang produk normal, Anda memerlukan aplikasi seluler dengan antarmuka yang baik.


Kemudian pada tahun 2016, saya mulai menulis di Jawa (tetapi backend) dan berpikir bahwa di bawah Android, mereka juga menulis di Jawa. Mengapa tidak mencoba pengembangan aplikasi, itu harus menjadi pengalaman yang menarik.
Masalah kedua adalah bahwa saya tidak tahu cara mendesain dan saya sendiri tidak akan melakukan antarmuka yang baik. Saya datang untuk mengunjungi tempat kerja pertama saya (sebuah studio kecil Le-Dantu) dan mengundang kolega saya burovk untuk berpartisipasi dalam proyek ini. Anehnya, dia setuju, untuk itu banyak terima kasih :)


Tata letak dan prototipe pertama
Pertama-tama, kami mencoba mencari nama baru, karena TravelPath bukan singkatan yang terlalu, dan terlalu berbicara. Maka melalui upaya Cyril muncul "Berkeliaran" dengan logo lucu:



Saya sangat mengaitkannya dengan pria berkumis, tetapi secara umum saya menyukainya.


Kemudian tata letak pertama aplikasi yang akan datang muncul:



Kami juga berpikir, membahas, opsi kedua muncul, yang menjadi versi pertama aplikasi:



Dari sisi pengembangan, saya secara sadar memutuskan untuk tidak menggunakan segala macam kerangka kerja modis yang melakukan sihir yang berbeda - karena ada risiko besar ketika menggunakannya tanpa memahami pekerjaan, dan mempelajari dasar-dasar dan keduanya terlalu sulit. Google, kami membaca dok resmi, artikel pendidikan dan kami mengatasi kesulitan.


Dari masalah dan tugas yang diingat:


  • Untuk android, ada ProGuard - sebuah utilitas yang memampatkan kode sumber selama perakitan, memotong yang tidak digunakan, mengubah nama, dan banyak lagi. Adalah masuk akal bahwa itu ada, tetapi ketika Anda hanya pergi ke pengembangan dan melakukannya sendiri - tidak jelas bahwa ada bidang penamaan ulang dan ini dapat mempengaruhi perilaku. Dan segala sesuatu yang terjadi hanya di majelis prod. Sebagai hasil dari rilis, semuanya keren, tetapi untuk beberapa alasan tidak ada statistik. Anda mulai mendebit dari backend - dan klien mengirim beberapa omong kosong, alih-alih nama bidang normal - a, b, c , dll. Kruk sehingga API mampu menguraikan ini dengan terampil, dan kemudian Anda mengetahui bahwa ProGuard mencoba dan Anda perlu menentukan kelas yang diperlukan sebagai pengecualian dalam konfigurasi. Secara umum tidak ada yang aneh, tetapi jam debugging terbang jauh.
  • Tugas yang menarik adalah memperbarui data aplikasi. Basis data utama dilengkapi dengan file apk dan saya memperbaruinya sebelum setiap rilis. Tetapi Anda juga perlu mendukung pembaruan melalui jaringan sehingga klien selalu memiliki data baru jika ada perubahan.
    Di versi pertama, saya memutuskan untuk hanya fokus pada waktu pembaruan terakhir. Aplikasi menyimpan waktu dari objek yang paling segar, pada setiap permulaannya menanyakan backend dengan waktu ini jika sesuatu yang baru telah muncul. Pembaruan dikirim kepadanya, klien mengingat lagi waktu terbaru dari objek yang diterima (tetapi bukan waktu pembaruan itu sendiri, ini penting).
    Ternyata saya berpikiran buruk - karena setahun kemudian kategori kelima muncul - bangunan. Dan ketika meningkatkan dari versi lama ke versi baru, muncul masalah. Saya harus berubah sedikit dan klien mengirimkan waktu untuk setiap kategori, bukan yang umum. Namun skemanya masih belum sempurna - saat menambahkan bidang baru ke objek, muncul masalah yang tidak dapat dipecahkan seperti itu. Ada ide tentang bagaimana melakukan yang lebih baik, tetapi tangan tidak mencapai dan secara umum tugas itu tidak terlalu prioritas. Moralitas - ada baiknya untuk secara hati-hati mendekati masalah ini dan berpikir sedikit lebih awal.

Dan saya juga ingin mengatakan apa yang sudah diketahui semua orang - Stack Overflow sangat keren dan ini terutama terlihat ketika Anda terbang ke pengembangan sesuatu yang tidak lazim seperti yang saya lakukan - segera menulis aplikasi, dan tidak lancar dari kursus, panduan, contoh demo . Dan ketika tidak ada seorang pun yang bertanya kepada seorang teman. Tapi selain dia, obrolan tentang pengembangan Android juga membantu - di sana Anda dapat mengajukan lebih banyak pertanyaan abstrak dan meminta tips tentang cara terbaik untuk melakukan sesuatu.


5 Desember 2016 aplikasi tersebut hits Google Play
Dia hanya memiliki fungsi dasar - meletakkan rute, melihat informasi tentang poin. Tetapi itu pun tampaknya berhasil! Sukses, tentu saja, hanya di mata mereka sendiri. Ada pemahaman bahwa aplikasi tersebut masih mentah dan perlu ditingkatkan.


Versi lengkap pertama dan media
Oleh karena itu, saya menganggap rilis berikutnya sebagai versi lengkap dan peluncuran pertama.
Pertama-tama, kami meninjau desain dan logo - sekarang menjadi seperti ini:



Dan mereka menambahkan fungsionalitas penting untuk buku panduan - favorit, melihat titik pada peta itu sendiri, daftar objek wisata dengan pencarian. Aplikasi yang diperbarui terlihat seperti ini:



Gagasan lain muncul - untuk menghubungi Museum Night dan membuat mode terpisah untuk acara di St. Petersburg.
Museum Night adalah hari libur internasional tahunan di mana museum buka pada malam hari sering dengan program khusus. Satu tiket berlaku dan banyak yang mencoba berkeliling di banyak museum sekaligus. Pada saat yang sama tidak ada navigator / peta untuk seluler - hanya beberapa fungsi di situs web resmi acara tersebut.
Kedengarannya sangat cocok dengan gagasan Wander dan juga diminati. Saya menghubungi penyelenggara acara, tetapi, sayangnya, ide itu tidak dihargai dan tetap ada di pikiran saya sampai waktu yang lebih baik.


Pada akhirnya, ternyata keren dan akhirnya aplikasi bisa sepenuhnya digunakan. Pada 2 Juni 2018, sebuah rilis dirilis dan kami memutuskan untuk mencoba menunjukkannya kepada dunia - kami membeli beberapa iklan di VKontakte dan Instagram. Tetapi yang paling penting, mereka menulis ke beberapa media. Koran itu menulis catatan tentang peluncuran aplikasi, setelah itu sejumlah publikasi Petersburg - The Village, Dog, dan lainnya - ditulis atau dicetak ulang dengan kipas. Dan akhirnya ada lalu lintas! Instalasi bergegas dengan puncak, grafik aktivitas di dalam aplikasi juga. Tentu saja, kami tidak harus bersukacita untuk waktu yang lama - tetapi kami mendapatkan pengguna pertama, umpan balik yang bermanfaat dan secara umum itu sangat memotivasi. Pada musim panas yang sama, lalu lintas dari pencarian Google Play terlihat, yang sangat menyenangkan, tetapi kemudian hasilnya tidak dapat direproduksi.
Secara keseluruhan, ini memberikan motivasi yang cukup kuat dan membantu untuk terus bekerja pada aplikasi.


Apa yang harus dilakukan selanjutnya? Museum Night, Google jahat, rute melingkar


Musim telah berlalu, aktivitas dalam aplikasi telah turun secara dramatis dan jelas bahwa hanya menggergaji fitur tidak terlalu berguna - tidak ada yang akan melihatnya, tidak ada anggaran untuk pemasaran. Itu perlu untuk datang dengan sesuatu dan kemudian kami kembali ke ide yang ditunda dengan Night of Museums.
Tetapi sekali lagi, tidak mungkin untuk menyetujui kemitraan, namun kali ini kami memutuskan untuk tidak menunda ide, tetapi untuk melakukan semuanya sendiri. Ternyata sejumlah fitur berguna dalam mode panduan terpisah: museum di peta, rute hanya untuk peserta, informasi singkat, favorit.


Selain mode ini, bahkan dari simpanan kami mendapat pelestarian rute dan yang paling penting - fitur tentang rute melingkar.


Rute melingkar selalu lebih penting daripada rute AB, tetapi dengan keras kepala diabaikan. Namun, orang sering berjalan di sekitar metro / rumah / kantor / hotel daripada sengaja dari A ke B. Akhirnya, mereka meraih tangan mereka dan saya datang dengan heuristik sederhana:
Kami mendapatkan semua poin di dalam radius yang diberikan. Radius adalah pembatas untuk panjang rute. Kami memilih beberapa titik terlebih dahulu (syarat acak). Semua yang lain darinya disortir dalam urutan menaik dari sudut di antara itu, pusat dan titik yang diberikan. / , .


, .


, , :



, , , , , . — , , .


Kotlin , , Wander. , . , . , java — .


, , , . — The Village. - 1000 , 1400 . , Wander , , , . .


Google . — 2018 , API. — 2018- Places API . API, - — . .


Places API , . , . , — Google Maps, . .


: android Google Play, . burovk , Wander , .



, , , — . , , , — . , — , . , , .


  • git tag v1.0.5 .
  • , , , .
  • - , .
  • — , //etc .

Android . , , , .


— , .



! , . , , , , , .
:


  1. — ? - ?
  2. . , — .
  3. IOS

. , IOS , .


. Google Play .



  • , — . , . . , .
  • — , . backend , , android Kotlin, , , . , .
  • — . - , . - . , — .

. IOS ( ) — !


PS
https://habr.com/post/414433/ . . , ( -!), .

Source: https://habr.com/ru/post/id471216/


All Articles