Return to Resources

Contact Monitoring Mobile SDK

Jul 27, 2020

3 min read

By: Sean Lin

We spent some time designing a mobile SDK that securely sends positioning data to our contact monitoring ingestion API. The SDK does it silently in the background, preserving battery, and sends indoor positioning data securely to our backend server. The following are the challenges we encountered when building out the SDK, specifically regarding user privacy.


Protecting user privacy:

One of the main challenges of this SDK was ensuring user privacy. According to Apple's privacy guidelines, an app should only request access only when the app needs the data. However, due to the nature of contact monitoring requiring constant background location updates to be actually useful, the user is required to allow permissions so that the app always provides location updates in the background.

To protect user privacy, we needed to use the minimum amount of data required which meant only storing and sending locations to the server when the user is actually at the venue. Fortunately for us at Mappedin we specialize in venue positioning data allowing us to accurately determine if the user is actually in the venue!


All venues generated by our mapping team in our Mappedin CMS are able to be exported in a specialized GeoJSON format called Mappedin Venue Format (MVF) which contains building and room coordinates from our CMS.

Through our SDK, we request the venue's MVF and use the data to calculate the geometry of the venue as a polygon. Additionally, a geofence region is calculated using a minimum bounding circle algorithm. This geofence region is used to toggle locations updates, which prevents the SDK from receiving location updates in the background when the device is outside the geofence region and only turn it on when they are in the geofence region. This also helps minimize battery usage.

Once location updates are turned on, the SDK will check each coordinate to determine if it is inside the venue. If it is in the venue, the location will be stored until a certain amount of time has elapsed (default is 5 minutes). It is then sent to the server in batches. This is done to prevent the number of requests sent to the server. Once the request succeeds, the locations will be deleted from the device.

So what do we store?

There are two CoreData entities in our SDK, Device and Location.

Device Attributes

extension Device {
@NSManaged public var authToken: String?
@NSManaged public var expiresAt: Date?
@NSManaged public var id: UUID
@NSManaged public var isActivated: NSNumber?
@NSManaged public var type: String?
@NSManaged public var venue: String?

Location Attributes

extension Location {
@NSManaged public var longitude: Double
@NSManaged public var latitude: Double
@NSManaged public var accuracy: Double
@NSManaged public var floor: Int32
@NSManaged public var deviceId: String
@NSManaged public var venueId: String
@NSManaged public var createdAt: Date
@NSManaged public var uploadStatus: Int16

The device type attribute is the model of the phone and the id is a unique UUID generated the first time the SDK starts tracking the user's position. This identifier does not provide any way to determine who the user actually is and non-persistent when the app is uninstalled. The only meaningful data that may provide some identification of the user is the type attribute.


Maintaining user privacy is a difficult challenge when it comes to contact monitoring, however it is an essential problem to solve. If the user doesn't trust the app with their data then they're unlikely to want to install the app. Well you could enforce it on employees making it mandatory if they want to work but that level of distrust would probably only make things worse. At Mappedin we believe it is important to maintain full transparency into how your app will store and use their location data and we hope that you do the same if you're involved in the development of any of the numerous contact monitoring projects!