Geofences en iOS (Swift)

1
5472

Tutorial en el que se explica cómo crear geofences en iOS.

Índice de contenidos

  1. Introducción
  2. Entorno
  3. Pidiendo permiso para utilizar la ubicación
  4. Crear la geofence
  5. Probando su funcionamiento
  6. Conclusiones

1. Introducción

Cuando hablamos de geofences nos referimos a un perímetro virtual para un área geográfica del mundo real el cual nos interesa monitorizar.

En iOS, el framework de CoreLocation nos permite definir regiones mediante una coordenada geográfica y un radio en metros, y comprobar mediante la ubicación del usuario, es decir, la coordenada geográfica en la que este se encuentra en un determinado momento, si dicha coordenada está dentro o no de esa determinada región.

Lo mejor de todo esto es que este trabajo de obtener periódicamente la ubicación y procesar si está dentro o no del área se realiza a nivel del sistema, disparando un evento que captura la App cuando se entra o sale de la región.

Como ejemplos del uso de geofences, podemos poner recordatorios asignados a una ubicación, o en cierto juego que estuvo de moda el verano pasado en el que al encontrarse en una determinada ubicación aparecían determinados tipos de pokémon salvajes…

Podéis clonar el proyecto desde aquí: https://github.com/DaniOtero/iOS-geofences.

2. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: portátil MacBook Pro 15’ (2.5 GHz Intel Core i7, 16 GB 1600 MHz DDR3)
  • Sistema operativo: Mac OS X Sierra 10.12.5
  • Xcode 8.3.3
  • iOS 10.3.1

3. Pidiendo permiso para utilizar la ubicación

Apple se toma muy en serio la privacidad de sus usuarios, de hecho la promociona como una de las características estrella de sus productos frente a la competencia.

Para pedir permiso para utilizar la App, lo podemos hacer por ejemplo en nuestro AppDelegate

import UIKit
import CoreLocation

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

   var window: UIWindow?
   // Important: location manager is declared as a class attribute in order to keep a strong reference. Otherwise, if it was deallocated all delegate method wouldn't be triggered
   var locationManager : CLLocationManager?

   func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
       // Override point for customization after application launch.
       locationManager = CLLocationManager()
       locationManager?.requestAlwaysAuthorization()
       return true
   }
}

Esto mostrará un diálogo modal pidiendo permiso al usuario para utilizar la ubicación. Solo se le preguntará una única vez, tanto si el usuario acepta como si no. En caso de que se arrepiente de su decisión, deberá cambiar el permiso desde el menú de preferencias del sistema.

Como cosa a tener en cuenta, para poder utilizar geofences en nuestra aplicación necesitamos solicitar el permiso para utilizar la ubicación siempre, en caso contrario los eventos de entrada/salida de una geofence no se dispararán.

Diálogo permisos

Para que esto funcione y poder utilizar la ubicación del usuario en nuestras apps, además debemos declarar con qué intención se va a utilizar la ubicación del usuario.

Para ello utilizaremos la key "NSLocationAlwaysUsageDescription" y como valor le daremos una explicación que será la que se muestra en el diálogo que hemos hablado antes.

Info.plist

4. Crear la geofence

Crear la geofence en iOS es muy sencillo. Para la prueba de concepto voy a crear desde el view controller principal del proyecto una vista muy sencilla con un mapa que muestra la ubicación actual, un label para indicar si está o no activo la geofence y un botón que desactive el botón.

Para ello lo primero que voy a hacer que el view controller principal sea el delegate del location manager

class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
   @IBOutlet weak var geofencesLabel: UILabel!
   @IBOutlet weak var mapView: MKMapView!

   var locationManager : CLLocationManager?

   override func viewDidLoad() {
       super.viewDidLoad()
       // Do any additional setup after loading the view, typically from a nib.
       if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
           locationManager = appDelegate.locationManager
           locationManager?.delegate = self
       }
   }
}

El centro de la geofence serán las oficinas de Autentia, y el radio 100 metros.

func regionToMonitor() -> CLCircularRegion {
   let autentia = CLCircularRegion(center: CLLocationCoordinate2D(latitude: 40.453163, longitude: -3.509220), radius: 100, identifier: "autentia")
   autentia.notifyOnExit = true
   autentia.notifyOnEntry = true
   return autentia
}

Una vez creada la región, tan solo tengo que indicarle al locator manager que empiece a monitorizar esa región. Para ello haré que el action asociado al boton inicie o detenga la monitorización de la región.

@IBAction func toggleGeofences(_ sender: Any) {
   if let locationManager = self.locationManager {
       let region = self.regionToMonitor()
       if(locationManager.monitoredRegions.count > 0) {
           locationManager.stopMonitoring(for: region)
       } else {
           locationManager.startMonitoring(for: region)
       }
       setupView()
   } else {
       notify(msg: "Unable to set geofence")
   }
}

Y por último creo los métodos delegados que se dispararán cuando se produzca un evento de entrada o salida en una región.

// MARK: - CLLocationManagerDelegagte methods
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
   notify(msg: "Hello from Autentia")
}

func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
   notify(msg: "Bye from Autentia")
}

Y ya está, tan simple como eso. Cuando el usuario esté dentro del radio o salga de él se le mostrará una notificación. Podemos crear tantas geofences como queramos, ya que como hemos visto al crear la región se le debe asignar un identificador para distinguirlas (si es que necesitamos diferenciarlas claro).

Una cosa que hay que tener en cuenta es que las geofences perduran aunque se cierre la app (da igual que seamos nosotros los que la cerremos o el sistema decida matarla en cualquier momento al estar en background), y cuando entre o salga en una geofence se disparará el evento y la app se ejecutará de nuevo.

5. Probando su funcionamiento

Para probar que todo funciona como esperamos, en el simulador de iOS en el menú "Debug->Location->Custom location…" podemos jugar con ubicaciones simuladas

Ubicación simulada

Con la longitud de la imagen estaríamos bastante cerca de la geofence pero fuera del radio, si la establecemos a -3.509220, estaríamos justo en el centro de la geofence y habríamos provocado un evento de entrada.

Entrada

Salida

6. Conclusiones

Establecer una geofence en iOS es increíblemente sencillo y rápido. La única pega es que se debe solicitar permiso para utilizar la ubicación en todo momento.

Esto puede hacer que algún usuario más preocupado por su privacidad sea reticente a dar su consentimiento a la app, que acabe borrándola o simplemente se queje amargamente en la App Store si no se le deja claro para que se va a utilizar su ubicación (y con razón…).

Por esta razón hay que plantearse si establecer geofences puede darle una funcionalidad útil para el usuario o por el contrario solo va a ser un consumo de batería inútil.

1 COMENTARIO

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad