Michael Hsu
Michael Hsu

Reputation: 982

use geofire for a one time location update? swift 4

So the Geofire documentation said this:

There are three kinds of events that can occur with a geo query:

Key Entered: The location of a key now matches the query criteria.

Key Exited: The location of a key no longer matches the query criteria.

Key Moved: The location of a key changed but the location still matches the query criteria.

But since these are all realtime, how would I do make it so that it only queries once, say, on a button press, and store the keys? My locationManager.didUpdateLocations looks something like this:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    if let location = locations.last {
        if String(describing: Date()) == String(describing: location.timestamp) {

            var query = geoFire.queryAtLocation(location, withRadius: 10)
            query.observe(.keyEntered, with: { (key, location) in
                // Is this where I store the keys?
                print("Key '\(key)' entered the search area and is at location '\(location)'")
            })

            manager.stopUpdatingLocation()
        }
    }
}

I tried this, but the results that come back are not determinant. Even though my location isn't moving (on the simulator), it sometimes misses some keys or double counts others.

Upvotes: 0

Views: 434

Answers (1)

tommybananas
tommybananas

Reputation: 5736

You can use ObserveReadyWithBlock: to know when the initial data has been loaded, then cancel the query.

Adds an observer that is called once all initial GeoFire data has been loaded and the relevant events have been fired for this query.

Here is an example in javascript, from a similar discussion on github, but it would be the same for iOS.

var items = []; // save the items

var onKeyEnteredRegistration = geoQuery.on("key_entered", function(key, location, distance) {
  console.log(key + " entered query at " + location + " (" + distance + " km from center)");
  items.push(key);
});

geoQuery.on("ready", function() {
  // This will fire once the initial data is loaded, so now we can cancel the "key_entered" event listener
  onKeyEnteredRegistration.cancel();
});

But isn't it inefficient to retrieve items one-by-one?

Not really. Firebase is highly optimized and keeps a persistent connection open via websockets.

Upvotes: 2

Related Questions