My customer asked if it is possible that when a customer walks by his store he receives an email with todays special prices, even if the app is not running.
My question is: Is it allowed by iOS to call a restservice if the app is wakened by the iBeacon event?
I tried to play a system sound to simulate the restservice call and this is not working. Only when the app is in foreground.
To give you an idea how I designed my Beaconhandler so far, here is my code. Perhaps someone has an idea to improve it:
#import "BeaconHandler.h"
#interface BeaconHandler ()
#property (strong, nonatomic) CLLocationManager *locationManager;
#property CLProximity lastProximity;
#end
#implementation BeaconHandler
-(void) startMonitoring{
if(![self monitoringIsAllowed]){
return;
}
[self initLocationManager];
[self startMonitoringBeacons:[self beaconIDsToMonitor]];
}
-(BOOL) monitoringIsAllowed{
//TODO configuration
return YES;
}
-(NSDictionary*) beaconIDsToMonitor{
//TODO: load beacons from server
return #{#"region1":[[NSUUID alloc] initWithUUIDString:#"B9407F30-F5F8-466E-AFF9-25556B57FE6D"],
#"region2":[[NSUUID alloc] initWithUUIDString:#"B9407F30-F5F8-466E-AFF9-25556B57FE6A"]
};
}
-(void) initLocationManager{
self.locationManager = [[CLLocationManager alloc] init];
if([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}
self.locationManager.delegate = self;
self.locationManager.pausesLocationUpdatesAutomatically = NO;
}
-(void) startMonitoringBeacons:(NSDictionary*)beacons{
for (NSString* beaconIdentifier in beacons.allKeys) {
NSUUID *beaconUUID = beacons[beaconIdentifier];
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:beaconUUID identifier:beaconIdentifier];
beaconRegion.notifyEntryStateOnDisplay = YES;
[self.locationManager startMonitoringForRegion:beaconRegion];
[self.locationManager startRangingBeaconsInRegion:beaconRegion];
}
[self.locationManager startUpdatingLocation];
}
//TODO replace by backend call
-(void)sendLocalNotificationWithMessage:(NSString*)message{
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.alertBody =message;
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}
#pragma CLLocationDelegate
-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
for (CLBeacon *beacon in beacons) {
if(beacon.proximity == self.lastProximity ||
beacon.proximity == CLProximityUnknown) {
return;
}
self.lastProximity = beacon.proximity;
[self sendLocalNotificationWithMessage:[NSString stringWithFormat:#"You are inside region %#", region.identifier]];
}
}
Yes, this is possible. I can confirm I have done this successfully on iOS. A couple of tips to get it running in the background:
Get this working in the foreground first.
You only have 5 seconds of background running time after entering/exiting a region, so make sure your web service returns quickly.
Add NSLog statements to your callbacks to figure out what is and is not completing in the background.
If the above does not help, post your code in the callback.
Related
Part one:
I have written the following code to monitor iBeacons. I would like to detect the didEnterRegion and didExitRegion event. However it never happens. Would you be able to take a look at the code and suggest what could be missing?
I use the Apple AirLocate sample code to configure one device as iBeacon and perform the following steps to test my code:
Steps:
compile and execute AirLocate sample code on device B
compile and execute this code on device A
in device B use AirLocate app to configure device as iBeacon choosing the following UUID: "74278BDA-B644-4520-8F0C-720EAF059935"
Results:
state inside message
Expected results:
state inside message
did enter region
Why is that?
Those are my plist entries:
Code:
#import "BeaconMonitoring.h"
#implementation BeaconMonitoring
- (instancetype)init
{
self = [super init];
if (self) {
self.locationManager = [[CLLocationManager alloc] init];
if([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}
self.locationManager.delegate = self;
self.locationManager.pausesLocationUpdatesAutomatically = NO;
self.monitoredRegions = [[NSMutableArray alloc] initWithCapacity:10];
}
return self;
}
- (void) startRangingForBeacons{
NSLog(#"in startRangingForBeacons");
[self.locationManager startUpdatingLocation];
[self startMonitoringForRegion:[[NSUUID alloc] initWithUUIDString:#"74278BDA-B644-4520-8F0C-720EAF059935"] :#"b"];
}
- (void) startMonitoringForRegion:(NSUUID*)beaconUUID :(NSString*)regionIdentifier{
/**
Alternatively:
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:#"xxxx"
major:10
minor:20
identifier:#"name"]
**/
// Override point for customization after application launch.
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:beaconUUID identifier:regionIdentifier];
beaconRegion.notifyEntryStateOnDisplay = NO;
beaconRegion.notifyOnEntry = YES;
beaconRegion.notifyOnExit = YES;
[self.locationManager startMonitoringForRegion:beaconRegion];
[self.locationManager startRangingBeaconsInRegion:beaconRegion];
[self.monitoredRegions addObject:beaconRegion];
}
- (void) stopRangingForbeacons{
NSLog(#"in stopRangingForbeacons");
[self.locationManager stopUpdatingLocation];
for (int i=0; i < [self.monitoredRegions count]; i++) {
NSObject * object = [self.monitoredRegions objectAtIndex:i];
if ([object isKindOfClass:[CLBeaconRegion class]]) {
CLBeaconRegion * region = (CLBeaconRegion*)object;
[self.locationManager stopMonitoringForRegion:region];
[self.locationManager stopRangingBeaconsInRegion:region];
}
else{
NSLog(#"Serious error, should never happen!");
}
}
}
#pragma CLLocationManagerDelegate
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
[manager startRangingBeaconsInRegion:(CLBeaconRegion*)region];
[self.locationManager startUpdatingLocation];
NSLog(#"You entered the region.");
}
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
[manager stopRangingBeaconsInRegion:(CLBeaconRegion*)region];
[self.locationManager stopUpdatingLocation];
NSDictionary * notificationData = #{ #"value" : #"exitedRegion"};
[[NSNotificationCenter defaultCenter] postNotificationName:#"dataUpdate" object:nil userInfo:notificationData];
NSLog(#"You exited the region.");
// [self sendLocalNotificationWithMessage:#"You exited the region."];
}
- (void) locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
NSLog(#"did determine state");
switch (state) {
case CLRegionStateInside:
NSLog(#"state inside");
break;
case CLRegionStateOutside:
NSLog(#"state outside");
break;
case CLRegionStateUnknown:
NSLog(#"state unknown");
break;
default:
NSLog(#"Default case: Region unknown");
break;
}
}
-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
NSLog(#"Did range %lu beacon in region %#", (unsigned long)[beacons count], region.identifier);
NSString * visibleInformation = [NSString stringWithFormat:#"(%lu)", (unsigned long)[beacons count]];
for (int i=0; i<[beacons count]; i++) {
CLBeacon *beacon = [beacons objectAtIndex:i];
if ([beacons count] == 1) {
NSNumber * distance = [NSNumber numberWithFloat:beacon.accuracy];
visibleInformation = [NSString stringWithFormat:#"%i-%i is %f", beacon.major.intValue, beacon.minor.intValue, distance.doubleValue];
}
else{
visibleInformation = [visibleInformation stringByAppendingString:[NSString stringWithFormat:#" %i-%i ", beacon.major.intValue, beacon.minor.intValue]];
}
}
}
#end
Part two:
I had a look at the AirLocate source code to understand if there was something that I had to trigger in the state inside message to get the monitoring working properly. However I found that the ** didDetermineState** method is implemented in the AppDelegate.
Why is that?
- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
/*
A user can transition in or out of a region while the application is not running. When this happens CoreLocation will launch the application momentarily, call this delegate method and we will let the user know via a local notification.
*/
UILocalNotification *notification = [[UILocalNotification alloc] init];
if(state == CLRegionStateInside)
{
notification.alertBody = NSLocalizedString(#"You're inside the region", #"");
}
else if(state == CLRegionStateOutside)
{
notification.alertBody = NSLocalizedString(#"You're outside the region", #"");
}
else
{
return;
}
/*
If the application is in the foreground, it will get a callback to application:didReceiveLocalNotification:.
If it's not, iOS will display the notification to the user.
*/
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}
Assumption: R = Region made by B and listened to by A
Case 1
IF A was started before B:
app A should tell you determine state for region R = outside
app A should run didEnter Region R
case 2
IF A was infact started after B:
it should only run determineState Region R = inside
the end. There is no 2 here because it never enters the range. it was started inside of it
I have create a custom delegate with CLLocationManagerDelegate when i call the delegate methods inside CLLocationManagerDelegate delegates are not working properly. i think the way i create the delegate was wrong can someone tell me what i have done wrong ?
.h file
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <UIKit/UIKit.h>
#protocol iBeaconDeligate<NSObject>
#required
-(void)getArray:(NSArray *)beaconArray;
#end
#interface iBeaconDeligate : NSObject <CLLocationManagerDelegate>
#property (strong, nonatomic) CLLocationManager *locationManager;
#property CLProximity lastProximity;
-(void) initiBeaconDeligate;
#end
this is .m file
#import "iBeaconDeligate.h"
#implementation iBeaconDeligate
-(void) initiBeaconDeligate
{
NSUUID *beaconUUID = [[NSUUID alloc] initWithUUIDString:
#"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"];
NSString *beaconIdentifier = #"iBeaconModules.us";
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:
beaconUUID identifier:beaconIdentifier];
self.locationManager = [[CLLocationManager alloc] init];
//[self.locationManager requestWhenInUseAuthorization];
//[self.locationManager requestAlwaysAuthorization];
// New iOS 8 request for Always Authorization, required for iBeacons to work!
if([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}
self.locationManager.delegate = self;
self.locationManager.pausesLocationUpdatesAutomatically = NO;
[self.locationManager startMonitoringForRegion:beaconRegion];
[self.locationManager startRangingBeaconsInRegion:beaconRegion];
[self.locationManager startUpdatingLocation];
}
-(void)sendLocalNotificationWithMessage:(NSString*)message {
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:60];
notification.alertBody = message;
notification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:
(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
NSString *message = #"";
if(beacons.count > 0) {
CLBeacon *nearestBeacon = beacons.firstObject;
if(nearestBeacon.proximity == self.lastProximity ||
nearestBeacon.proximity == CLProximityUnknown) {
return;
}
self.lastProximity = nearestBeacon.proximity;
switch(nearestBeacon.proximity) {
case CLProximityFar:
message = #"You are far away from the beacon";
break;
case CLProximityNear:
message = #"You are near the beacon";
break;
case CLProximityImmediate:
message = #"You are in the immediate proximity of the beacon";
break;
case CLProximityUnknown:
return;
}
} else {
message = #"No beacons are nearby";
}
[self performSelector:#selector(getArray:) withObject:beacons];
NSLog(#"%#", message);
[self sendLocalNotificationWithMessage:message];
}
-(void)locationManager:(CLLocationManager *)manager
didEnterRegion:(CLRegion *)region {
[manager startRangingBeaconsInRegion:(CLBeaconRegion*)region];
[self.locationManager startUpdatingLocation];
NSLog(#"You entered the region.");
[self sendLocalNotificationWithMessage:#"You entered the region."];
}
-(void)locationManager:(CLLocationManager *)manager
didExitRegion:(CLRegion *)region {
[manager stopRangingBeaconsInRegion:(CLBeaconRegion*)region];
[self.locationManager stopUpdatingLocation];
NSLog(#"You exited the region.");
[self sendLocalNotificationWithMessage:#"You exited the region."];
}
#end
this is how i called it in my controller class
.h
#interface HomeViewController : UIViewController<iBeaconDeligate>
.m
iBeaconDeligate *sampleProtocol = [[iBeaconDeligate alloc]init];
[sampleProtocol initiBeaconDeligate];
the problem was methodes that invoke automatically in CLLocationManagerDelegate are not calling in my custom delegate
As sampleProtocol is a local variable inside the method, it will be deallocated when the method exits.
You should create a (strong) #property to store this object to ensure it is retained.
i'm developing an iOS application and i'm using beacons.
I've a problem. I'm at the beginning of the development, so I only have my appdelegate. In appdelegate.m I have initialized like so
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:#"8AEFB031-6C32-486F-825B-E26FA193487D"];
CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:uuid
identifier:#"Region"];
if ([CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]])
{
NSLog(#"I'm looking for a beacon");
[self.locationManager startRangingBeaconsInRegion:region];
} else {
NSLog(#"Device doesn't support beacons ranging");
}
return YES;
}
and then I wrote two delegate methods
- (void) locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
NSLog(#"EXIT");
}
- (void) locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
NSLog(#"ENTER");
}
but they never get called!!! What's the problem here?
you RANGE but you never MONITOR the regions.
Ranging for beacons will only call: locationManager:didRangeBeacons:inRegion:
The methods enterRegion/exitRegion you want are for monitoring only. So call:
- (void)startMonitoringForRegion:(CLRegion *)region
I don't know why there are not calling but this is how we can handle beacons...
- (void)createBeaconRegion
{
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:#"8AEFB031-6C32-486F-825B-E26FA193487D"];
CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:uuid
identifier:#"Region"];
if ([CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]])
{
NSLog(#"I'm looking for a beacon");
[self.locationManager startRangingBeaconsInRegion:region];
} else {
NSLog(#"Device doesn't support beacons ranging");
}
}
- (void)turnOnRanging
{
NSLog(#"Turning on ranging...");
if (![CLLocationManager isRangingAvailable]) {
NSLog(#"Couldn't turn on ranging: Ranging is not available.");
self.rangingSwitch.on = NO;
return;
}
if (self.locationManager.rangedRegions.count > 0) {
NSLog(#"Didn't turn on ranging: Ranging already on.");
return;
}
[self createBeaconRegion];
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
NSLog(#"Ranging turned on for region: %#.", self.beaconRegion);
}
- (void)startRangingForBeacons
{
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.detectedBeacons = [NSArray array];
[self turnOnRanging];
}
- (void)stopRangingForBeacons
{
if (self.locationManager.rangedRegions.count == 0) {
NSLog(#"Didn't turn off ranging: Ranging already off.");
return;
}
[self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
NSLog(#"Turned off ranging.");
}
You can refer the entire sample project using below link
https://github.com/nicktoumpelis/HiBeacons
That uses to display Beacons..
Hope it helps you....!
FIXED: I was creating my CLLocationManager in the viewDidLoad method, so it was being cleaned by ARC almost immediately. I changed my instance to be a class instance instead of method instance and the problem is solved.
I have a class, an NSObject, which I'm using to control the entering and exiting of beacon regions.
It's implementation is here:
#import "dcBeaconManager.h"
#implementation dcBeaconManager
-(id)init
{
self = [super init];
if (self != nil){}
return self;
}
bool testRanging = true;
bool firstRegionEntered = true;
- (void)initBeaconManager {
NSLog(#"initBeaconManager called");
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
NSUUID *uuid = [[NSUUID alloc]initWithUUIDString:#"B9407F30-F5F8-466E-AFF9-25556B57FE6D"];
self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:#"digiConsRegion"];
[self.locationManager startMonitoringForRegion:self.beaconRegion];
}
- (void)stopBeaconManager {
[self.locationManager stopMonitoringForRegion:self.beaconRegion];
}
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
NSLog(#"Started looking for regions");
[self.locationManager requestStateForRegion:self.beaconRegion];
}
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
NSLog(#"Region discovered");
if (firstRegionEntered) {
NSLog(#"First time in region");
firstRegionEntered = false;
}
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
NSLog(#"Region left");
[self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.alertBody = #"We hope you enjoyed the event, thank you for coming.";
notification.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}
- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
NSLog(#"locationManager initiated");
CLBeacon *beacon = [[CLBeacon alloc] init];
beacon = [beacons lastObject];
//Store some information about this beacon
NSNumber *currentBeaconMajor = beacon.major; //it's major (group) number
NSNumber *currentBeaconMinor = beacon.minor; //it's minor (individual) number
if (([currentBeaconMinor floatValue] == 59204) && ([currentBeaconMajor floatValue] == 33995) && (beacon.proximity == CLProximityNear)) {
NSLog(#"Mint discovered");
[[NSNotificationCenter defaultCenter] postNotificationName:#"didLocateMint" object:nil];
} else if (([currentBeaconMinor floatValue] == 7451) && ([currentBeaconMajor floatValue] == 63627) && (beacon.proximity == CLProximityNear)) {
NSLog(#"Blue discovered");
[[NSNotificationCenter defaultCenter] postNotificationName:#"didLocateBlue" object:nil];
} else if (([currentBeaconMinor floatValue] == 51657) && ([currentBeaconMajor floatValue] == 26976) && (beacon.proximity == CLProximityNear)) {
NSLog(#"Purple discovered");
[[NSNotificationCenter defaultCenter] postNotificationName:#"didLocatePurple" object:nil];
}
}
- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region {
if (testRanging) {
NSLog(#"Testing: forced ranging");
if ([region isEqual:self.beaconRegion] && state == CLRegionStateInside) {
[_locationManager startRangingBeaconsInRegion:(CLBeaconRegion *)region];
}
}
}
#end
Here's the header:
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <CoreBluetooth/CoreBluetooth.h>
#interface dcBeaconManager : NSObject <CLLocationManagerDelegate>
//properties
#property (strong, nonatomic) CLBeaconRegion *beaconRegion; //used to define which beacons we are looking for
#property (strong, nonatomic) CLLocationManager *locationManager; //set up location services and allow beacons to be found
//methods
- (void)initBeaconManager;
- (void)stopBeaconManager;
#end
Now, this code has worked fine before when included in the main view controller, but I'm trying to get better at OOP in Obj-C. The logs show the object is created and the main initBeaconManager is called, but from there is just stops. I cannot figure out why. Any thoughts?
Cheers.
I'm not sure this help but can you replace this line:
self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:#"digiConsRegion"];
with that one:
self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid major:1 minor:2 identifier:#"digiConsRegion"];
self.beaconRegion.notifyOnEntry = entry;
self.beaconRegion.notifyOnExit = exit;
self.beaconRegion.notifyEntryStateOnDisplay = YES;
I believe you need to provide major and minor values for bacon region.
I was creating my CLLocationManager in my viewDidLoad method, and ARC was killing it off almost immediately. Moving it to be a class instance instead of a method instance fixed the problem.
I'm having an issue where my app will not fire the didEnterRegion event if I start the app within the region. If I start the app outside the region and then enter the region, it fires. If I start the app inside the region, then leave the region, then re-enter the region, it fires.
Any suggestions on how to get it to fire as soon as the app is opened if it's in the region would be much appreciated!
I suggest you to use this code
[locationManager requestStateForRegion:region];
And use the delegate method didDetermineState: to check if the state is CLRegionStateInside or CLRegionStateOutside.
I don't think you can do that.
But, you can get the current location and check if it's inside the region you're specifying yourself. CLCircularRegion has a containsCoordinate: method for this.
The first conclusion is that didEnterRegion is implemented consistently with its name. :)
Implement something like this in your CLLocationManagerDelegate:
- (void) locationManager: (CLLocationManager *) manager
didStartMonitoringForRegion: (CLRegion *) region
{
if ([self insideRegion: region location: manager.location])
[self locationManager: manager
didEnterRegion: region];
}
From apple's documentation:
Monitoring of a geographical region begins immediately after
registration for authorized apps. However, don’t expect to receive an
event right away, because only boundary crossings generate an event.
In particular, if the user’s location is already inside the region
at registration time, the location manager doesn’t automatically
generate an event. Instead, your app must wait for the user to cross
the region boundary before an event is generated and sent to the
delegate. To check whether the user is already inside the boundary
of a region, use the requestStateForRegion: method of the
CLLocationManager class.
So I ended up doing this:
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic, strong) NSDictionary *regionDictionary;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// setup regions in case you have multiple regions
self.regionDictionary = #{#"com.test" : #"2FAE2A83-1634-443B-8A0C-56704F81A181"};
// setup location manager
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
if([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}
[self.locationManager startUpdatingLocation];
//start monitoring for all regions
for (NSString *key in self.regionDictionary.allKeys) {
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:self.regionDictionary[key]] identifier:key];
[self.locationManager startMonitoringForRegion:beaconRegion];
}
}
- (void)locationManager:(CLLocationManager*)manager didEnterRegion:(CLRegion *)region {
if (region.identifier.length != 0) {
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:self.regionDictionary[region.identifier]] identifier:region.identifier];
[self.locationManager startRangingBeaconsInRegion:beaconRegion];
}
}
- (void)locationManager:(CLLocationManager*)manager didExitRegion:(CLRegion *)region {
if (region.identifier.length != 0) {
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:self.regionDictionary[region.identifier]] identifier:region.identifier];
[self.locationManager stopRangingBeaconsInRegion:beaconRegion];
}
}
- (void)locationManager:(CLLocationManager*)manager didRangeBeacons:(NSArray*)beacons inRegion:(CLBeaconRegion*)region {
// Beacon found!
CLBeacon *foundBeacon = [beacons firstObject];
NSLog(#"UUID:%#; major:%#; minor:%#;", foundBeacon.proximityUUID.UUIDString, foundBeacon.major, foundBeacon.minor);
}
- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region {
if ([region isKindOfClass:[CLBeaconRegion class]] && state == CLRegionStateInside) {
[self locationManager:manager didEnterRegion:region];
}
}
- (void)locationManager:(CLLocationManager *) manager didStartMonitoringForRegion:(CLRegion *) region {
[manager requestStateForRegion:region];
}