Perilaku untuk perubahan lokasi API yang signifikan ketika dihentikan / ditangguhkan?

108

Ini adalah bagian dari dokumentasi CLLocationManager yang menjelaskan perilaku aplikasi dengan startMonitoringSignificantLocationChanges :

Jika Anda memulai layanan ini dan aplikasi Anda kemudian dihentikan, sistem secara otomatis meluncurkan kembali aplikasi ke latar belakang jika acara baru tiba. Dalam kasus seperti itu, kamus opsi diteruskan ke application: didFinishLaunchingWithOptions: metode delegasi aplikasi Anda berisi kunci UIApplicationLaunchOptionsLocationKey untuk menunjukkan bahwa aplikasi Anda diluncurkan karena peristiwa lokasi. Setelah peluncuran ulang, Anda masih harus mengonfigurasi objek pengelola lokasi dan memanggil metode ini untuk terus menerima peristiwa lokasi. Saat Anda memulai ulang layanan lokasi, acara saat ini dikirimkan ke delegasi Anda segera. Selain itu, properti lokasi objek pengelola lokasi Anda diisi dengan objek lokasi terbaru bahkan sebelum Anda memulai layanan lokasi.

Jadi pemahaman saya adalah bahwa jika aplikasi Anda berhenti (dan saya berasumsi jika Anda tidak memanggil stopMonitoringSignificantLocationChanges dari applicationWillTerminate ) Anda akan terbangun dengan parameter UIApplicationLaunchOptionsLocationKey ke application: didFinishLaunchingWithOptions . Kemudian Anda membuat CLLocationManager , panggil startMonitoringSignificantLocationChanges dan lakukan pemrosesan lokasi latar belakang untuk terbatas . Jadi saya baik-baik saja dengan bagian ini.

Paragraf sebelumnya hanya berbicara tentang apa yang terjadi ketika aplikasi dihentikan, tidak menyarankan apa yang Anda lakukan ketika aplikasi ditangguhkan. Dokumentasi untuk didFinishLaunchingWithOptions mengatakan:

Aplikasi melacak pembaruan lokasi di latar belakang, dihapus, dan sekarang telah diluncurkan kembali. Dalam kasus ini, kamus berisi kunci yang menunjukkan bahwa aplikasi diluncurkan kembali karena acara lokasi baru.

Menyarankan bahwa Anda hanya akan menerima panggilan ini saat aplikasi Anda diluncurkan (karena perubahan lokasi) setelah Anda dihentikan.

Namun paragraf di Layanan Perubahan Signifikan dalam Panduan Pemrograman Kesadaran Lokasi mengatakan hal berikut:

Jika Anda membiarkan layanan ini berjalan dan aplikasi Anda kemudian ditangguhkan atau dihentikan, layanan secara otomatis membangunkan aplikasi Anda saat data lokasi baru tiba. Saat bangun, aplikasi Anda diletakkan di latar belakang dan diberi sedikit waktu untuk memproses data lokasi. Karena aplikasi Anda berada di latar belakang, aplikasi tersebut harus melakukan pekerjaan minimal dan menghindari tugas apa pun (seperti membuat kueri jaringan) yang mungkin mencegahnya kembali sebelum waktu yang dialokasikan berakhir. Jika tidak, aplikasi Anda dapat dihentikan.

Ini menunjukkan Anda dibangunkan dengan data lokasi jika aplikasi Anda telah ditangguhkan, tetapi gagal menyebutkan bagaimana Anda dibangunkan:

  • Apakah itu UIApplicationDelegate mendapatkan panggilan balik yang memberi tahu saya bahwa saya melanjutkan dari status ditangguhkan ke status latar belakang?
  • Apakah pengelola lokasi (yang dibekukan saat aplikasi ditangguhkan) mulai menerima callback locationManager: didUpdateToLocation: fromLocation ?
  • Apakah saya hanya perlu menerapkan kode dalam pesan didUpdateToLocation saya yang memeriksa status aplikasi dan melakukan pemrosesan minimal jika dalam mode latar belakang?

Dalam proses penulisan ini, saya pikir saya mungkin baru saja menjawab pertanyaan saya sendiri, tetapi akan sangat bagus jika pemahaman saya tentang ini dikonfirmasi oleh seseorang yang lebih berpengetahuan.

RedBlueThing
sumber

Jawaban:

80

