Ricevere messaggi beacon

La tua app può abbonarsi ai messaggi di beacon BLE (Bluetooth Low Energy) usando lo stesso meccanismo utilizzato per abbonarsi ai messaggi pubblicati da altri dispositivi nelle vicinanze.

Per impostazione predefinita, gli abbonamenti a beacon funzionano soltanto quando la tua app è in primo piano. Quando l'app passa in background, gli abbonamenti interrompono automaticamente la ricerca dei beacon. Per informazioni dettagliate sull'attivazione della scansione in background, consulta Scansione in background.

Per abbonarti ai beacon, imposta il parametro deviceTypesToDiscover su kGNSDeviceBLEBeacon nei parametri dell'abbonamento. Lo snippet riportato di seguito mostra come eseguire questa operazione:

Objective-C

id<GNSSubscription> beaconSubscription = [messageManager
    subscriptionWithMessageFoundHandler:myMessageFoundHandler
                     messageLostHandler:myMessageLostHandler
                            paramsBlock:^(GNSSubscriptionParams *params) {
                              params.deviceTypesToDiscover = kGNSDeviceBLEBeacon;
                            }];

Swift

let beaconSubscription = messageManager.subscriptionWithMessageFoundHandler(
    myMessageFoundHandler, messageLostHandler: myMessageLostHandler,
    paramsBlock: { (params: GNSSubscriptionParams!) in
      params.deviceTypesToDiscover = .BLEBeacon
    })

La sottoscrizione precedente rileva solo i beacon di proprietà del tuo progetto e riceve tutti i messaggi da questi beacon. Se vuoi ricevere messaggi da beacon registrati con uno spazio dei nomi diverso, puoi passare uno spazio dei nomi nei parametri dell'abbonamento. Analogamente, se vuoi un tipo di messaggio specifico, puoi anche passare un tipo di messaggio per l'applicazione di filtri. Lo snippet seguente mostra come procedere:

Objective-C

id<GNSSubscription> beaconSubscription = [messageManager
    subscriptionWithMessageFoundHandler:myMessageFoundHandler
                     messageLostHandler:myMessageLostHandler
                            paramsBlock:^(GNSSubscriptionParams *params) {
                              params.deviceTypesToDiscover = kGNSDeviceBLEBeacon;
                              params.messageNamespace = @"com.mycompany.mybeaconservice";
                              params.type = @"mybeacontype";
                            }];

Swift

let beaconSubscription = messageManager.subscriptionWithMessageFoundHandler(
    myMessageFoundHandler, messageLostHandler: myMessageLostHandler,
    paramsBlock: { (params: GNSSubscriptionParams!) in
      params.deviceTypesToDiscover = .BLEBeacon
      params.messageNamespace = "com.mycompany.mybeaconservice"
      params.type = "mybeacontype"
    })

Per impostazione predefinita, l'abbonamento a un beacon esegue la scansione di entrambi i tipi di beacon, Eddystone e iBeacon. Quando la scansione di iBeacon è abilitata, agli utenti verrà chiesto di autorizzare l'app a utilizzare i loro dati sulla posizione. L'elemento Info.plist dell'app deve includere la chiave NSLocationWhenInUseUsageDescription con una breve spiegazione del motivo per cui viene usata la posizione. Per ulteriori dettagli, consulta la documentazione di Apple.

Se vuoi eseguire la scansione solo per i beacon Eddystone, puoi disabilitare la scansione di iBeacon in GNSBeaconStrategy e iOS non chiederà all'utente l'autorizzazione per utilizzare la posizione. Lo snippet seguente mostra come disattivare la scansione di iBeacon per l'abbonamento originale sopra indicato:

Objective-C

