Sonlandırıldığında / askıya alındığında önemli değişiklik konumu API'sinin davranışı?


108

Bu, CLLocationManager belgelerinden startMonitoringSignificantLocationChanges ile uygulama davranışını açıklayan bölümdür :

Bu hizmeti başlatırsanız ve uygulamanız sonradan sonlandırılırsa, sistem yeni bir olay gelirse uygulamayı otomatik olarak arka planda yeniden başlatır. Böyle bir durumda, uygulamaya geçirilen seçenekler sözlüğü: didFinishLaunchingWithOptions: uygulama temsilcinizin yöntemi, uygulamanızın bir konum olayı nedeniyle başlatıldığını belirtmek için UIApplicationLaunchOptionsLocationKey anahtarını içerir. Yeniden başlatmanın ardından, yine de bir konum yöneticisi nesnesi yapılandırmanız ve konum olaylarını almaya devam etmek için bu yöntemi çağırmanız gerekir. Konum hizmetlerini yeniden başlattığınızda, mevcut olay temsilcinize hemen teslim edilir. Ek olarak, konum yöneticisi nesnenizin konum özelliği, siz konum hizmetlerini başlatmadan önce en son konum nesnesiyle doldurulur.

Benim anlayış, uygulama sonlanır (aramıyorsun eğer ben varsayarsak olmasıdır Yani stopMonitoringSignificantLocationChanges gelen applicationWillTerminate ) Bir ile uyandı alacak UIApplicationLaunchOptionsLocationKey için parametre didFinishLaunchingWithOptions: Uygulama . Bu noktada size oluşturmak CLLocationManager , çağrı startMonitoringSignificantLocationChanges ve için arka planda konum işlem yapmak sınırlı bir süre . Bu yüzden bu konuda iyiyim.

Önceki paragraf yalnızca uygulama sonlandırıldığında ne olacağı hakkında konuşur, uygulama askıya alındığında ne yaptığınız hakkında bir fikir vermez. DidFinishLaunchingWithOptions dokümantasyonu şunu söylüyor:

Uygulama arka planda konum güncellemelerini izler, temizlendi ve şimdi yeniden başlatıldı. Bu durumda sözlük, uygulamanın yeni bir konum olayı nedeniyle yeniden başlatıldığını belirten bir anahtar içerir.

Bu aramayı yalnızca sonlandırıldıktan sonra uygulamanız başlatıldığında (bir konum değişikliği nedeniyle) alacağınızı öneriyoruz.

Ancak üzerinde paragraf Anlamlı Değişim Servisi de yer Bilinci Programlama Kılavuzu söylemek için aşağıdaki etti:

Bu hizmeti çalışır durumda bırakırsanız ve uygulamanız daha sonra askıya alınır veya sonlandırılırsa, hizmet yeni konum verileri geldiğinde uygulamanızı otomatik olarak uyandırır. Uyanma zamanında uygulamanız arka plana alınır ve konum verilerini işlemesi için kısa bir süre verilir. Uygulamanız arka planda olduğu için, asgari düzeyde çalışmalı ve tahsis edilen süre sona ermeden önce geri dönmesini engelleyebilecek herhangi bir görevden (ağı sorgulama gibi) kaçınmalıdır. Aksi takdirde, başvurunuz sonlandırılabilir.

Bu, uygulamanız askıya alınmışsa, ancak nasıl uyandığınızdan bahsetmiyorsa konum verileriyle uyandığınızı gösterir:

Bunu yazma sürecinde, sanırım kendi sorumu yanıtlamış olabilirim, ancak bu konudaki anlayışımın daha bilgili biri tarafından onaylanması harika olur.

Yanıtlar:


80

Bu soruyu sorduğumdan beri, oldukça fazla test yaptım (çoğunlukla ev ile iş arasında trende) ve sorunun sonunda şüphelendiğim gibi askıya alınan uygulamaların davranışının olduğunu doğruladım.

Yani, askıya alınan uygulamanız uyandırılır, uygulama temsilcinize herhangi bir geri arama almazsınız, bunun yerine konum güncellemelerinizi mevcut CLLocationManagerDelegate aracılığıyla alırsınız . ApplicationState'i kontrol ederek arka planda çalıştığınızı tespit edebilir ve konum işleme yapmak için askıya alınmış durumdan uyandırıldığınız durum için sınırlı iş yapabilirsiniz.