Sejak saya mengajukan pertanyaan ini, saya telah melakukan sedikit pengujian (kebanyakan di kereta antara rumah dan kantor) dan telah mengonfirmasi bahwa perilaku untuk aplikasi yang ditangguhkan seperti yang saya duga di akhir pertanyaan.

Artinya, aplikasi Anda yang ditangguhkan dibangunkan, Anda tidak menerima callback apa pun pada delegasi aplikasi Anda, sebagai gantinya Anda menerima pembaruan lokasi melalui CLLocationManagerDelegate yang ada . Anda dapat mendeteksi bahwa Anda sedang berjalan di latar belakang dengan memeriksa applicationState , dan melakukan pekerjaan terbatas untuk kasus ketika Anda dibangunkan dari status ditangguhkan untuk melakukan pemrosesan lokasi.

[UIApplication sharedApplication].applicationState == UIApplicationStateBackground

Saya sampai pada kesimpulan ini dengan memanfaatkan uji lokasi yang dapat Anda unduh dan coba. Ini adalah aplikasi yang cukup sederhana yang memungkinkan Anda mengaktifkan perubahan signifikan dan API perubahan GPS melalui UI dan mencatat semua respons yang Anda dapatkan kembali.

NB Poin enam pada jawaban sebelumnya salah. Membekukan kering aplikasi ditangguhkan lakukan menerima CLLocationManagerDelegate callback ketika mereka terbangun dari keadaan ditangguhkan.

RedBlueThing
sumber
1
Gunakan # 6 dalam jawaban saya agar tidak membingungkan orang.
Aaron
Ironisnya, saya juga merasakan kebingungan yang sama saat mengembangkan perubahan yang signifikan. Saya masih ragu tentang apa yang terjadi jika aplikasi ditutup. apakah callback UIApplicationDelegate tidak akan terjadi? adalah cara yang tepat untuk memulai aplikasi. jika pengelola lokasi belum diaktifkan, bagaimana bisa mendapatkan pemberitahuan di latar belakang? (waktu untuk R&D lagi)
darshansonde
Terima kasih banyak untuk aplikasi sampelnya, itu sangat berguna bagi saya. Saya punya pertanyaan: Bagaimana jika saya menggunakan layanan lokasi standar di latar belakang, bukan yang signifikan, apakah aplikasi juga akan diluncurkan kembali setelah penghentian dalam kasus itu? Saya mengajukan pertanyaan ini di sini secara mendetail, saya akan senang jika Anda dapat meringankan saya:] stackoverflow.com/questions/12239967/…
aslisabanci
2
Tidak bekerja di ios7 stackoverflow.com/questions/18946881/…
Igor
Tahukah Anda berapa lama waktu yang dibutuhkan hingga aplikasi Anda dihentikan? Lalu dapatkan callback appDelegate sebagai gantinya? (Apakah seperti 30 menit? 2 jam? 5 jam?) Alasan saya menanyakan hal ini adalah karena saya telah menyiapkan wilayah untuk memantau. Mencoba berkali-kali untuk melihat aplikasi saya diluncurkan tetapi hanya sekali saya harus meluncurkan kembali aplikasi. Di lain waktu didExitRegionpanggilan balik tetapi saya tidak dapat startLocationUpdatesdari sana karena tidak melalui peluncuran aplikasi ...
Sayang
25

Pemahaman saya adalah sebagai berikut (Saya sedang dalam proses menulis aplikasi yang mengandalkan API ini, tetapi belum menyelesaikan komponen ini cukup untuk memulai pengujian):

  1. Aplikasi Anda dijalankan untuk pertama kali, Anda mendaftar ke startMonitoringSignificantLocationChanges , dan menyediakan fungsi callback. Saat aplikasi Anda berjalan, itu akan memanggil callback itu setiap kali menerima perubahan signifikan.
  2. Jika aplikasi Anda diletakkan di latar belakang, UIApplication akan menerima applicationWillResignActive , diikuti oleh applicationDidEnterBackground .
  3. Jika aplikasi Anda terhenti saat ditangguhkan di latar belakang, Anda tidak akan diberi tahu; Namun, jika aplikasi Anda mati saat sedang berjalan (latar depan atau latar belakang sepengetahuan saya), Anda akan mendapatkan momen dengan applicationWillTerminate . Anda tidak dapat meminta waktu latar belakang tambahan dari fungsi ini.
  4. Meskipun dimatikan di latar belakang, OS akan meluncurkan kembali aplikasi Anda. Jika aplikasi Anda hanya diluncurkan oleh OS untuk suatu perubahan, Anda akan mendapatkan panggilan ke application didFinishLaunchingWithOptions :

    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey])

    akan membantu Anda menentukan apakah Anda kembali dari perubahan lokasi latar belakang.

  5. Jika, sebaliknya, Anda saat ini berjalan di latar belakang, dan aplikasi Anda diluncurkan kembali secara manual oleh pengguna, Anda akan menerima applicationWillEnterForeground diikuti oleh applicationDidBecomeActive .
  6. Terlepas dari bagaimana hal itu terjadi, saat aplikasi Anda diluncurkan kembali (kecuali jika masih berjalan di latar belakang sebagai akibat dari tugas latar belakang dan tugas tersebut telah mulai memantau perubahan), Anda perlu secara eksplisit memberitahukannya ke startMonitoringSignificantLocationChanges lagi karena callback tidak ada lebih lama dipasang setelah "pengeringan beku". Dan ya, Anda hanya perlu mengimplementasikan kode dalam didUpdateToLocation setelah Anda memasang kembali penangan lokasi setelah kembali dari status ditangguhkan.

