Partager via


Procédure pas à pas - Emplacement d’arrière-plan dans Xamarin.iOS

Dans cet exemple, nous allons créer une application d’emplacement iOS qui imprime des informations sur notre emplacement actuel : latitude, longitude et autres paramètres à l’écran. Cette application montre comment effectuer correctement les mises à jour d’emplacement pendant que l’application est active ou en arrière-plan.

Cette procédure pas à pas décrit certains concepts clés d’arrière-plan, notamment l’inscription d’une application en tant qu’application nécessaire en arrière-plan, la suspension des mises à jour de l’interface utilisateur lorsque l’application est en arrière-plan et l’utilisation des méthodes et WillEnterForegroundAppDelegate des WillEnterBackground méthodes.

Configuration de l’application

  1. Tout d’abord, créez une application iOS > App > Single View (C#). Appelez-le Emplacement et vérifiez que iPad et i Téléphone ont été sélectionnés.

  2. Une application d’emplacement se qualifie comme une application nécessaire en arrière-plan dans iOS. Inscrivez l’application en tant qu’application Emplacement en modifiant le fichier Info.plist pour le projet.

    Sous Explorateur de solutions, double-cliquez sur le fichier Info.plist pour l’ouvrir, puis faites défiler vers le bas de la liste. Placez une case activée à la fois par les modes d’arrière-plan activer et l’emplacement Mises à jour case activée boxes.

    Dans Visual Studio pour Mac, il se présente comme suit :

    Placez un case activée à la fois par les modes d’arrière-plan d’activation et les Mises à jour case activée boxes d’emplacement

    Dans Visual Studio, Info.plist doit être mis à jour manuellement en ajoutant la paire clé/valeur suivante :

    <key>UIBackgroundModes</key>
    <array>
      <string>location</string>
    </array>
    
  3. Maintenant que l’application est inscrite, elle peut obtenir des données d’emplacement à partir de l’appareil. Dans iOS, la CLLocationManager classe est utilisée pour accéder aux informations d’emplacement et peut déclencher des événements qui fournissent des mises à jour d’emplacement.

  4. Dans le code, créez une classe appelée LocationManager qui fournit un emplacement unique pour différents écrans et code pour s’abonner aux mises à jour d’emplacement. Dans la LocationManager classe, créez une instance de l’appelé CLLocationManagerLocMgr:

    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; }
        }
    }
    

    Le code ci-dessus définit un certain nombre de propriétés et d’autorisations sur la classe CLLocationManager :

    • PausesLocationUpdatesAutomatically : il s’agit d’une valeur booléenne qui peut être définie selon que le système est autorisé à suspendre les mises à jour d’emplacement. Sur un appareil, il a truela valeur par défaut , ce qui peut entraîner l’arrêt de l’obtention des mises à jour d’emplacement en arrière-plan après environ 15 minutes.
    • RequestAlwaysAuthorization - Vous devez passer cette méthode pour permettre à l’utilisateur de l’application d’autoriser l’accès à l’emplacement en arrière-plan. RequestWhenInUseAuthorization peut également être transmis si vous souhaitez donner à l’utilisateur la possibilité d’autoriser l’accès à l’emplacement uniquement lorsque l’application est au premier plan.
    • AllowsBackgroundLocationUpdates : il s’agit d’une propriété booléenne, introduite dans iOS 9 qui peut être définie pour permettre à une application de recevoir des mises à jour d’emplacement lorsqu’elle est suspendue.

    Important

    IOS 8 (et ultérieur) nécessite également une entrée dans le fichier Info.plist pour afficher l’utilisateur dans le cadre de la demande d’autorisation.

  5. Ajoutez des clés Info.plist pour les types d’autorisations requis par l’application avec NSLocationAlwaysAndWhenInUseUsageDescriptionNSLocationAlwaysUsageDescriptionNSLocationWhenInUseUsageDescriptionune chaîne qui sera affichée à l’utilisateur dans l’alerte qui demande l’accès aux données d’emplacement.

  6. IOS 9 nécessite que lors de l’utilisation AllowsBackgroundLocationUpdates de Info.plist inclut la clé UIBackgroundModes avec la valeur location. Si vous avez terminé l’étape 2 de cette procédure pas à pas, celle-ci doit déjà se trouver dans votre fichier Info.plist.

  7. À l’intérieur de la LocationManager classe, créez une méthode appelée StartLocationUpdates avec le code suivant. Ce code montre comment commencer à recevoir des mises à jour d’emplacement à partir des CLLocationManageréléments suivants :

    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();
    }
    

    Il y a plusieurs choses importantes qui se produisent dans cette méthode. Tout d’abord, nous effectuons une case activée pour voir si l’application a accès aux données d’emplacement sur l’appareil. Nous vérifions cela en appelant LocationServicesEnabled le CLLocationManager. Cette méthode retourne false si l’utilisateur a refusé l’accès de l’application aux informations d’emplacement.

  8. Ensuite, indiquez au gestionnaire de localisation la fréquence à mettre à jour. CLLocationManager fournit de nombreuses options pour filtrer et configurer des données d’emplacement, notamment la fréquence des mises à jour. Dans cet exemple, définissez la DesiredAccuracy valeur à mettre à jour chaque fois que l’emplacement change d’un compteur. Pour plus d’informations sur la configuration de la fréquence de mise à jour de l’emplacement et d’autres préférences, reportez-vous à la référence de la classe CLLocationManager dans la documentation Apple.

  9. Enfin, appelez StartUpdatingLocation l’instance CLLocationManager . Cela indique au gestionnaire d’emplacements d’obtenir un correctif initial sur l’emplacement actuel et de commencer à envoyer des mises à jour

Jusqu’à présent, le gestionnaire d’emplacements a été créé, configuré avec les types de données que nous voulons recevoir et a déterminé l’emplacement initial. À présent, le code doit restituer les données d’emplacement à l’interface utilisateur. Nous pouvons le faire avec un événement personnalisé qui prend un CLLocation argument :

// event for the location changing
public event EventHandler<LocationUpdatedEventArgs>LocationUpdated = delegate { };

L’étape suivante consiste à s’abonner aux mises à jour d’emplacement à partir du CLLocationManager, et à déclencher l’événement personnalisé LocationUpdated lorsque de nouvelles données d’emplacement sont disponibles, en passant l’emplacement en tant qu’argument. Pour ce faire, créez une classe LocationUpdateEventArgs.cs. Ce code est accessible dans l’application principale et retourne l’emplacement de l’appareil lorsque l’événement est déclenché :

public class LocationUpdatedEventArgs : EventArgs
{
    CLLocation location;

    public LocationUpdatedEventArgs(CLLocation location)
    {
       this.location = location;
    }

    public CLLocation Location
    {
       get { return location; }
    }
}

Interface utilisateur

  1. Utilisez le Générateur d’interface Xcode pour générer l’écran qui affiche les informations d’emplacement. Double-cliquez sur le fichier Main.storyboard pour commencer.

    Dans le storyboard, faites glisser plusieurs étiquettes sur l’écran pour agir en tant qu’espaces réservés pour les informations d’emplacement. Dans cet exemple, il existe des étiquettes pour la latitude, la longitude, l’altitude, le cours et la vitesse.

    Pour plus d’informations, consultez Conception d’interfaces utilisateur avec Xcode.

  2. Dans le Panneau Solution, double-cliquez sur le ViewController.cs fichier et modifiez-le pour créer une instance du LocationManager et appelez-le StartLocationUpdates. Modifiez le code comme suit :

    #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
    

    Cela démarre les mises à jour de l’emplacement au démarrage de l’application, bien qu’aucune donnée ne s’affiche.

  3. Maintenant que les mises à jour de l’emplacement sont reçues, mettez à jour l’écran avec les informations d’emplacement. La méthode suivante obtient l’emplacement de notre LocationUpdated événement et l’affiche dans l’interface utilisateur :

    #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
    

Nous devons toujours nous abonner à l’événement LocationUpdated dans notre AppDelegate et appeler la nouvelle méthode pour mettre à jour l’interface utilisateur. Ajoutez le code ViewDidLoad, suivant juste après l’appel StartLocationUpdates :

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;

}

À présent, lorsque l’application est exécutée, elle doit ressembler à ceci :

Exemple d’exécution d’application

Gestion des états actifs et en arrière-plan

  1. L’application met à jour l’emplacement pendant qu’elle est au premier plan et active. Pour illustrer ce qui se passe lorsque l’application entre en arrière-plan, remplacez les méthodes qui suivent les AppDelegate modifications d’état de l’application afin que l’application écrit dans la console lorsqu’elle passe au premier plan et à l’arrière-plan :

    public override void DidEnterBackground (UIApplication application)
    {
        Console.WriteLine ("App entering background state.");
    }
    
    public override void WillEnterForeground (UIApplication application)
    {
        Console.WriteLine ("App will enter foreground");
    }
    

    Ajoutez le code suivant dans le cadre de l’impression LocationManager continue des données d’emplacement mises à jour dans la sortie de l’application pour vérifier que les informations d’emplacement sont toujours disponibles en arrière-plan :

    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);
        }
    }
    
  2. Il existe un problème restant avec le code : la tentative de mise à jour de l’interface utilisateur lorsque l’application est en arrière-plan entraîne l’arrêt d’iOS. Lorsque l’application passe en arrière-plan, le code doit se désabonner des mises à jour d’emplacement et arrêter la mise à jour de l’interface utilisateur.

    iOS nous fournit des notifications lorsque l’application est sur le point de passer à un autre état d’application. Dans ce cas, nous pouvons nous abonner à la ObserveDidEnterBackground notification.

    L’extrait de code suivant montre comment utiliser une notification pour indiquer à l’affichage quand arrêter les mises à jour de l’interface utilisateur. Cela va aller dans ViewDidLoad:

    UIApplication.Notifications.ObserveDidEnterBackground ((sender, args) => {
        Manager.LocationUpdated -= HandleLocationChanged;
    });
    

    Lorsque l’application est en cours d’exécution, la sortie ressemble à ceci :

    Exemple de sortie d’emplacement dans la console

  3. L’application imprime les mises à jour de l’emplacement à l’écran lors de l’opération au premier plan et continue d’imprimer des données dans la fenêtre de sortie de l’application tout en fonctionnant en arrière-plan.

Un seul problème en suspens reste : l’écran démarre les mises à jour de l’interface utilisateur lorsque l’application est chargée pour la première fois, mais elle n’a aucun moyen de savoir quand l’application a recréé le premier plan. Si l’application en arrière-plan est renvoyée au premier plan, les mises à jour de l’interface utilisateur ne reprendront pas.

Pour résoudre ce problème, imbriquez un appel pour démarrer les mises à jour de l’interface utilisateur à l’intérieur d’une autre notification, qui se déclenche lorsque l’application entre dans l’état Actif :

UIApplication.Notifications.ObserveDidBecomeActive ((sender, args) => {
  Manager.LocationUpdated += HandleLocationChanged;
});

À présent, l’interface utilisateur commence à mettre à jour lorsque l’application est démarrée pour la première fois et reprend la mise à jour à tout moment où l’application revient au premier plan.

Dans cette procédure pas à pas, nous avons créé une application iOS prenant en compte les arrière-plans qui imprime les données d’emplacement à la fois à l’écran et à la fenêtre de sortie de l’application.