id<GNSSubscription> beaconSubscription = [messageManager
    subscriptionWithMessageFoundHandler:myMessageFoundHandler
                     messageLostHandler:myMessageLostHandler
                            paramsBlock:^(GNSSubscriptionParams *params) {
                              params.deviceTypesToDiscover = kGNSDeviceBLEBeacon;
                              params.beaconStrategy =
                                  [GNSBeaconStrategy strategyWithParamsBlock:^(GNSBeaconStrategyParams *params) {
                                    params.includeIBeacons = NO;
                                  };
                            }];

Swift

let beaconSubscription = messageManager.subscriptionWithMessageFoundHandler(
    myMessageFoundHandler, messageLostHandler: myMessageLostHandler,
    paramsBlock: { (params: GNSSubscriptionParams!) in
      params.deviceTypesToDiscover = .BLEBeacon
      params.beaconStrategy =
          GNSBeaconStrategy(paramsBlock: { (params: GNSBeaconStrategyParams!) in
            params.includeIBeacons = false
          })
    })

Per impostazione predefinita, è abilitata la scansione a bassa potenza, il che a volte può generare grandi latenza durante la ricerca dei beacon Eddystone. Quando la modalità a basso consumo è disabilitata, la scansione iBeacon viene utilizzata per trovare i beacon Eddystone, che possono ridurre queste latenze. Tuttavia, questo comporta un maggiore utilizzo della batteria e iOS chiederà all'utente l'autorizzazione a usare la posizione.

Il seguente snippet mostra come disattivare la modalità a basso consumo durante la scansione dei beacon di Eddystone.

Objective-C

id<GNSSubscription> beaconSubscription = [messageManager
    subscriptionWithMessageFoundHandler:myMessageFoundHandler
                     messageLostHandler:myMessageLostHandler
                            paramsBlock:^(GNSSubscriptionParams *params) {
                              params.deviceTypesToDiscover = kGNSDeviceBLEBeacon;
                              params.beaconStrategy =
                                  [GNSBeaconStrategy strategyWithParamsBlock:^(GNSBeaconStrategyParams *params) {
                                    params.includeIBeacons = NO;
                                    params.lowPowerPreferred = NO;
                                  };
                            }];

Swift

let beaconSubscription = messageManager.subscriptionWithMessageFoundHandler(
    myMessageFoundHandler, messageLostHandler: myMessageLostHandler,
    paramsBlock: { (params: GNSSubscriptionParams!) in
      params.deviceTypesToDiscover = .BLEBeacon
      params.beaconStrategy =
          GNSBeaconStrategy(paramsBlock: { (params: GNSBeaconStrategyParams!) in
            params.includeIBeacons = false
            params.lowPowerPreferred = false
          })
    })

Durante la ricerca di iBeacon, la finestra di dialogo dell'autorizzazione di accesso alla posizione di iOS è preceduta dalla finestra di dialogo dell'autorizzazione Nelle vicinanze. Se vuoi eseguire l'override di questa finestra di dialogo (ad esempio, per fornire una finestra di dialogo "preflight" che spiega perché è necessaria l'autorizzazione di accesso alla posizione), imposta permissionRequestHandler su un blocco personalizzato nei parametri dell'abbonamento. Lo snippet seguente mostra come eseguire questa operazione:

Objective-C

id<GNSSubscription> beaconSubscription = [messageManager
    subscriptionWithMessageFoundHandler:myMessageFoundHandler
                     messageLostHandler:myMessageLostHandler
                            paramsBlock:^(GNSSubscriptionParams *params) {
                              params.deviceTypesToDiscover = kGNSDeviceBLEBeacon;
                              params.permissionRequestHandler = ^(GNSPermissionHandler permissionHandler) {
                                // Show your custom dialog here, and don't forget to call permissionHandler after it is dismissed
                                permissionHandler(userGavePermission);
                              };
                            }];

Swift

let beaconSubscription = messageManager.subscriptionWithMessageFoundHandler(
    myMessageFoundHandler, messageLostHandler: myMessageLostHandler,
    paramsBlock: { (params: GNSSubscriptionParams!) in
      params.deviceTypesToDiscover = .BLEBeacon
      params.permissionRequestHandler = { (permissionHandler: GNSPermissionHandler!) in
        // Show your custom dialog here, and don't forget to call permissionHandler after it is dismissed
        permissionHandler(userGavePermission);
      }
    })

Scansione in background

Poiché la scansione di beacon utilizza la tecnologia BLE, può funzionare in background. Ecco alcuni aspetti da tenere presenti quando decidi di utilizzare la modalità in background:

  • È previsto un costo aggiuntivo per la batteria BLE in background. Il costo è basso, ma è consigliabile misurarlo prima di decidere di utilizzare la modalità in background.
  • Se la scansione di iBeacon è attivata o la modalità a basso consumo è disattivata, iOS chiederà all'utente l'autorizzazione a utilizzare la posizione in background.

Per attivare la scansione di beacon in background, svolgi i seguenti passaggi aggiuntivi:

  • Attiva la modalità in background per la tua sottoscrizione passando un oggetto GNSBeaconStrategy configurato correttamente. Lo snippet seguente mostra come fare:

    Objective-C

    id<GNSSubscription> beaconSubscription = [messageManager
        subscriptionWithMessageFoundHandler:myMessageFoundHandler
                         messageLostHandler:myMessageLostHandler
                                paramsBlock:^(GNSSubscriptionParams *params) {
                                  params.deviceTypesToDiscover = kGNSDeviceBLEBeacon;
                                  params.beaconStrategy = [GNSBeaconStrategy
                                      strategyWithParamsBlock:^(GNSBeaconStrategyParams *params) {
                                        params.allowInBackground = YES;
                                      }];
                                }];
    

    Swift

    let beaconSubscription = messageManager.subscriptionWithMessageFoundHandler(
        myMessageFoundHandler, messageLostHandler: myMessageLostHandler,
        paramsBlock: { (params: GNSSubscriptionParams!) in
          params.deviceTypesToDiscover = .BLEBeacon
          params.beaconStrategy =
              GNSBeaconStrategy(paramsBlock: { (params: GNSBeaconStrategyParams!) in
                params.allowInBackground = true
              })
        })
    

  • Aggiungi le voci obbligatorie al Info.plist dell'app:

    • UIBackgroundModes voci:

      • bluetooth-central per la scansione BLE in background.
      • location per la scansione con iBeacon in background utilizzando la modalità ad alta potenza. Questo campo può essere omesso se esegui la scansione a bassa potenza solo per i beacon Eddystone.
    • Stringa NSLocationAlwaysUsageDescription che descrive perché monitorerai la posizione dell'utente in background. Ad esempio: "Per rilevare la presenza di beacon in background è necessaria la tua posizione". Per ulteriori dettagli, consulta la documentazione di Apple. Questo campo può essere omesso se esegui la scansione a bassa potenza solo per beacon Eddystone.

  • L'utente può attivare o disattivare la scansione in background nella tua app? In tal caso, devi salvare il valore della modalità in background su NSUserDefaults perché iOS può terminare la tua app in qualsiasi momento mentre è in background. La tua app deve:

    • Salva il valore della modalità background su NSUserDefaults ogni volta che l'utente lo modifica.
    • All'avvio, leggilo da NSUserDefaults e ripristina l'abbonamento al beacon se è attivata la modalità in background.

Notifiche in background

Se vuoi che la tua app invii una notifica all'utente quando vengono rilevati beacon in background, puoi utilizzare le notifiche locali. Per maggiori dettagli, consulta la sezione Notifiche in background.