web-dev-qa-db-fra.com

Ranging Beacons ne fonctionne que lorsque l'application est en cours d'exécution?

J'ai du mal à faire fonctionner cela lorsque l'application n'est pas en cours d'exécution. J'ai locationManager:didRangeBeacons:inRegion: implémenté et il est appelé lorsque l'application s'exécute au premier plan ou en arrière-plan, mais il ne semble rien faire lorsque je quitte l'application et verrouille l'écran. L'icône des services de localisation disparaît et je ne sais jamais que je suis entré dans une plage de balises. La notification locale doit-elle toujours fonctionner?

J'ai des mises à jour de localisation et utilise des accessoires Bluetooth LE sélectionnés dans les modes d'arrière-plan (XCode 5), je ne pensais pas en avoir besoin.

Toute aide grandement appréciée.

-(void)watchForEvents { // this is called from application:didFinishLaunchingWithOptions
    id class = NSClassFromString(@"CLBeaconRegion");
    if (!class) {
        return;
    }

    CLBeaconRegion * rflBeacon = [[CLBeaconRegion alloc] initWithProximityUUID:kBeaconUUID identifier:kBeaconString];
    rflBeacon.notifyOnEntry = YES;
    rflBeacon.notifyOnExit = NO;
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    [self.locationManager startRangingBeaconsInRegion:rflBeacon];
    [self.locationManager startMonitoringForRegion:rflBeacon];
}

-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
    if (beacons.count == 0 || eventRanged) { // breakpoint set here for testing
        return;
    }

    eventRanged = YES;
    if (backgroundMode) { // this is set in the EnterBackground/Foreground delegate calls
        UILocalNotification *notification = [[UILocalNotification alloc] init];
        notification.alertBody = [NSString stringWithFormat:@"Welcome to the %@ event.",region.identifier];
        notification.soundName = UILocalNotificationDefaultSoundName;
        [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
    }

    // normal processing here...
}
24
Aaron Bratcher

La surveillance peut lancer une application qui n'est pas en cours d'exécution. La distance ne peut pas.

La clé de la surveillance du lancement de votre application consiste à définir cet indicateur mal documenté sur votre CLBeaconRegion: region.notifyEntryStateOnDisplay = YES; Cela peut lancer votre application sur une transition de région même après avoir redémarré complètement votre téléphone. Mais il y a quelques mises en garde:

  1. Votre application ne se lance en arrière-plan que pendant quelques secondes. (Essayez d'ajouter des instructions NSLog à applicationDidEnterBackground et à d'autres méthodes dans votre AppDelegate pour voir ce qui se passe.)
  2. iOS peut prendre son propre temps pour décider que vous avez entré un CLBeaconRegion. Je l'ai vu prendre jusqu'à quatre minutes.

En ce qui concerne la télémétrie, même si la télémétrie ne peut pas réveiller votre application, vous pouvez faire en sorte que votre application effectue à la fois la surveillance et la télémétrie. Si la surveillance réveille votre application et la met en arrière-plan pendant quelques secondes, les rappels de gamme démarrent immédiatement. Cela vous donne la possibilité d'effectuer des actions de télémétrie rapide pendant que votre application est toujours en cours d'exécution.

EDIT: Une enquête plus approfondie prouve que notifyEntryStateOnDisplay n'a aucun effet sur la surveillance en arrière-plan, donc ce qui précède devrait fonctionner, que vous ayez ou non cet indicateur. Voir cette explication détaillée et discussion des retards que vous pouvez rencontrer

11
davidgyoung

Code pour iOS 9 pour répartir les balises en arrière-plan, en utilisant Mises à jour de l'emplacement :

  1. Ouvrez Paramètres du projet -> Capacités -> Modes d'arrière-plan -> Basculez Location Updates Et Uses Bluetooth LE accessories Sur ON.

  2. Créez un CLLocationManager, demandez Always une autorisation de surveillance (n'oubliez pas d'ajouter le Application does not run in background À NO et NSLocationAlwaysUsageDescription dans l'application de info.plist) Et définissez les propriétés suivantes:

    locationManager!.delegate = self
    locationManager!.pausesLocationUpdatesAutomatically = false
    locationManager!.allowsBackgroundLocationUpdates = true
    
  3. Commencer la télémétrie pour les balises et la région de surveillance:

    locationManager!.startMonitoringForRegion(yourBeaconRegion)
    locationManager!.startRangingBeaconsInRegion(yourBeaconRegion)
    locationManager!.startUpdatingLocation()
    
    // Optionally for notifications
    UIApplication.sharedApplication().registerUserNotificationSettings(
        UIUserNotificationSettings(forTypes: .Alert, categories: nil))
    
  4. Implémentez le CLLocationManagerDelegate et dans votre didEnterRegion envoyez les messages startRangingBeaconsInRegion() et startUpdatingLocation() (envoyez également la notification en option) et définissez le stopRangingBeaconsInRegion() et stopUpdatingLocation() dans didExitRegion

Soyez conscient que cette solution fonctionne mais qu'elle n'est pas recommandée par Apple en raison de la consommation de la batterie et de la confidentialité des clients!

Plus ici: https://community.estimote.com/hc/en-us/articles/203914068-Is-it-possible-to-use-beacon-ranging-in-the-background-

8
Teodor Ciuraru

Voici le processus que vous devez suivre pour varier en arrière-plan:

  1. Pour tout CLBeaconRegion continuez à surveiller, en arrière-plan ou au premier plan et gardez notifyEntryStateOnDisplay = YES
  2. notifyEntryStateOnDisplay appelle locationManager:didDetermineState:forRegion: en arrière-plan, alors implémentez cet appel délégué ...

...comme ça:

- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region{

   if (state == CLRegionStateInside) {


        //Start Ranging
        [manager startRangingBeaconsInRegion:region];
    }

   else{

        //Stop Ranging
        [manager stopRangingBeaconsInRegion:region];
    }

}

J'espère que ça aide.

7
manishnath

Vous effectuez deux opérations distinctes ici - "balise" des balises et surveillance pour une région. Vous pouvez surveiller une région en arrière-plan, mais pas les balises de distance.

Par conséquent, votre implémentation de locationManager:didRangeBeacons:inRegion: ne sera pas appelé en arrière-plan. Au lieu de cela, votre appel à startMonitoringForRegion entraînera l'appel à une/certaines des méthodes suivantes:

– locationManager:didEnterRegion:
– locationManager:didExitRegion:
– locationManager:didDetermineState:forRegion:

Ceux-ci seront appelés en arrière-plan. Vous pouvez alors déclencher une notification locale, comme dans votre code d'origine.

2
James Frost

Votre application devrait actuellement se réveiller si vous souhaitez simplement être averti lorsque vous entrez dans une région de balise. La seule restriction d'arrière-plan que je connaisse concerne l'hébergement d'un iBeacon sur un appareil iOS. Dans ce cas, l'application doit être physiquement ouverte au premier plan. Pour cette situation, vous feriez mieux de simplement implémenter directement CoreBluetooth CBPeripheralManager. De cette façon, vous auriez des capacités publicitaires en arrière-plan.

1
Tommy Devoy