Getting started - iOS

Notification Service with Location and API calls for iOS
  1. Woosmap Geofencing
  2. Overview
  3. Pre-requisites
  4. Installation
  5. Get Keys
  6. Usage
  7. Simulate Notification
  8. GPX files
  9. Additional Documentation
  10. Contributing
  11. License

Github Project:

Woosmap Geofencing

badge badge badge badge badge badge

Location intelligence is one of the next revolutions to improve and “smoothen” user experience on mobile. Mobile operating systems use and provide multiple location services that might be tricky to handle or tune to achieve advanced location based services on mobile. And users are more and more aware of the capabilities of their mobile devices. During the last two years, we analysed, exploited and followed the evolution of those location services, changes that occurred either on tech side or regulation side.

We are convinced that location is an effective way for App makers to propose tailor made and locally contextualised interactions with mobile users. But knowing the location of a user is not enough. Knowing from what a user is close to or what he is visiting is the important part. So we decided to share our findings and tricks for location collection on mobile to help you focus on this real value of location.

This repository is designed to share samples of codes and a SDK on iOS to take the best of location in your mobile apps. We had 3 main focus when developing and sharing this code: take full advantage of location capabilities of mobile devices, doing so in a battery friendly way and be fair with user privacy (see Enabling Location).

Woosmap Geofencing SDK and sample app should help you build Rich Push Notifications (highlighted with a Location context), analyse your mobile users surroundings (search for proximity to your assets, competitors, etc) and much more on iOS to go a step further on Location Intelligence.

Use case where location matters:

As a banking company, you need to enrich the expense list with local information (logo, shop info, etc)? Use this repo to learn how to leverage locally enriched notification to retrieve local information where your users spend their money.

As a retailer company, you need to be informed when a user is close to one of your stores (or competitors’)? Find in this repo how to collect in background location of your users and build your own geofencing analysis.

As a retailer, insurance, banking or travel company, you need to add local context to your user profiles in your CRM? Build your own process of background location collection in your mobile app and analyze geographic behaviors of your mobile users.

As a retailer, insurance, banking or travel company, you want to be informed when a user is visiting specific POIs you decided to monitor (your own stores, your competitors, specific locations)? Use our SDK/code samples to not just collect location but directly obtain “visit triggers” and build advanced scenarios (e.g. a Bank being able to propose specific loans or services when users visits Real Estate agencies, Car Dealers, etc - an Insurance company proposing travel insurance when users visit airports, car insurance when users visit car dealers, etc)


Get user location

Collect in background user’s locations and host them in a local database. Call the Woosmap Search API to retrieve closest stores to each location to locally contextualized users journeys.


Enrich Notification with user location and POIs (Points of Interest)

Get the location of a user on notification reception, to complete the payload with local information from third parties APIs.
In this sample, fetched location is then used to perform a request to the Woosmap Search API to get the closest POIs (Points of Interest) to the location of the user. In addition, a call to Google Static Map is performed to enrich the notification with a map displaying the user’s location and the closest POIs.

Notification Location

Detect Visits (spending time at one place) of your users

Get the location and the time spent when a user is visiting places. Once again use the Woosmap Search API if needed to detect if your users visit your stores, your competitors or POI you may want to monitor.


Detect Zone of Interest (cluster) of your users

Identify areas of interest for your users (location where they spend time, once or recurrently).

Visit Visit

Classification of Zone of Interest (cluster)

The classification of zones of interest (zois) aims to assign them types. For now, two types are supported “home” (zone where a user is supposed to live) and “work” (zone where a user is supposed to work).


Calculations for each zoi are performed to determine the number of different weeks that the user has spent there. A zoi is considered to be recurrent if the number of weeks spent in the zone is greater than or equal to the average of the number of weeks spent in all the zones.

The creation of zois is enable by default. For disable that, in your AppDelegate, you can change the value in the settings of the SDK as follow:

// Set creation of zoi enable
WoosmapGeofencing.shared.creationOfZOIEnable(enable: false)

The classification of zois is enable by default. For disable that, in your AppDelegate, you can change the value in the settings of the SDK as follow:

// Set classification of zoi enable
WoosmapGeofencing.shared.setClassification(enable: false)



Swift Package Manager

To integrate Woosmap Geofencing SDK into your project using Swift Package Manager, you can add the library as a dependency in Xcode (11 and above) – see the docs. The package repository URL is:


Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. To integrate Woosmap Geofencing into your Xcode project using Carthage, specify it in your Cartfile:

github "woosmap/woosmap-geofencing-ios-sdk" ~> 1.0.0


CocoaPods is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate Woosmap Geofencing SDK into your Xcode project using CocoaPods, specify it in your Podfile:

target 'MyApp' do
  pod 'WoosmapGeofencing', :git => ''

Get Keys

WoosmapGeofencing with POI from Search API

Search API

Google map Static

Google map Static


If you plan to perform searches or distance calculations thanks to the Woosmap APIs, please be sure your Woosmap Private Key is set every time your app is launched (in Foreground AND Background). This should be done as early as possible in your didFinishLaunchingWithOptions App Delegate. Depending on your integration, you should call startMonitoringInBackground too. This method must also be called everytime your app is launched. As soon as data is available, set the locationServiceDelegate, searchAPIDataDelegate, visitDelegate and distanceAPIDataDelegate to retrieve location data, POIs from a Woosmap datasource, distance by road to those POIs and visit data if the Visit parameter is enabled.

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    let dataLocation = DataLocation()
    let dataPOI = DataPOI()
    let dataDistance = DataDistance()
    let dataRegion = DataRegion()
    let dataVisit = DataVisit()
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Set Woosmap API Private key
            WoosmapGeofencing.shared.setWoosmapAPIKey(key: WoosmapKey)
            WoosmapGeofencing.shared.setGMPAPIKey(key: GoogleStaticMapKey)
            // Set the Woosmap Search API url
            WoosmapGeofencing.shared.setSearchWoosmapAPI(api: searchWoosmapAPI)
            // Set the Woosmap Distance API url
            WoosmapGeofencing.shared.setDistanceWoosmapAPI(api: distanceWoosmapAPI)
            WoosmapGeofencing.shared.setDistanceAPIMode(mode: drivingModeDistance)
            // Set your filter on position location and search
            WoosmapGeofencing.shared.setCurrentPositionFilter(distance: 10.0, time: 10)
            WoosmapGeofencing.shared.setSearchAPIFilter(distance: 10.0, time: 10)
            // Set classification of zoi enable 
            WoosmapGeofencing.shared.setClassification(enable: true)
            // Set delegate of protocol Location, POI and Distance
            WoosmapGeofencing.shared.getLocationService().locationServiceDelegate = dataLocation
            WoosmapGeofencing.shared.getLocationService().searchAPIDataDelegate = dataPOI
            WoosmapGeofencing.shared.getLocationService().distanceAPIDataDelegate = dataDistance
            WoosmapGeofencing.shared.getLocationService().regionDelegate = dataRegion

            // Enable Visit and set delegate of protocol Visit
            WoosmapGeofencing.shared.setVisitEnable(enable: true)
            WoosmapGeofencing.shared.getLocationService().visitDelegate = dataVisit
             // Check the authorization Status of location Manager
             if (CLLocationManager.authorizationStatus() != .notDetermined) {
        return true

In order to avoid loosing data, you also need to call startMonitoringInBackground in the proper AppDelegate method :

func applicationDidEnterBackground(_ application: UIApplication) {
    if (CLLocationManager.authorizationStatus() != .notDetermined) {

To keep the SDK up to date with user’s data, you need to call didBecomeActive in the proper AppDelegate method too.

func applicationDidBecomeActive(_ application: UIApplication) {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.

The position tracking is enabled by default. To disable location collection, just change the value in the settings of the SDK as follow:

WoosmapGeofencing.shared.setTrackingEnable(enable: false)

Retrieve Location

In your class delegate, retrieve location data :

public class DataLocation:LocationServiceDelegate  {
    public init() {}
    public func tracingLocation(location: Location) { .newLocationSaved, object: self,userInfo: ["Location": location])
    public func tracingLocationDidFailWithError(error: Error) {
    public func readLocations()-> [Location] {
        return Locations.getAll()
    public func eraseLocations() {

Retrieve POI

In your class delegate, retrieve POI data :

public class DataPOI:SearchAPIDelegate  {
    public init() {}
    public func searchAPIResponse(poi: POI) { .newPOISaved, object: self, userInfo: ["POI": poi])
    public func serachAPIError(error: String) {
    public func readPOI()-> [POI] {
        return POIs.getAll()
    func getPOIbyLocationID(locationId: String)-> POI? {
        return POIs.getPOIbyLocationID(locationId: locationId)
    public func erasePOI() {

The Search API request is enabled on all positions by default. To disable Search request, just change the value in the settings of the SDK as follow:

WoosmapGeofencing.shared.setSearchAPIRequestEnable(enable: false)

Retrieve Distance API

In your class delegate, retrieve Distance data :

public class DataDistance:DistanceAPIDelegate  {
    public init() {}
    public func distanceAPIResponseData(distanceAPIData: DistanceAPIData, locationId: String) {
        if (distanceAPIData.status == "OK") {
            if (distanceAPIData.rows?.first?.elements?.first?.status == "OK") {
                let distance = distanceAPIData.rows?.first?.elements?.first?.distance?.value!
                let duration = distanceAPIData.rows?.first?.elements?.first?.duration?.text!
                if(distance != nil && duration != nil) {
                    print(distance ?? 0)
                    print(duration ?? 0)
    public func distanceAPIError(error: String) {

The Distance API request is enabled on all search results by default. If distance by road between the mobile and the retrieved Woosmap POIs is not necessary, settings of the SDK can be modified as follow:

WoosmapGeofencing.shared.setDistanceAPIRequestEnable(enable: false)

Retrieve Visits

For the visits, in the app delegate, you can retrieve the visit like this:

public class DataVisit:VisitServiceDelegate  {
    public init() {}
    public func processVisit(visit: Visit) { .newVisitSaved, object: self,userInfo: ["Visit": visit])
    public func readVisits()-> Array<Visit> {
        return Visits.getAll()
    public func eraseVisits() {

Retrieve Zone of Interest

ZOIs are built from visits, grouped by proximity. We use the Fast Incremental Gaussian Mixture Model of classification Algorithm FIGMM to build and update our ZOI according to visits recurrency along time.

For the ZOIs, in the app delegate, you can retrieve zoi data like this:

public class DataZOI {
    public init() {}
    public func readZOIs()-> [ZOI] {
        return ZOIs.getAll()
    public func eraseZOIs() {

Each ZOI includes the following informations:

public var zoiId: UUID?
public var idVisits: [UUID]?
public var lngMean: Double
public var latMean: Double
public var age: Double
public var accumulator: Double
public var covariance_det: Double
public var prior_probability: Double
public var x00Covariance_matrix_inverse: Double
public var x01Covariance_matrix_inverse: Double
public var x10Covariance_matrix_inverse: Double
public var x11Covariance_matrix_inverse: Double
public var startTime: Date?
public var endTime: Date?
public var duration: Int64
public var wktPolygon: String?

Simulate Notification

GPX files

To test geolocation in an iOS app, you can mock a route to simulate locations.
To create a gpx files, the following tool converts a Google Maps link (also works with Google Maps Directions) to a .gpx file: To emulate, follow instructions here:

Additional Documentation


Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. Thank you for your suggestions!


Woosmap Geofencing is released under the MIT License. See LICENSE file for details.