Location Tracking with Swift

I’m writing this for a local university with students who are working on an iOS project to track the locations of an object at a fixed location. I advised them to ensure that the data models input into Realm match those in the script and be cautioned that further work will be required for the mobile app, such as recalculating things as your device location changes in relation to the object you’re tracking.

To track and follow a moving object using Swift, you can use the Core Location framework, specifically the CLLocationManager class. Here’s an example code snippet that shows how to track and follow a moving object using the CLLocationManager:

import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate {

    let locationManager = CLLocationManager()

    override func viewDidLoad() {
        super.viewDidLoad()

        // Request authorization to use location services
        locationManager.requestWhenInUseAuthorization()

        // Set up location manager
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
        locationManager.startUpdatingLocation()
        locationManager.startUpdatingHeading()
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        // Get the current location
        guard let currentLocation = locations.last else { return }

        // Calculate the distance and bearing to the target location
        let targetLocation = CLLocation(latitude: 37.7749, longitude: -122.4194)  // target location (e.g., moving object)
        let distance = currentLocation.distance(from: targetLocation)
        let bearing = currentLocation.bearing(to: targetLocation)

        // Rotate the view to point in the direction of the target location
        // (assuming that the view is a compass or map view)
        let heading = locationManager.heading?.trueHeading ?? 0.0  // get the current heading
        let relativeBearing = bearing - heading  // calculate the relative bearing
        // rotate the view by relativeBearing degrees
        // (assuming that the view's orientation is measured in degrees clockwise from true north)
    }
}

In this example, we create a CLLocationManager object and request authorization to use location services. We set the delegate to self and configure the location manager to use the best available accuracy for navigation. We start updating the location and heading of the device.

In the locationManager(_:didUpdateLocations:) method, we get the current location from the locations array. We then calculate the distance and bearing to the target location, which in this case is a fixed location that represents the moving object.

We calculate the relative bearing by subtracting the current heading from the bearing to the target location. We then rotate the view by the relative bearing to point in the direction of the target location.

Note that this is a simplified example and assumes that the target location is a fixed location. If the target location is a moving object, you’ll need to update its location periodically and recalculate the distance and bearing to it. You can do this using a timer or by subscribing to location updates from a remote API.

Just leaving this here

To use Swift with MongoDB Realm to calculate the locations of objects relative to your location, you can follow these general steps:

  1. Set up a MongoDB Realm app and configure it to work with your Swift app.

  2. Create a data model in Swift that represents the objects you want to track. You can use the @objcMembers attribute to expose the Swift properties to Objective-C.

   import RealmSwift

   @objcMembers
   class Object: Object {
       dynamic var id = UUID().uuidString
       dynamic var name = ""
       dynamic var latitude = 0.0
       dynamic var longitude = 0.0
   }
  1. Create a Realm database and add some sample data.

   let config = Realm.Configuration(schemaVersion: 1)
   Realm.Configuration.defaultConfiguration = config
   let realm = try! Realm()

   try! realm.write {
       let object1 = Object()
       object1.name = "Object 1"
       object1.latitude = 37.7749
       object1.longitude = -122.4194
       realm.add(object1)

       let object2 = Object()
       object2.name = "Object 2"
       object2.latitude = 37.773972
       object2.longitude = -122.431297
       realm.add(object2)
   }
  1. Retrieve the objects from the Realm database and calculate their distances and bearings relative to your location.
   let objects = realm.objects(Object.self)

   let myLocation = CLLocation(latitude: 37.7749, longitude: -122.4194)
   for object in objects {
       let objectLocation = CLLocation(latitude: object.latitude, longitude: object.longitude)
       let distance = myLocation.distance(from: objectLocation)
       let bearing = myLocation.bearing(to: objectLocation)
       print("Object: \(object.name), Distance: \(distance)m, Bearing: \(bearing)°")
   }

In this example, we create a CLLocation object for our location and loop through each object in the Realm database. We create a CLLocation object for each object’s location and use the distance(from:) method to calculate the distance between the two locations. We use the bearing(to:) method to calculate the bearing from our location to the object’s location.

Note that the bearing(to:) method returns the bearing in degrees clockwise from true north, so you may need to convert it to a different format depending on your use case.

  1. Update the UI to display the calculated distances and bearings.

    You can update the UI of your app to display the calculated distances and bearings. You may also want to add functionality to dynamically update the locations of the objects in the database, as well as your own location, so that the distances and bearings are continually updated in real time.