Skip to content

iOS: Visits and GeoFencing For MobileLocation

Starting with Xojo 2023r3 there are two new features in the iOS MobileLocation control: Visits and GeoFencing. Visits allows the operating system to notify an app when a device stays near a given place for some time. GeoFencing can notify an app when the user enters and/or leaves a previously registered region.

As for any other features involving the MobileLocation control on iOS, the same rules apply when enabling the required capabilities (from the Attributes section in the Inspector Panel with the iOS item selected in the Navigator), and also when requesting the user’s permission to use location services. In fact, it is advisable to enable the Background Modes > Location capability so your app still gets notified both when using Visits or GeoFencing and the app itself is running in the background.

Because we want to receive these events even when the app is not in use, you will want to use the MobileLocationUsageTypes.Always value for the request:

location1.RequestUsageAuthorization(MobileLocation.UsageTypes.Always)

Have a Nice Visit!

From the device point of view (iPhone or iPad), Visits are the most power-consumption effective way to track the user location involving almost no code. The downside is that the operating system does not guarantee the immediate sending of the generated events to the running app.

In order to get this to work in your Xojo iOS app all you need to do is set the VisitAwareness property on the MobileLocation instance of the app to True. Setting the instance to True starts tracking the device location and setting it to False stops tracking and raising Visits based events in the app.

Then, when implementing the VisitChanged Event Handler in the MobileLocation instance of the app, it will receive the following parameters when a new Visit event is raised by the operating system:

  • latitude As Double
  • longitude As Double
  • accuracy As Double
  • arrival As DateTime
  • departure As DateTime

So, for example, it will be really easy to automatically add new MapLocation instances to a MobileMap in the app based on the information received. The following snippet of code added to the VisitChanged event shows how to do that on a MobileMap control instance named VisitsMap that has been added to the Screen of the iOS app:

Var arrivalDate As String = If(arrival <> Nil, arrival.ToString, "")
Var departureDate As String = If(departure <> Nil, departure.ToString, "")

Var lc As New MapLocation(latitude, longitude, "Arrival: " + arrivalDate + EndOfLine + "Departure: " + departureDate)
VisitsMap.AddLocation(lc)

It is worth mentioning the checks on the arrival and departure DateTime objects against Nil, iOS does not guarantee to always fulfill this information on the generated Visit events. That means, you may just receive the arrival date and time or the departure date and time, or both of them.

Lastly, the Visits feature will not work when the app is run in the Simulator so you will need to build the app and copy it to the device itself (using Xcode > Devices and Simulators window). You can find an example project for the Visits feature in the Examples folder in the Xojo download,

The screenshot above shows what it looks like after using the app (in the background) for about one hour. As you can see, several MapLocation items have been added to the map tracking the places visited by the user.

GeoFencing on iOS

GeoFencing allows the operating system to notify the app when the device enters and/or exists a previously registered region. These regions are created by providing latitude, longitude and radius (in meters) values along with a String value that uniquely identifies the region. These regions persist even after exiting the app or restarting the device. The main limitation is that a maximum of 20 regions can be registered by an app.

The way to create such regions is through the new MobileCircularRegion class; for example:

Var EiffelTowerRegion As New MobileCircularRegion(48.858093, 2.294694, 20.0, "EiffelTowerExample")

By default it is set to notify when the device enters and leaves the region, this can be changed using the available class properties.

Once the region instance has been created, it needs to be added to the MobileLocation instance of your app using the AddRegion method:

MyLocationInstance.AddRegion(EiffelTowerRegion)

Lastly, and in order to receive GeoFencing events, add the RegionEntered and/or RegionExited Event Handlers to the MobileLocation instance in your app. Both of these will provide the associated MobileCircularRegion instance as the parameter, so the logic of your app can take the required path based on that.

Also, while the Visits feature can only be tested on a physical device, the GeoFencing feature can be tested in the Simulator.

You will also find other new methods in MobileLocation in order to remove a previously added Region or retrieve all the registered Regions in addition to adding them as we did in the earlier code example above.

As with the Visits, you can find a project in the Examples folder to test GeoFencing on iOS.

In Summary

Both Visits and GeoFencing provide to you new ways of retrieving the user location that can be more suitable for the purposes of the iOS apps you develop with Xojo, and because these are based in events managed by the operating system itself, they have less impact in the iPhone/iPad battery.

Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón, Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at @XojoES or on the Xojo Forum.