¿CLLocationManager SupervisadoRegiones (NSSet) no es correcto, o tal vez algo más?

Quiero verificar cada vez que el usuario pasa una tienda de una variedad de tiendas, tengo más de 20 tiendas, así que escribí una función que encuentra las 20 tiendas más cercanas a la ubicación del usuario y las monitorea. La lista que se actualiza enlocationManager: didUpdateLocations, También reemplazo las antiguas 20 regiones monitoreadas con las nuevas 20 tiendas más cercanas.

El problema es eselocationManager: didEnterRegion no se llama regularmente cuando el usuario ingresa a una región.

También he notado que cuando reviso ellocationManager.monitoredRegions NSSet las regiones allí están mal por alguna razón (lo verifiqué conif oración, ¿tal vez son correctas y más cortas?).

Si alguien pudiera verificar mi código y tal vez notara algo que hice mal, ¡realmente me ayudará!

Mi código:

monitorLocationViewController.m(desplácese para ver el código completo):

-(void)getStoresArrays:(NSNotification*)notification
{
    //Fetching "allStoresArray"(NSArray of all the stores sent from another class using NSNotificationCenter) and adding it to "allStores"(NSMutableArray)
    NSDictionary *storesCategoriesArrays=[notification userInfo];
    self.allStores=[storesCategoriesArrays objectForKey:@"allStoresArray"];

    //Calling "locationChangeHandler" for monitoring
    [self locationChangeHandler];
}

#pragma mark - CLLocationDelegate methods
//Being called when user's location updated
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
    //If "allStores"(NSMutableArray) isn't nil - calling "locationChangeHandler" to update monitoring
    if (self.allStores!=nil) {
        [self locationChangeHandler];
    }
}
//Being called when user enters a monitored region
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    NSLog(@"Entered");
}

#pragma mark - Closest stores sorting methods
//Sorting closest stores to the user's location and adding the 20 closest store to "twentyClosestStores"(NSMutableArray)
-(void)sortClosestStores
{
    //Sorting "allStores"(NSMutableArray) from the closest "Store" to the furthest.
    [self.allStores sortUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
        //Creating "location1"(CLLocation) and "location2"(CLLocation) and initializing each with "obj1"(id) and "obj2"(id) coordinates
        CLLocation *location1=[[CLLocation alloc] initWithLatitude:((Store*)obj1).geoPoint.latitude longitude:((Store*)obj1).geoPoint.longitude];
        CLLocation *location2=[[CLLocation alloc] initWithLatitude:((Store*)obj2).geoPoint.latitude longitude:((Store*)obj2).geoPoint.longitude];

        //Creating "dist1"(float) and setting its value to the distance between "location1"(CLLocation) and the user's location
        float dist1 =[location1 distanceFromLocation:self.locationManager.location];
        //Creating "dist2"(float) and setting its value to the distance between "location2"(CLLocation) and the user's location
        float dist2 = [location2 distanceFromLocation:self.locationManager.location];

        //If the distances are equal - the order will stay the same
        if (dist1 == dist2) {
            return NSOrderedSame;
        }
        else if (dist1 < dist2) { //If "dist1"(float) is smaller than "dist2"(float) - "dist2"(float) will be before "dist1" in the array
            return NSOrderedAscending;
        }
        else { //else - "dist2"(float) will be before "dist1" in the array
            return NSOrderedDescending;
        }
    }];

    //If "twentyClosestStores"(NSMutableArray) is nil
    if (self.twentyClosestStores==nil) {
        //Initializing "twentyClosestStores"(NSMutableArray)
        self.twentyClosestStores=[NSMutableArray array];
    }

    //If "previousTwentyStores"(NSMutableArray) is nil
    if (self.previousTwentyStores==nil) {
        //Initializing "previousTwentyStores"(NSMutableArray)
        self.previousTwentyStores=[NSMutableArray array];
    }
    //Setting "previousTwentyStores"(NSMutableArray) to "twentyClosestStores"(NSMutableArray)
    self.previousTwentyStores=self.twentyClosestStores;
    //Cleaning (reInitializing) "twentyClosestStores"(NSMutableArray)
    self.twentyClosestStores=[NSMutableArray array];

    //Adding indexes 0-19 of "allStores"(NSMutableArray) (20 closest stores to the user's current location) to "twentyClosestStores"(NSMutableArray)
    for (int i = 0; i < 20; i++) {
        [self.twentyClosestStores addObject:[self.allStores objectAtIndex:i]];
    }
}

