From ed845a40434c82530c2e4d5de43c3d4301a59c32 Mon Sep 17 00:00:00 2001 From: Liam Meier Date: Thu, 21 Sep 2023 12:49:18 -0400 Subject: [PATCH] try to fix stopping and starting of monitoring same beacon regions --- RadarSDK.podspec | 2 +- RadarSDK/RadarLocationManager.h | 2 + RadarSDK/RadarLocationManager.m | 124 +++++++++++++++++++++++++++++++- RadarSDK/RadarUtils.m | 2 +- 4 files changed, 126 insertions(+), 4 deletions(-) diff --git a/RadarSDK.podspec b/RadarSDK.podspec index e12db6e22..b065bc373 100644 --- a/RadarSDK.podspec +++ b/RadarSDK.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'RadarSDK' - s.version = '3.8.9-beta.2' + s.version = '3.8.9-beta.3' s.summary = 'iOS SDK for Radar, the leading geofencing and location tracking platform' s.homepage = 'https://radar.com' s.author = { 'Radar Labs, Inc.' => 'support@radar.com' } diff --git a/RadarSDK/RadarLocationManager.h b/RadarSDK/RadarLocationManager.h index f09d98d20..b136f6480 100644 --- a/RadarSDK/RadarLocationManager.h +++ b/RadarSDK/RadarLocationManager.h @@ -28,6 +28,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)stopTracking; - (void)replaceSyncedGeofences:(NSArray *)geofences; - (void)replaceSyncedBeacons:(NSArray *)beacons; +- (void)updateSyncedBeacons:(NSArray *)beacons; +- (void)updateSyncedBeaconUUIDs:(NSArray *)uuids; - (void)replaceSyncedBeaconUUIDs:(NSArray *)uuids; - (void)updateTracking; - (void)updateTrackingFromMeta:(RadarMeta *_Nullable)meta; diff --git a/RadarSDK/RadarLocationManager.m b/RadarSDK/RadarLocationManager.m index fca91dc48..1b6c452ee 100644 --- a/RadarSDK/RadarLocationManager.m +++ b/RadarSDK/RadarLocationManager.m @@ -565,6 +565,126 @@ - (void)removePendingNotificationsWithCompletionHandler:(void (^)(void))completi }]; } +- (void)updateSyncedBeacons:(NSArray *)newBeacons { + BOOL tracking = [RadarSettings tracking]; + RadarTrackingOptions *options = [Radar getTrackingOptions]; + if (!tracking || !options.beacons || !newBeacons) { + [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelDebug message:@"Skipping updating synced beacons"]; + return; + } + + // Convert new beacons to set for faster lookup + NSMutableSet *newBeaconIdentifiers = [NSMutableSet set]; + for (RadarBeacon *beacon in newBeacons) { + NSString *identifier = [NSString stringWithFormat:@"%@%@", kSyncBeaconIdentifierPrefix, beacon._id]; + [newBeaconIdentifiers addObject:identifier]; + } + + // Determine current beacons being monitored + NSMutableSet *currentBeaconIdentifiers = [NSMutableSet set]; + for (CLRegion *region in self.locationManager.monitoredRegions) { + if ([region isKindOfClass:[CLBeaconRegion class]] && [region.identifier hasPrefix:kSyncBeaconIdentifierPrefix]) { + [currentBeaconIdentifiers addObject:region.identifier]; + } + } + + // Stop monitoring beacons that are not in the new list + for (NSString *identifier in currentBeaconIdentifiers) { + if (![newBeaconIdentifiers containsObject:identifier]) { + CLRegion *regionToRemove = nil; + for (CLRegion *region in self.locationManager.monitoredRegions) { + if ([region.identifier isEqualToString:identifier]) { + regionToRemove = region; + break; + } + } + if (regionToRemove) { + [self.locationManager stopMonitoringForRegion:regionToRemove]; + } + } + } + + // Start monitoring new beacons not currently being monitored + NSUInteger numBeacons = MIN(newBeacons.count, 9); + for (int i = 0; i < numBeacons; i++) { + RadarBeacon *beacon = [newBeacons objectAtIndex:i]; + NSString *identifier = [NSString stringWithFormat:@"%@%@", kSyncBeaconIdentifierPrefix, beacon._id]; + if (![currentBeaconIdentifiers containsObject:identifier]) { + CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:beacon.uuid] + major:[beacon.major intValue] + minor:[beacon.minor intValue] + identifier:identifier]; + + if (region) { + region.notifyEntryStateOnDisplay = YES; + [self.locationManager startMonitoringForRegion:region]; + [self.locationManager requestStateForRegion:region]; + + [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelDebug + message:[NSString stringWithFormat:@"Synced beacon | identifier = %@; uuid = %@; major = %@; minor = %@", identifier, beacon.uuid, + beacon.major, beacon.minor]]; + } else { + [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelDebug + message:[NSString stringWithFormat:@"Error syncing beacon | identifier = %@; uuid = %@; major = %@; minor = %@", identifier, + beacon.uuid, beacon.major, beacon.minor]]; + } + } + } +} + +- (void)updateSyncedBeaconUUIDs:(NSArray *)uuids { + NSMutableArray *existingUUIDs = [NSMutableArray array]; + for (CLRegion *region in self.locationManager.monitoredRegions) { + if ([region.identifier hasPrefix:kSyncBeaconUUIDIdentifierPrefix]) { + NSString *existingUUID = [(CLBeaconRegion *)region proximityUUID].UUIDString; + [existingUUIDs addObject:existingUUID]; + } + } + + BOOL tracking = [RadarSettings tracking]; + RadarTrackingOptions *options = [Radar getTrackingOptions]; + if (!tracking || !options.beacons || !uuids) { + return; + } + + NSUInteger numUUIDs = MIN(uuids.count, 9); + + for (int i = 0; i < numUUIDs; i++) { + NSString *uuid = uuids[i]; + + // If UUID is already being monitored, skip + if ([existingUUIDs containsObject:uuid]) { + continue; + } + + NSString *identifier = [NSString stringWithFormat:@"%@%@", kSyncBeaconUUIDIdentifierPrefix, uuid]; + CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:uuid] identifier:identifier]; + + if (region) { + region.notifyEntryStateOnDisplay = YES; + [self.locationManager startMonitoringForRegion:region]; + [self.locationManager requestStateForRegion:region]; + + [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelDebug message:[NSString stringWithFormat:@"Synced UUID | identifier = %@; uuid = %@", identifier, uuid]]; + } else { + [[RadarLogger sharedInstance] logWithLevel:RadarLogLevelDebug message:[NSString stringWithFormat:@"Error syncing UUID | identifier = %@; uuid = %@", identifier, uuid]]; + } + } + + // Remove any old UUIDs that aren't in the new list + for (NSString *existingUUID in existingUUIDs) { + if (![uuids containsObject:existingUUID]) { + NSString *identifierToRemove = [NSString stringWithFormat:@"%@%@", kSyncBeaconUUIDIdentifierPrefix, existingUUID]; + for (CLRegion *region in self.locationManager.monitoredRegions) { + if ([region.identifier isEqualToString:identifierToRemove]) { + [self.locationManager stopMonitoringForRegion:region]; + } + } + } + } +} + + - (void)replaceSyncedBeacons:(NSArray *)beacons { [self removeSyncedBeacons]; @@ -838,9 +958,9 @@ - (void)sendLocation:(CLLocation *)location stopped:(BOOL)stopped source:(RadarL limit:10 completionHandler:^(RadarStatus status, NSDictionary *_Nullable res, NSArray *_Nullable beacons, NSArray *_Nullable beaconUUIDs) { if (beaconUUIDs && beaconUUIDs.count) { - [self replaceSyncedBeaconUUIDs:beaconUUIDs]; + [self updateSyncedBeaconUUIDs:beaconUUIDs]; } else if (beacons && beacons.count) { - [self replaceSyncedBeacons:beacons]; + [self updateSyncedBeacons:beacons]; } }]; } diff --git a/RadarSDK/RadarUtils.m b/RadarSDK/RadarUtils.m index b38d8f572..e63cfee8e 100644 --- a/RadarSDK/RadarUtils.m +++ b/RadarSDK/RadarUtils.m @@ -45,7 +45,7 @@ + (NSNumber *)timeZoneOffset { } + (NSString *)sdkVersion { - return @"3.8.9-beta.2"; + return @"3.8.9-beta.3"; } + (NSString *)deviceId {