From 4b411b413281418c0f61270e1bd697748e2c8eb8 Mon Sep 17 00:00:00 2001 From: michalchudziak Date: Sun, 1 Sep 2024 09:52:37 +0200 Subject: [PATCH] chore: fix watch clearing issues --- ios/RNCGeolocation.mm | 14 +++++++++++++ js/implementation.native.ts | 42 +++++++++++++++---------------------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/ios/RNCGeolocation.mm b/ios/RNCGeolocation.mm index d7faad7..03df64d 100644 --- a/ios/RNCGeolocation.mm +++ b/ios/RNCGeolocation.mm @@ -309,6 +309,10 @@ - (void)enableBackgroundLocationUpdates RCT_REMAP_METHOD(startObserving, startObserving:(RNCGeolocationOptions)options) { checkLocationConfig(); + + if (_observingLocation) { + [self stopObserving]; + } // Select best options _observerOptions = options; @@ -376,6 +380,12 @@ - (void)enableBackgroundLocationUpdates successBlock(@[_lastLocationEvent]); return; } + + BOOL didPause = NO; + if (_observingLocation) { + [self stopObserving]; + didPause = YES; + } // Create request RNCGeolocationRequest *request = [RNCGeolocationRequest new]; @@ -400,6 +410,10 @@ - (void)enableBackgroundLocationUpdates [self beginLocationUpdatesWithDesiredAccuracy:accuracy distanceFilter:options.distanceFilter useSignificantChanges:options.useSignificantChanges]; + + if (didPause) { + [self startObserving]; + } } #pragma mark - CLLocationManagerDelegate diff --git a/js/implementation.native.ts b/js/implementation.native.ts index 9a1d313..640b3b9 100644 --- a/js/implementation.native.ts +++ b/js/implementation.native.ts @@ -23,10 +23,9 @@ import type { const { RNCGeolocation, GeolocationEventEmitter } = GeolocationNativeInterface; -let subscriptions: ( - | [EmitterSubscription, EmitterSubscription | null] - | undefined -)[] = []; +let subscriptions: { + [key: number]: [EmitterSubscription, EmitterSubscription | null]; +} = {}; let updatesEnabled = false; /** @@ -100,13 +99,13 @@ export function watchPosition( RNCGeolocation.startObserving(options); updatesEnabled = true; } - const watchID = subscriptions.length; - subscriptions.push([ + const watchID = Object.keys(subscriptions).length + 1000; + subscriptions[watchID] = [ GeolocationEventEmitter.addListener('geolocationDidChange', success), error ? GeolocationEventEmitter.addListener('geolocationError', error) : null, - ]); + ]; return watchID; } @@ -117,6 +116,7 @@ export function watchPosition( */ export function clearWatch(watchID: number) { const sub = subscriptions[watchID]; + console.log('clear watch', watchID, sub); if (!sub) { // Silently exit when the watchID is invalid or already cleared // This is consistent with timers @@ -127,13 +127,9 @@ export function clearWatch(watchID: number) { // array element refinements not yet enabled in Flow const sub1 = sub[1]; sub1 && sub1.remove(); - subscriptions[watchID] = undefined; - let noWatchers = true; - for (let ii = 0; ii < subscriptions.length; ii++) { - if (subscriptions[ii]) { - noWatchers = false; // still valid subscriptions - } - } + + delete subscriptions[watchID]; + let noWatchers = Object.keys(subscriptions).length === 0; if (noWatchers) { stopObserving(); } @@ -146,18 +142,14 @@ export function clearWatch(watchID: number) { */ export function stopObserving() { if (updatesEnabled) { + console.log('stopping observing') RNCGeolocation.stopObserving(); updatesEnabled = false; - for (let ii = 0; ii < subscriptions.length; ii++) { - const sub = subscriptions[ii]; - if (sub) { - warning(false, 'Called stopObserving with existing subscriptions.'); - sub[0].remove(); - // array element refinements not yet enabled in Flow - const sub1 = sub[1]; - sub1 && sub1.remove(); - } - } - subscriptions = []; + Object.values(subscriptions).forEach(([sub, sub1]) => { + warning(false, 'Called stopObserving with existing subscriptions.'); + sub.remove(); + sub1 && sub1.remove(); + }); + subscriptions = {}; } }