[UIApplication sharedApplication].applicationState == UIApplicationStateBackground

Bu sonuca, indirip deneyebileceğiniz bir konum testi kablo demeti ile geldim . UI aracılığıyla önemli değişiklik ve GPS değiştirme API'lerini açmanıza ve geri aldığınız tüm yanıtları kaydetmenize olanak tanıyan oldukça basit bir uygulamadır.

NB Önceki cevaptaki altıncı nokta doğru değil. Dondurularak kurutulmuş askıya alınmış uygulamalar , askıya alınmış bir durumdan uyandırıldıklarında CLLocationManagerDelegate geri aramalarını alırlar .


1
İnsanların kafasını karıştırmamak için cevabımda 6. sırada yer aldı.
Aaron

İronik olarak, önemli bir değişiklik için geliştirirken aynı kafa karışıklığını da hissettim. Uygulama kapatılırsa ne olacağı konusunda hala bazı şüphelerim var. UIApplicationDelegate geri aramaları olmayacak mı? uygulamayı başlatmanın doğru yolu budur. konum yöneticisi henüz çalıştırılmadıysa, bildirimleri arka planda nasıl alabilir? (biraz daha Ar-Ge zamanı)
darshansonde

Örnek uygulama için çok teşekkürler, benim için çok faydalı oldu. Bir sorum var: Ya arka planda standart konum hizmetini kullanıyorsam, önemli olanı değil, bu durumda uygulama sonlandırıldıktan sonra yeniden başlatılır mı? Bu soruyu burada ayrıntılı olarak sordum, beni aydınlatırsanız sevinirim:] stackoverflow.com/questions/12239967/…
aslisabanci


Uygulamanızın feshedilmesinin ne kadar sürdüğünü biliyor musunuz? Ve bunun yerine appDelegate geri araması alınsın mı? (30 dakika mı? 2 saat mi? 5 saat mi?) Bunu sormamın nedeni izlenecek bir bölge kurmuş olmam. Birçok kez uygulamamın başlatıldığını görmeyi denedim, ancak yalnızca bir kez uygulamayı yeniden başlatmam gerekti. Diğer zamanlar didExitRegiongeri arama oldu, ancak startLocationUpdatesuygulama başlatılmadığı için oradan yapamadım ...
Tatlım

25

Anladığım kadarıyla aşağıdaki gibi (bu API'ye dayanan bir uygulama yazma sürecindeyim, ancak bu bileşeni test etmeye başlamak için yeterince tamamlamadım):

  1. Uygulamanız ilk kez çalıştırıldığında startMonitoringSignificantLocationChanges'a kaydolur ve bir geri arama işlevi sağlarsınız . Uygulamanız çalışırken, önemli bir değişiklik aldığında bu geri aramayı arayacaktır.
  2. Uygulamanız arka plana yerleştirilirse, UIApplication applicationWillResignActive öğesini ve ardından applicationDidEnterBackground öğesini alır .
  3. Başvurunuz arka planda askıda iken öldürülürse, size haber verilmeyecektir; ancak uygulamanız çalışırken öldürülürse (bildiğim kadarıyla ön plan veya arka plan), applicationWillTerminate ile bir an elde edeceksiniz . Bu işlevden fazladan arka plan süresi talep edemezsiniz.
  4. Arka planda öldürülmesine rağmen, işletim sistemi uygulamanızı yeniden başlatacaktır. Uygulamanız bir değişiklik için işletim sistemi tarafından basitçe başlatılırsa, didFinishLaunchingWithOptions uygulamasına bir çağrı alırsınız :

    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey])

    arka planda bir konum değişikliğinden dönüp dönmediğinizi belirlemenize yardımcı olur.

  5. Yerine, şu anda arka planda çalışan edildi ve uygulama kullanıcı tarafından elle yeniden hizmete edilirse, bir alacak applicationWillEnterForeground izledi applicationDidBecomeActive .
  6. Nasıl gerçekleştiğine bakılmaksızın, uygulamanız yeniden başlatıldığında (arka planda çalışan bir görevin sonucu olarak hala arka planda çalışmıyorsa ve söz konusu görev değişiklikleri izlemeye başlamadıysa), geri çağırma hayır olmadığından, ona açık bir şekilde yeniden başlamasını söylemeniz gerekirMonitoringSignificantLocationChanges "dondurarak kurutma" sonrasında daha uzun süre takılır. Ve evet, askıya alınmış durumdan döndüğünüzde bir tür konum işleyicisini yeniden ekledikten sonra didUpdateToLocation'da kodu uygulamanız yeterlidir.

