I'm fairly new to xamarin and mobile dev. I'm currently migrating geofire library by Firebase to xamarin.ios. I came across the following objective-c code and trying to figure out what is actually doing? and its c# equivalent:
@property (nonatomic, strong) NSMutableDictionary *keyEnteredObservers;
...
GFQueryLocationInfo *info = self.locationInfos[key];
[self.keyEnteredObservers enumerateKeysAndObjectsUsingBlock:^(id observerKey,
GFQueryResultBlock block,
BOOL *stop) {
dispatch_async(self.geoFire.callbackQueue, ^{ // the callbackQueue is of type @property (nonatomic, strong) dispatch_queue_t callbackQueue;
block(key, info.location);
});
}];
for the callbackQueue I am currently using type BlockingCollection<'Task>
Any help is greatly appreciated.
A NSMutableDictionary.enumerateKeysAndObjectsUsingBlock in this context is doing two basic things.
It filters the dictionary based on an key. (A Linq Where would work as a C# replacement)
The filtered elements of the dictionary are available to a "block" of code as it is executed asynchronously(dispatch_async) via GCD (Grand Central Dispatch). So you are already using a BlockingCollection as a Task pump, so pass the key string that is a parameter to updateLocationInfo and the CLLocation to your Task...
Note: The stop boolean will cause an early exit from the enumerator, so a C# break as a replacement, but it is not used in this context...
If you are still using a NSMutableDictionary for your observers, you can filter via KeysForObject. In my version of GeoFire, I used a BlockingCollection<Action> vs. Tasks thus added the lambdas directly to the work queue.
Something like:
foreach (var info in keyEnteredObservers.KeysForObject(firebaseHandle))
{
var nonCapturedLocation = info.location.Copy(); // location = CLLocation, do not capture entire dictionary by ref in lambda
callbackQueue.Add(() =>
{
GFQueryResultBlock(key, nonCapturedLocation);
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With