#pragma mark - Start/stop monitoring methods
//For updating monitoring
-(void)locationChangeHandler
{
    //If "allStores"(NSMutableArray) isn't nil
    if (self.allStores!=nil) {
        //Finding the 20 closest stores to he user's location and adding it to "twentyClosestStores"(NSMutableArray)
        [self sortClosestStores];
        //Stop monitoring "previousTwentyStores"(NSMutableArray) (20 closest stores before user's location  updated)
        [self stopMonitoringStores];
        //Start monitoring "twentyClosestStores"(NSMutableArray)
        [self startMonitoringClosestStores];
    }
}
//Start monitoring "twentyClosestStores"(NSMutableArray)
-(void)startMonitoringClosestStores
{
    //If monitoring isn't availible for "CLCircularRegion"
    if (![CLLocationManager isMonitoringAvailableForClass:[CLCircularRegion class]]) {
        NSLog(@"Monitoring is not available for CLCircularRegion class");
    }

    //Run on all "twentyClosestStores"(NSMutableArray)'s objects
    for (Store *currentStore in self.twentyClosestStores) {
        //Creating "region"(CLCircularRegion) and setting it to "currentStore"(Store)'s circular region
        CLCircularRegion *region=[currentStore createCircularRegion];

        //Start monitoring "region"(CLCircularRegion)
        [self.locationManager startMonitoringForRegion:region];
    }
}
//Stop monitoring "previousTwentyStores"(NSMutableArray) (20 closest stores before user's location  updated)
-(void)stopMonitoringStores
{
    //Run on all "previousTwentyStores"(NSMutableArray)'s objects
    for (Store *currentStore in self.previousTwentyStores) {
        //Creating "region"(CLCircularRegion) and setting it to "currentStore"(Store)'s circular region
         CLCircularRegion *region=[currentStore createCircularRegion];

        //Stop monitoring "region"(CLCircularRegion)
        [self.locationManager stopMonitoringForRegion:region];
    }
}

//Finding a store for region
-(Store*)storeForRegion:(CLCircularRegion*)region
{
    //Creating "latitude"(CGFloat) and "longtitude"(CGFloat) and setting it to "region"(CLCircularRegion)'s center.latitude/longtitude
    CGFloat latitude=region.center.latitude;
    CGFloat longtitude=region.center.longitude;

    //Run on all "allStores"(NSMutableArray)'s objects
    for (Store *currentStore in self.allStores) {

        //If "currentStore"(Store)'s latitude and longtitude is equal to "latitude"(CGFloat) and longtitude(CGFloat)
        if (currentStore.geoPoint.latitude==latitude&&currentStore.geoPoint.longitude==longtitude) {
            //Returning "currentStore"(Store)
            return currentStore;
        }
    }
    //Store not found - returning nil
    NSLog(@"No store found for this region: %@",[region description]);
    return nil;
}

Store.m:

    //Creating and returning a "CLCircularRegion" object of the store
-(CLCircularRegion*)createCircularRegion
{
    //Creating "region"(CLCircularRegion) and initializing it with current store information (self) and radios of 200m
    CLCircularRegion *region=[[CLCircularRegion alloc] initWithCenter:self.geoPoint radius:200 identifier:self.identifier];

    //Setting "region"(CLCircularRegion)'s notifyOnEntry to YES
    region.notifyOnEntry=YES;

    //Returning "region"(CLCircularRegion)
    return region;
}

Nota: Se están llamando a los métodos delegados, inclusodidEnterRegion: pero no siempre por alguna razón

Resuelve el problema:

(He decidido no usar el monitoreo de la región y hacerlo yo mismo)

 -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
    [self checkIfNearStore]; //Not being called in background
}

-(void)checkIfNearStore
    {
        for (Store *currentStore in self.allStores) {
            if ([currentStore.circularRegion containsCoordinate:self.locationManager.location.coordinate]&&currentStore.alreadySendNotification==NO) {
                NSLog(@"Entered: %@",[[self storeForRegion:currentStore.circularRegion] address]);
                currentStore.alreadySendNotification=YES;
                [self.storesAlreadySentNotifications addObject:currentStore];
            }
        }

        for (Store *currentStore in self.storesAlreadySentNotifications) {
            if (![currentStore.circularRegion containsCoordinate:self.locationManager.location.coordinate]) {
                currentStore.alreadySendNotification=NO;
            }
        }
    }

¡Muchas gracias!

Respuestas a la pregunta(1)

Su respuesta a la pregunta