Şu anda kod geliştirmeme devam ediyorum. Daha önce de bahsettiğim gibi, bunu bir cihazda test etmeye tam olarak hazır değilim, bu yüzden her şeyi doğru yorumlayıp yorumlamadığımı anlayamıyorum, bu yüzden yorumcular, lütfen beni düzeltmekten çekinmeyin (yine de konu).

Oh, ve biraz şanssızlık eseri benim yapmamı istediğimi yapan bir uygulama yayınlarsan, ağlayabilirim :)

İyi şanslar!


1
@Tegeril +1 Cevabınız için teşekkürler. Bu sefer cırcır böceklerini duymaya başlamıştım. :) Askıya alınmadan başlayan uygulamaların startMonitoringSignificantLocationChanges'ı yeniden çağırması gerektiğine şaşırdım. Bunun açıklandığı doco ile bağlantınız var mı? Anladığım kadarıyla, askıya alınmış bir durumdan yüklenmenin, tüm nesnelerinizi uygulama askıya alındığında olduğu gibi başlatacağıdır. Bu nedenle, önemli değişiklik talebinin geçerli olmasını bekliyorum.
RedBlueThing

Bunun hakkında konuşuyor olabilirsiniz? "Yeniden başlatmanın ardından, yine de bir konum yöneticisi nesnesini yapılandırmanız ve konum olaylarını almaya devam etmek için bu yöntemi çağırmanız gerekir" Ancak bunun, uygulamanızın sonlandırılmış bir durumdan (bir konum olayıyla) başlatıldığı duruma atıfta bulunduğunu düşünüyorum. Bu temelde sorumun köküdür, 'askıya alınan dava için ne olur?'
RedBlueThing

Morgan Grainger, Dev forumlarında şunu önerdi: "Bir CLLocationManager oluşturmanız, bir temsilci ayarlamanız ve uygulamanız başlatıldığında startMonitoringSignificantLocationChanges'ı aramanız gerekir, aksi takdirde Core Location güncellemeleri teslim edecek hiçbir yere sahip olmayacak." sonlandırılmış veya askıya alınmış durumdan bağımsız olarak bir uygulamayı yeniden başlatma bağlamında. "Uygulama, startMonitoringSignificantLocationChanges sonra yeniden başlatıldı ve şimdi ne olacak?"
Aaron

Forum gönderisi bağlamında bile bunun belirsiz olabileceğini kabul ediyorum (afiş arka plandan uyanmayı tartışıyordu, ancak Morgan bir uygulamanın daha genel bir şekilde yeniden başlatılmasını kullandı). Yine de, önemli değişiklikler işleviyle çalışmak istiyorsanız, uygulamanız yeniden başlatıldığında izlemeyi tekrar aramanız gerektiğini düşünüyorum. Bunun yerine bir arka plan görevi başlatmak ve standart konum hizmeti ve GPS işlevselliği ile güncellemek istiyorsanız, bu alternatif bir seçenektir. Yine de yeniden başlatılmak için her lansmanda önemli değişikliklerle yeniden kaydolmanız gerektiğine inanmıyorum.
Aaron

1
Bundan kesin bir şey çıktığına sevindim, gelecekte bana yardımcı olabilir :)
Aaron

1

Uygulama, konum değişikliğinin bir sonucu olarak askıya alınmış durumdan çıkarılırsa, uygulama arka planda başlatılır.

Tüm nesneler yayınlanacak ve mevcut delegede konum güncellemesi alacaksınız.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.