Search code examples
iosobjective-cbroadcastadsibeacon

How to set iBeacon to broadcast a local notification only once for a single device?


I'm presenting a local notification whenever we're entering or exiting a region in

locationManager:didRangeBeacons:inRegion method of CLLocationManagerDelegate:

something like this..

//local notification sent from transmitter to receiver 

switch (beacon.proximity) 
{  
 case CLProximityNear:   
   message = @"You are near the ibeacon device";  
   bgColor = [UIColor blueColor];  
   break;  
 case CLProximityImmediate:   
   message = @"You are very closer to the device..";  
   bgColor = [UIColor colorWithRed:.0f green:.0f blue:230.0f alpha:1.0f];  
   break; 
}

Now when the receiver detects the transmitter and sends the local notification, the receiver will be getting the local notifications. Additionally I want to set the local notification for one day i.e., receiver should receive the message from transmitter only once. Valuable suggestions are highly appreciated.

Note: I'm using iPad mini as the Transmitter & iPhone 5 as the receiver.


Solution

  • You need to keep track of the times each beacon was detected in your didRangeBeaconsInRegion method and ignore certain beacons using a software filter if they have been seen recently.

    An example of how to do this is shown here. The core of that is:

      - (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLRegion *)region
      {
          for (CLBeacon *beacon in beacons) {
              Boolean shouldSendNotification = NO;
              NSDate *now = [NSDate date];
              NSString *beaconKey = [NSString stringWithFormat:@"%@_%ld_%ld", [beacon.proximityUUID UUIDString], (long) beacon.major, (long) beacon.minor];
              NSLog(@"Ranged UUID: %@ Major:%ld Minor:%ld RSSI:%ld", [beacon.proximityUUID UUIDString], (long)beacon.major, (long)beacon.minor, (long)beacon.rssi);
    
              if ([beaconLastSeen objectForKey:beaconKey] == Nil) {
                  NSLog(@"This beacon has never been seen before");
                  shouldSendNotification = YES;
              }
              else {
                  NSDate *lastSeen = [beaconLastSeen objectForKey:beaconKey];
                  NSTimeInterval secondsSinceLastSeen = [now timeIntervalSinceDate:lastSeen];
                  NSLog(@"This beacon was last seen at %@, which was %.0f seconds ago", lastSeen, secondsSinceLastSeen);
                  if (secondsSinceLastSeen < 3600*24 /* one day in seconds */) {
                      shouldSendNotification = YES;
                  }
              }
    
              if (shouldSendNotification) {
                  [self sendLocalNotification];
              }
          }
      }