İzlenecek yol - Xamarin.iOS'ta Arka Plan Konumu
Bu örnekte, geçerli konumumuzla ilgili bilgileri yazdıran bir iOS Konum uygulaması oluşturacağız: enlem, boylam ve diğer parametreler ekrana. Bu uygulama, uygulama Etkin veya Arka Planlı durumdayken konum güncelleştirmelerinin düzgün bir şekilde nasıl gerçekleştirileceğini gösterir.
Bu kılavuzda, bir uygulamayı arka planda gerekli bir uygulama olarak kaydetme, uygulama arka planlandığında kullanıcı arabirimi güncelleştirmelerini askıya alma ve ve WillEnterForeground
AppDelegate
yöntemleriyle WillEnterBackground
çalışma gibi bazı temel arka plan kavramları açıklanmaktadır.
Uygulama kurulumu
İlk olarak yeni bir iOS > Uygulaması > Tek Görünüm Uygulaması (C#) oluşturun. Konum olarak adlandırın ve hem iPad hem de i Telefon'nin seçildiğinden emin olun.
Konum uygulaması, iOS'ta arka plan için gerekli bir uygulama olarak niteler. Projenin Info.plist dosyasını düzenleyerek uygulamayı Konum uygulaması olarak kaydedin.
Çözüm Gezgini altında Info.plist dosyasına çift tıklayarak açın ve listenin en altına kaydırın. Hem Arka Plan Modlarını Etkinleştir hem de Konum Güncelleştirmeler onay kutularına onay işareti yerleştirin.
Mac için Visual Studio aşağıdakine benzer olacaktır:
Visual Studio'da Info.plist dosyasının aşağıdaki anahtar/değer çifti eklenerek el ile güncelleştirilmesi gerekir:
<key>UIBackgroundModes</key> <array> <string>location</string> </array>
Uygulama artık kayıtlı olduğuna göre cihazdan konum verilerini alabilir. iOS'ta,
CLLocationManager
sınıf konum bilgilerine erişmek için kullanılır ve konum güncelleştirmeleri sağlayan olaylar oluşturabilir.Kodda, çeşitli ekranlar ve kodlar için konum güncelleştirmelerine abone olmak için tek bir yer sağlayan adlı
LocationManager
yeni bir sınıf oluşturun.LocationManager
sınıfında adlıLocMgr
öğesininCLLocationManager
bir örneğini oluşturun:public class LocationManager { protected CLLocationManager locMgr; public LocationManager () { this.locMgr = new CLLocationManager(); this.locMgr.PausesLocationUpdatesAutomatically = false; // iOS 8 has additional permissions requirements if (UIDevice.CurrentDevice.CheckSystemVersion (8, 0)) { locMgr.RequestAlwaysAuthorization (); // works in background //locMgr.RequestWhenInUseAuthorization (); // only in foreground } if (UIDevice.CurrentDevice.CheckSystemVersion (9, 0)) { locMgr.AllowsBackgroundLocationUpdates = true; } } public CLLocationManager LocMgr { get { return this.locMgr; } } }
Yukarıdaki kod CLLocationManager sınıfında bir dizi özellik ve izin ayarlar:
PausesLocationUpdatesAutomatically
– Bu, sistemin konum güncelleştirmelerini duraklatma izni olup olmadığına bağlı olarak ayarlanabilen bir Boole değeridir. Bazı cihazlarda varsayılan olaraktrue
değeri olur. Bu, cihazın yaklaşık 15 dakika sonra arka plan konumu güncelleştirmelerini almayı durdurmasına neden olabilir.RequestAlwaysAuthorization
- Uygulama kullanıcısına konumun arka planda erişilmesine izin verme seçeneği vermek için bu yöntemi geçirmelisiniz.RequestWhenInUseAuthorization
ayrıca, kullanıcıya yalnızca uygulama ön planda olduğunda konuma erişim izni verme seçeneği vermek isterseniz de geçirilebilir.AllowsBackgroundLocationUpdates
– Bu, iOS 9'da kullanıma sunulan ve bir uygulamanın askıya alındığında konum güncelleştirmelerini almasına izin verecek şekilde ayarlanabilen bir Boole özelliğidir.
Önemli
iOS 8 (ve üzeri), kullanıcıyı yetkilendirme isteğinin bir parçası olarak göstermek için Info.plist dosyasında bir giriş gerektirir.
Uygulamanın gerektirdiği
NSLocationAlwaysUsageDescription
izin türleri (,NSLocationWhenInUseUsageDescription
, ve/veyaNSLocationAlwaysAndWhenInUseUsageDescription
) için Info.plist anahtarlarını, konuma veri erişimi isteyen uyarıda kullanıcıya görüntülenecek bir dizeyle ekleyin.iOS 9, Info.plist kullanılırken
AllowsBackgroundLocationUpdates
değerinilocation
içeren anahtarıUIBackgroundModes
içermesini gerektirir. Bu kılavuzun 2. adımını tamamladıysanız, bu zaten Info.plist dosyanızda olmalıdır.sınıfının içinde
LocationManager
, aşağıdaki kodla adlıStartLocationUpdates
bir yöntem oluşturun. Bu kod, konumundan konum güncelleştirmelerini almaya nasıl başlayacağınıCLLocationManager
gösterir:if (CLLocationManager.LocationServicesEnabled) { //set the desired accuracy, in meters LocMgr.DesiredAccuracy = 1; LocMgr.LocationsUpdated += (object sender, CLLocationsUpdatedEventArgs e) => { // fire our custom Location Updated event LocationUpdated (this, new LocationUpdatedEventArgs (e.Locations [e.Locations.Length - 1])); }; LocMgr.StartUpdatingLocation(); }
Bu yöntemde gerçekleşen birkaç önemli şey vardır. İlk olarak, uygulamanın cihazdaki konum verilerine erişimi olup olmadığını görmek için bir denetim gerçekleştiririz. Bunu, üzerinde arayarak
LocationServicesEnabled
doğrularızCLLocationManager
. Kullanıcı konum bilgilerine uygulama erişimini reddettiyse bu yöntem false döndürür.Ardından konum yöneticisine ne sıklıkta güncelleştirileceklerini söyleyin.
CLLocationManager
, güncelleştirme sıklığı dahil olmak üzere konum verilerini filtrelemek ve yapılandırmak için birçok seçenek sağlar. Bu örnekte, konum ölçüme göre her değiştiğinde öğesini güncelleştirilecek şekilde ayarlayınDesiredAccuracy
. Konum güncelleştirme sıklığını ve diğer tercihleri yapılandırma hakkında daha fazla bilgi için Apple belgelerindeki CLLocationManager Sınıf Başvurusu'na bakın.Son olarak örnekte çağrısında
StartUpdatingLocation
bulunurCLLocationManager
. Bu, konum yöneticisine geçerli konumla ilgili ilk düzeltmeyi almalarını ve güncelleştirmeleri göndermeye başlamalarını söyler
Şu ana kadar konum yöneticisi oluşturuldu, almak istediğimiz veri türleriyle yapılandırıldı ve ilk konumu belirledi. Şimdi kodun konum verilerini kullanıcı arabirimine işlemesi gerekiyor. Bunu bağımsız değişken olarak alan özel bir CLLocation
olayla yapabiliriz:
// event for the location changing
public event EventHandler<LocationUpdatedEventArgs>LocationUpdated = delegate { };
Bir sonraki adım, konumundan CLLocationManager
konum güncelleştirmelerine abone olmak ve yeni konum verileri kullanılabilir olduğunda özel LocationUpdated
olayı tetikleyerek konumu bağımsız değişken olarak geçirmektir. Bunu yapmak için yeni bir sınıf LocationUpdateEventArgs.cs oluşturun. Bu koda ana uygulama içinden erişilebilir ve olay tetiklendiğinde cihaz konumunu döndürür:
public class LocationUpdatedEventArgs : EventArgs
{
CLLocation location;
public LocationUpdatedEventArgs(CLLocation location)
{
this.location = location;
}
public CLLocation Location
{
get { return location; }
}
}
Kullanıcı Arabirimi
Konum bilgilerini görüntüleyecek ekranı oluşturmak için Xcode Arabirim Oluşturucusu'nu kullanın. Başlamak için Main.storyboard dosyasına çift tıklayın.
Görsel taslakta, konum bilgileri için yer tutucu görevi görmesi için birkaç etiketi ekrana sürükleyin. Bu örnekte enlem, boylam, rakım, kurs ve hız etiketleri vardır.
Daha fazla bilgi için bkz . Xcode ile kullanıcı arabirimleri tasarlama.
Çözüm Bölmesi'nde dosyaya
ViewController.cs
çift tıklayın ve dosyayı düzenleyerek LocationManager'ın yeni bir örneğini oluşturun ve dosyayı arayınStartLocationUpdates
. Kodu aşağıdaki gibi görünecek şekilde değiştirin:#region Computed Properties public static bool UserInterfaceIdiomIsPhone { get { return UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone; } } public static LocationManager Manager { get; set;} #endregion #region Constructors public ViewController (IntPtr handle) : base (handle) { // As soon as the app is done launching, begin generating location updates in the location manager Manager = new LocationManager(); Manager.StartLocationUpdates(); } #endregion
Bu, uygulama başlatmada konum güncelleştirmelerini başlatır, ancak hiçbir veri görüntülenmez.
Konum güncelleştirmeleri alındığına göre, ekranı konum bilgileriyle güncelleştirin. Aşağıdaki yöntem olayımızdan
LocationUpdated
konumu alır ve kullanıcı arabiriminde gösterir:#region Public Methods public void HandleLocationChanged (object sender, LocationUpdatedEventArgs e) { // Handle foreground updates CLLocation location = e.Location; LblAltitude.Text = location.Altitude + " meters"; LblLongitude.Text = location.Coordinate.Longitude.ToString (); LblLatitude.Text = location.Coordinate.Latitude.ToString (); LblCourse.Text = location.Course.ToString (); LblSpeed.Text = location.Speed.ToString (); Console.WriteLine ("foreground updated"); } #endregion
Yine de AppDelegate'imizdeki olaya abone LocationUpdated
olmamız ve kullanıcı arabirimini güncelleştirmek için yeni yöntemi çağırmamız gerekir. Aramadan hemen sonra StartLocationUpdates
içine ViewDidLoad,
aşağıdaki kodu ekleyin:
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// It is better to handle this with notifications, so that the UI updates
// resume when the application re-enters the foreground!
Manager.LocationUpdated += HandleLocationChanged;
}
Şimdi, uygulama çalıştırıldığında şuna benzer olmalıdır:
Etkin ve Arka Plan durumlarını işleme
Uygulama, ön planda ve etkinken konum güncelleştirmeleri çıkışı yapıyor. Uygulama arka plana girdiğinde ne olduğunu göstermek için, uygulama ön plan ile arka plan arasında geçiş yaparken uygulamanın konsola yazması için uygulama durumunu izleyen yöntemleri geçersiz kılın
AppDelegate
:public override void DidEnterBackground (UIApplication application) { Console.WriteLine ("App entering background state."); } public override void WillEnterForeground (UIApplication application) { Console.WriteLine ("App will enter foreground"); }
Konum bilgilerinin arka planda hala kullanılabilir olduğunu doğrulamak için, güncelleştirilmiş konum verilerini sürekli olarak uygulama çıkışına yazdırmak için öğesine aşağıdaki kodu
LocationManager
ekleyin:public class LocationManager { public LocationManager () { ... LocationUpdated += PrintLocation; } ... //This will keep going in the background and the foreground public void PrintLocation (object sender, LocationUpdatedEventArgs e) { CLLocation location = e.Location; Console.WriteLine ("Altitude: " + location.Altitude + " meters"); Console.WriteLine ("Longitude: " + location.Coordinate.Longitude); Console.WriteLine ("Latitude: " + location.Coordinate.Latitude); Console.WriteLine ("Course: " + location.Course); Console.WriteLine ("Speed: " + location.Speed); } }
Kodla ilgili bir sorun daha var: Uygulama arka planlandığında kullanıcı arabirimini güncelleştirmeye çalışmak iOS'un sonlandırmasına neden olur. Uygulama arka plana geçtiğinde kodun konum güncelleştirmelerinin aboneliğini kaldırması ve kullanıcı arabirimini güncelleştirmeyi durdurması gerekir.
iOS, uygulama farklı bir uygulama durumuna geçmek üzere olduğunda bize bildirimler sağlar. Bu durumda Bildirime
ObserveDidEnterBackground
abone olabilirsiniz.Aşağıdaki kod parçacığı, görünümün kullanıcı arabirimi güncelleştirmelerini ne zaman durdurduğunu bildirmek için bir bildirimin nasıl kullanılacağını gösterir. Bu, içinde
ViewDidLoad
yer alır:UIApplication.Notifications.ObserveDidEnterBackground ((sender, args) => { Manager.LocationUpdated -= HandleLocationChanged; });
Uygulama çalışırken çıkış şuna benzer olacaktır:
Uygulama, ön planda çalışırken konum güncelleştirmelerini ekrana yazdırır ve arka planda çalışırken verileri uygulama çıktı penceresine yazdırmaya devam eder.
Yalnızca bir bekleyen sorun kaldı: Uygulama ilk yüklendiğinde ekran kullanıcı arabirimi güncelleştirmelerini başlatır, ancak uygulamanın ön plana yeniden ne zaman girdiğini öğrenmenin bir yolu yoktur. Arka plandaki uygulama ön plana geri getirilirse, kullanıcı arabirimi güncelleştirmeleri devam etmez.
Bunu düzeltmek için, kullanıcı arabirimi güncelleştirmelerini başlatmak için bir çağrıyı başka bir Bildirim içinde iç içe yerleştirerek uygulama Etkin duruma girdiğinde tetiklenir:
UIApplication.Notifications.ObserveDidBecomeActive ((sender, args) => {
Manager.LocationUpdated += HandleLocationChanged;
});
Artık uygulama ilk başlatıldığında kullanıcı arabirimi güncelleştirmeyi başlatır ve uygulama ön plana geri döndüğünde güncelleştirmeyi sürdürür.
Bu kılavuzda, konum verilerini hem ekrana hem de uygulama çıkış penceresine yazdıran iyi davranmış, arka plana duyarlı bir iOS uygulaması oluşturdunuz.