Baru-baru ini saya memutuskan untuk mencoba menerapkan gagasan tentang cara berbagi lokasi melalui VK API dengan teman-teman dalam mode real-time. Outputnya adalah aplikasi Qt lintas platform untuk iOS / Android, aplikasi web untuk VKontakte dan beberapa permintaan tarik untuk VK API. Dalam artikel ini, saya ingin membagikan beberapa poin implementasi yang tidak jelas yang mungkin menarik bagi seseorang. Jadi, tertarik silakan minta kucing.
Mengapa saya membutuhkannya?
Cepat atau lambat, anak-anak tumbuh dewasa. Kebenaran dangkal. Jadi, anak perempuan saya yang berusia sepuluh tahun pada suatu hari berkata, "Ayah, jangan bawa saya dengan mobil lagi, saya ingin pergi ke sekolah sendirian!" Nah, kemudian, saya menemukan klaim adil, meminta masa tenggang dua minggu, dan mulai persiapan.
Karena saya memiliki beberapa pengalaman menulis aplikasi, dan putri saya terus-menerus membawa di saku iPhone SE, sebagai persiapan, diputuskan untuk dengan cepat menulis aplikasi yang akan menunjukkan di mana putri itu berada pada saat tertentu. Ya, saya tahu bahwa sekarang ada banyak aplikasi semacam itu (bahkan fungsionalitas serupa baru-baru ini muncul di Google Maps), dan dimungkinkan untuk menggunakan beberapa solusi yang sudah jadi, tetapi saya tertarik untuk menulis sesuatu dari saya sendiri.
Mengapa VKontakte?
Karena saya tidak ingin mengaitkan dengan pemrosesan dan penyimpanan data pribadi orang lain (kemungkinan prospek) pada peralatan saya dengan semua "pesona" yang timbul dari ini, saya berpikir tentang bagaimana melakukan tanpa bagian server saya sendiri. Dan kemudian saya sadar - setelah semua, ada monster seperti VKontakte! Itu modis, kuat dan dengan API yang dikembangkannya, dan yang paling penting, semua anak kita telah duduk di dalamnya untuk waktu yang lama dan ketat (saya tidak bisa mengatakan bahwa saya menyukainya, tetapi itu kenyataan). Tapi sial, Holmes, bagaimana saya bisa memasukkan data lokasi ke dalamnya sehingga, pertama, itu tidak muncul di tempat yang tidak perlu, dan kedua, sehingga Anda dapat mengontrol akses ke data ini sehingga pedobir yang buruk kepada mereka tidak sampai di sana?
Catatan datang untuk menyelamatkan. Ya, catatan wikipedia yang sama yang dulu (menurut desas-desus) sangat populer dan sekarang berada di kandang, sebagian besar mereka berhenti berkedip di kaset dan pindah ke bagian terpisah dari situs, yang Anda tidak akan mendapatkan kambing lumpuh. Anda dapat menempatkan data teks sewenang-wenang di dalamnya, tetapi yang utama adalah mereka dapat diberi daftar akses yang mencantumkan orang dan grup yang dapat melihat dan mengomentari catatan ini.
Skema umum aplikasi di mata saya mulai terlihat seperti ini:
- Buat daftar teman yang ingin Anda bagikan data lokasi (saya menyebutnya "Teman Tepercaya");
- Kami membuat catatan dengan nama tertentu, memberikan hak untuk melihatnya di daftar di atas, menuliskan data lokasi di sana dan memperbaruinya secara berkala;
- Kami secara teratur menelusuri daftar teman tepercaya, memeriksa untuk melihat apakah mereka juga memiliki catatan dengan nama khusus ini, jika ya, maka kami mencoba mengekstrak data tentang lokasi teman dari isinya, dan jika berhasil, kami menampilkannya di peta;
- ???
- KEUNTUNGAN!
Jadi, ada ide, terserah hal kecil untuk menyadarinya.
iOS
Karena putrinya menggunakan iPhone, logis untuk memulai implementasi dengan versi iOS. Dengan pandangan untuk lintas platform, Qt dipilih sebagai kerangka kerja, karena saya telah terbiasa dengannya sejak lama, dan Open Street Map yang bagus, yang ada plugin di Qt Location, dipilih sebagai mesin untuk peta. Karena aplikasi ini awalnya dibuat sebagai sumber terbuka, pembatasan lisensi Qt tidak membuat saya takut.
GUI ditulis dalam QML, untuk bekerja dengan VK, saya terhubung dan menggunakan
SDK iOS VK biasa, ditulis dalam Objective-C, jadi integrasinya tidak menyebabkan masalah. Bekerja di latar belakang pada iOS diimplementasikan melalui Layanan Lokasi Ubah Signifikan. Untuk mengurangi konsumsi energi, aplikasi memonitor aktivitas gerakan, dan jika memahami bahwa seseorang duduk untuk sekitar satu tempat untuk waktu yang lama (katakanlah, dia datang ke sekolah atau kantor), maka dia menurunkan akurasi yang diperlukan untuk menentukan geolokasi, memaksa OS untuk beralih ke cara yang kurang intensif energi untuk menentukannya (bagaimana sebagai aturan, di menara sel). Jika aplikasi memahami bahwa orang tersebut telah mulai bergerak aktif, keakuratannya meningkat lagi.
Kode sumber lengkap untuk versi iOS tersedia di
GitHub . Berikut adalah beberapa poin tidak jelas yang saya temui dalam proses implementasi:
Mengganti Metode NSApplicationDelegate dalam Aplikasi QtVKontakte iOS SDK memerlukan penambahan panggilan ke beberapa fungsinya dalam aplikasi: didFinishLaunchingWithOptions: dan aplikasi: openURL: options: methods. Sebelum beberapa versi Qt (menurut saya, sebelum 5.11), cukup membuat kategori untuk QIOSApplicationDelegate seperti ini:
@interface QIOSApplicationDelegate : UIResponder <UIApplicationDelegate> @end @interface QIOSApplicationDelegate (QIOSApplicationDelegateVKGeoCategory) @end @implementation QIOSApplicationDelegate (QIOSApplicationDelegateVKGeoCategory) - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [...] } - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options { [...] } @end
Tetapi dalam versi terbaru Qt, QIOSApplicationDelegate sudah memiliki implementasi aplikasi: openURL: options:, sehingga opsi dengan kategori tidak lagi bergulir. Saya harus membuat pewaris dari QIOSApplicationDelegate dan menetapkan delegasi melalui setDelegate:
@interface VKGeoApplicationDelegate : QIOSApplicationDelegate @end @implementation VKGeoApplicationDelegate - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options { [...] } @end void InitializeVKGeoApplicationDelegate() { [[UIApplication sharedApplication] setDelegate:[[VKGeoApplicationDelegate alloc] init]]; } int main(int argc, char *argv[]) { [...] InitializeVKGeoApplicationDelegate(); [...] }
Kesalahan penanganan dari VKRequestMenghadapi kenyataan bahwa VKRequest on error mengembalikan NSError kosong (kosong). Saya membuat tambalan yang menambal tambalan seseorang sebelumnya dan
menarik permintaan untuk tambalan ini, tapi itu masih hang yang belum ditinjau.
Android
Berikut ini adalah versi untuk Android. Kode GUI digunakan kembali dari iOS hampir sepenuhnya, untuk berinteraksi dengan VK,
VK Android SDK biasa digunakan lagi, interaksi dengan yang terjadi melalui JNI, pekerjaan di latar belakang dilaksanakan sesuai dengan perjanjian Google untuk aplikasi tersebut - yaitu, melalui Layanan Foreground. Tentu saja, logika untuk mengurangi konsumsi energi, mirip dengan yang digunakan di iOS, juga diterapkan.
Set lengkap kode sumber untuk versi Android tersedia lagi di
GitHub , dan berikut adalah beberapa poin yang tidak jelas yang saya temui dalam proses penerapan versi ini:
Cara membuat layanan Android di QtUntuk membuat layanan di Qt 5.10, kelas QAndroidService muncul, yang harus digunakan alih-alih aplikasi QGui. Anda dapat mengkompilasi terpisah .so untuk aktivitas dan layanan, atau Anda dapat menggunakan .so untuk semuanya, dan agar kode memahami mode apa yang berfungsi, Anda dapat menentukan mode ini melalui kunci baris perintah, sesuatu seperti ini:
<service android:name=".VKGeoService"> <meta-data android:name="android.app.arguments" android:value="-service"/> </service>
int main(int argc, char *argv[]) { if (argc == 1) { QGuiApplication app(argc, argv); [...] } else if (argc == 2 && QString(argv[1]) == "-service") { QAndroidService app(argc, argv); [...] } else { return 0; } }
Aktivitas "menjuntai" yang aneh di onDestroy ()Dalam proses implementasi layanan, masalah lucu menjadi jelas - QtActivity "tergantung" di suatu tempat di perut onDestroy (), tergantung pada ketersediaan layanan latar depan yang berfungsi. Rupanya, Qt tidak berharap bahwa setelah aktivitas selesai, sesuatu yang lain mungkin tetap dari aplikasi. Masalahnya diselesaikan dengan spasi aktivitas dan layanan di berbagai proses melalui penggunaan android: proses di manifes:
<service android:name=".VKGeoService" android:process=":VKGeoService"> [...] </service>
dan memaku proses di mana aktivitas berjalan, di onDestroy yang ditimpa ():
@Override public void onDestroy() { [...] Process.killProcess(Process.myPid()); }
Ya, serat terus bersumpah pada ini, tetapi bagaimana menghadapinya secara berbeda belum jelas bagi saya, tetapi mendapatkan QTBUG dengan PoC tentang topik ini belum mencapai apa pun.
UPDATE : di Qt 5.12.3 (mungkin sedikit lebih awal - saya tidak memeriksa) bug dengan menggantung QtActivity.onDestroy () diperbaiki ketika layanan dimulai, solusi ini tidak lagi diperlukan.
Missing errorBlock call saat membatalkan VKBatchRequestSaya banyak menggunakan permintaan batch untuk memudahkan memuat di server VKontakte, dan itu berada di bawah Android (semuanya berfungsi dengan baik di iOS) bahwa saya mengalami masalah jika VKBatchRequest dibatalkan dan errorBlocks tidak dipanggil untuk permintaan yang dibatalkan. Saya memperbaiki masalah ini di versi lokal perpustakaan, membuat tambalan yang sesuai dan
menarik permintaan untuk tambalan ini, tetapi sekali lagi itu masih tergantung pada yang belum ditinjau.
Kesimpulan
Versi iOS Apple dengan mudah ditempatkan di App Store, dan masih tersedia di sana, versi Android tinggal di Google Play selama beberapa waktu hingga Kebijakan Google Play diperketat (itu menetapkan bahwa aplikasi pelacakan geolokasi harus secara eksplisit ditujukan untuk penggunaan keluarga atau perusahaan), setelah itu aplikasi saya diblokir dengan aman di sana. Dalam upaya saya untuk mengajukan banding, seorang karyawan Google yang bertanggung jawab (atau mungkin itu adalah bot, sekarang tidak begitu jelas siapa yang menjawab pertanyaan Anda) dengan tegas menyatakan bahwa "baik, aplikasi ini MUNGKIN TIDAK DIGUNAKAN HANYA UNTUK pelacakan keluarga atau perusahaan" , yang saya tidak dapat menemukan apa pun untuk diperdebatkan - memang, dengan palu Anda tidak hanya dapat palu paku, tetapi juga meninju kepala Anda ... Saya menempatkan versi Android di Yandex.Store dan Amazon Appstore dan sebagai APK di situs web proyek.
Saya akan senang jika aplikasi ini bermanfaat bagi seseorang sebagai alat bantu visual untuk memperjelas beberapa momen yang tidak jelas saat menulis aplikasi Qt untuk iOS / Android, terutama yang terkait dengan implementasi layanan Android pada Qt (fungsi ini relatif baru, contoh implementasi, berapa banyak Saya tidak tahu banyak). Saya juga akan dengan senang hati menjawab pertanyaan di komentar, jika ada.