Inilah yang saya lakukan dengan pengembangan kode saya sekarang. Seperti yang saya sebutkan sebelumnya, saya belum cukup siap untuk menguji ini pada perangkat jadi saya tidak tahu apakah saya telah menafsirkan semuanya dengan benar, jadi pemberi komentar, jangan ragu untuk mengoreksi saya (meskipun saya telah membaca substansial pada tema).

Oh, dan jika karena sedikit kesialan, Anda merilis aplikasi yang melakukan apa yang saya ingin saya lakukan, saya mungkin menangis :)

Semoga berhasil!

Aaron
sumber
1
@Tegeril +1 Terima kasih atas jawabannya. Saya pun mulai mendengar suara jangkrik yang satu ini. :) Saya terkejut bahwa aplikasi yang mulai ditangguhkan perlu memanggil ulang startMonitoringSignificantLocationChanges. Apakah Anda memiliki tautan ke dokumen di mana ini dijelaskan? Pemahaman saya adalah bahwa dimuat dari status ditangguhkan akan membuat instance semua objek Anda seperti saat aplikasi ditangguhkan. Jadi saya berharap permintaan perubahan signifikan akan diberlakukan.
RedBlueThing
Anda mungkin berbicara tentang ini? "Setelah peluncuran ulang, Anda masih harus mengonfigurasi objek pengelola lokasi dan memanggil metode ini untuk terus menerima peristiwa lokasi" Tapi menurut saya ini mengacu pada kasus di mana aplikasi Anda diluncurkan dari keadaan dihentikan (oleh peristiwa lokasi). Ini pada dasarnya adalah akar dari pertanyaan saya, 'apa yang terjadi dengan kasus yang ditangguhkan?'.
RedBlueThing
Morgan Grainger di forum Dev menyarankan ini: "Anda perlu membuat CLLocationManager, menetapkan delegasi, dan memanggil startMonitoringSignificantLocationChanges saat aplikasi Anda diluncurkan, atau Lokasi Inti tidak akan memiliki tempat untuk mengirimkan pembaruan." dalam konteks memulai ulang aplikasi terlepas dari dari status dihentikan atau ditangguhkan. Dari "aplikasi diluncurkan kembali setelah startMonitoringSignificantLocationChanges dan sekarang apa?"
Aaron
Saya setuju bahwa ini masih bisa kabur bahkan dalam konteks posting forum itu (poster membahas bangun dari latar belakang, tetapi Morgan menggunakan restart aplikasi yang lebih umum). Saya masih berpikir Anda perlu memanggil untuk memantau lagi ketika aplikasi Anda diluncurkan kembali jika Anda ingin bekerja dengan fungsi perubahan signifikan. Jika Anda ingin meluncurkan tugas latar belakang dan memperbarui dengan layanan lokasi standar dan fungsionalitas GPS, itu adalah opsi alternatif. Saya tidak yakin Anda perlu mendaftar ulang pada setiap peluncuran dengan perubahan yang signifikan agar dapat diluncurkan lagi.
Aaron
1
Saya senang sesuatu yang pasti keluar dari ini, akan membantu saya di masa depan :)
Aaron
1

Jika aplikasi muncul dari status ditangguhkan sebagai akibat dari perubahan lokasi, aplikasi akan diluncurkan dalam status latar belakang.

Semua objek akan ditayangkan dan Anda akan menerima pembaruan lokasi pada delegasi yang ada.

Anshu
sumber