@rodrigo7/react-native-beacons-manager 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/.flowconfig +21 -0
  2. package/.nvmrc +1 -0
  3. package/.prettierignore +4 -0
  4. package/.prettierrc +12 -0
  5. package/.vscode/settings.json +24 -0
  6. package/LICENSE +21 -0
  7. package/README.md +246 -0
  8. package/ReactNativeBeaconsManager.podspec +13 -0
  9. package/android/.project +17 -0
  10. package/android/.settings/org.eclipse.buildship.core.prefs +2 -0
  11. package/android/build.gradle +108 -0
  12. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  13. package/android/gradle/wrapper/gradle-wrapper.properties +6 -0
  14. package/android/gradle/wrapper/gradle.properties +2 -0
  15. package/android/gradlew +160 -0
  16. package/android/gradlew.bat +90 -0
  17. package/android/src/main/AndroidManifest.xml +8 -0
  18. package/android/src/main/java/com/mackentoch/beaconsandroid/BeaconsAndroidModule.java +457 -0
  19. package/android/src/main/java/com/mackentoch/beaconsandroid/BeaconsAndroidPackage.java +29 -0
  20. package/index.js +10 -0
  21. package/ios/RNiBeacon/RNiBeacon/ESSBeaconScanner.h +41 -0
  22. package/ios/RNiBeacon/RNiBeacon/ESSBeaconScanner.m +204 -0
  23. package/ios/RNiBeacon/RNiBeacon/ESSEddystone.h +117 -0
  24. package/ios/RNiBeacon/RNiBeacon/ESSEddystone.m +352 -0
  25. package/ios/RNiBeacon/RNiBeacon/ESSTimer.h +72 -0
  26. package/ios/RNiBeacon/RNiBeacon/ESSTimer.m +107 -0
  27. package/ios/RNiBeacon/RNiBeacon/RNiBeacon.h +16 -0
  28. package/ios/RNiBeacon/RNiBeacon/RNiBeacon.m +467 -0
  29. package/ios/RNiBeacon/RNiBeacon.xcodeproj/project.pbxproj +290 -0
  30. package/jsconfig.json +9 -0
  31. package/lib/next/module.types.js +169 -0
  32. package/lib/next/new.module.android.js +451 -0
  33. package/lib/next/new.module.ios.js +176 -0
  34. package/package.json +65 -0
  35. package/typings/index.d.ts +174 -0
  36. package/typings.json +7 -0
  37. package/yarn-error.log +4182 -0
@@ -0,0 +1,72 @@
1
+ // Copyright 2015 Google Inc. All rights reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #import <Foundation/Foundation.h>
16
+
17
+ @class ESSTimer;
18
+
19
+ typedef void(^ESSTimerBlock)(ESSTimer *timer);
20
+
21
+ /**
22
+ *=-----------------------------------------------------------------------------------------------=
23
+ * ESSTimer
24
+ *=-----------------------------------------------------------------------------------------------=
25
+ * A Timer class, much like NSTimer, but implemented using dispatch queues and sources.
26
+ */
27
+ @interface ESSTimer : NSObject
28
+
29
+ @property(nonatomic, copy, readonly) ESSTimerBlock block;
30
+ @property(nonatomic, strong, readonly) dispatch_queue_t queue;
31
+ @property(nonatomic, assign, readonly) NSTimeInterval delay;
32
+
33
+ - (ESSTimer *)initWithDelay:(NSTimeInterval)delay
34
+ onQueue:(dispatch_queue_t)queue
35
+ block:(ESSTimerBlock)block;
36
+
37
+ + (ESSTimer *)timerWithDelay:(NSTimeInterval)delay
38
+ onQueue:(dispatch_queue_t)queue
39
+ block:(ESSTimerBlock)block;
40
+
41
+ + (ESSTimer *)scheduledTimerWithDelay:(NSTimeInterval)delay
42
+ onQueue:(dispatch_queue_t)queue
43
+ block:(ESSTimerBlock)block;
44
+
45
+ /**
46
+ * Schedule this timer so that it will fire after the specified delay.
47
+ */
48
+ - (void)schedule;
49
+
50
+ /**
51
+ * Reschedule the timer, so it will fire after the specified delay from the current time, rather
52
+ * than from when it was initially scheduled or last rescheduled.
53
+ * This should not be called before |schedule|, though it will have no effect.
54
+ */
55
+ - (void)reschedule;
56
+
57
+ /**
58
+ * Suspend this timer, so that it will not fire unless and until it has been resumed.
59
+ */
60
+ - (void)suspend;
61
+
62
+ /**
63
+ * Resume the timer to allow it to fire.
64
+ */
65
+ - (void)resume;
66
+
67
+ /**
68
+ * Cancel the timer, preventing it from ever firing again.
69
+ */
70
+ - (void)cancel;
71
+
72
+ @end
@@ -0,0 +1,107 @@
1
+ // Copyright 2015 Google Inc. All rights reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #import "ESSTimer.h"
16
+
17
+ /**
18
+ *=-----------------------------------------------------------------------------------------------=
19
+ * Private Additions to ESSTimer
20
+ *=-----------------------------------------------------------------------------------------------=
21
+ */
22
+ @interface ESSTimer ()
23
+
24
+ @property(nonatomic, copy, readwrite) ESSTimerBlock block;
25
+ @property(nonatomic, copy, readwrite) void(^wrappedBlock)();
26
+ @property(nonatomic, strong, readwrite) dispatch_queue_t queue;
27
+ @property(nonatomic, assign, readwrite) NSTimeInterval delay;
28
+
29
+ // The dispatch source used for the timer.
30
+ @property(nonatomic, strong, readwrite) dispatch_source_t source;
31
+
32
+ @property(nonatomic, assign) BOOL suspended;
33
+
34
+ @end
35
+
36
+ /**
37
+ *=-----------------------------------------------------------------------------------------------=
38
+ * Implementation for ESSTimer
39
+ *=-----------------------------------------------------------------------------------------------=
40
+ */
41
+ @implementation ESSTimer
42
+
43
+ - (ESSTimer *)initWithDelay:(NSTimeInterval)delay
44
+ onQueue:(dispatch_queue_t)queue
45
+ block:(ESSTimerBlock)block {
46
+ self = [super init];
47
+ if (self) {
48
+ _block = block;
49
+ _queue = queue;
50
+ _delay = delay;
51
+
52
+ __block ESSTimer *blockSelf = self;
53
+
54
+ _wrappedBlock = ^{
55
+ // This is a one-shot timer - ensure we don't call its block after it has been canceled.
56
+ if (!dispatch_source_testcancel(blockSelf.source)) {
57
+ dispatch_source_cancel(blockSelf.source);
58
+ blockSelf.block(blockSelf);
59
+ }
60
+ };
61
+
62
+ _source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _queue);
63
+ }
64
+ return self;
65
+ }
66
+
67
+ + (ESSTimer *)timerWithDelay:(NSTimeInterval)delay
68
+ onQueue:(dispatch_queue_t)queue
69
+ block:(ESSTimerBlock)block {
70
+ return [[self alloc] initWithDelay:delay onQueue:queue block:block];
71
+
72
+ }
73
+
74
+ + (ESSTimer *)scheduledTimerWithDelay:(NSTimeInterval)delay
75
+ onQueue:(dispatch_queue_t)queue
76
+ block:(ESSTimerBlock)block {
77
+ ESSTimer *timer = [self timerWithDelay:delay onQueue:queue block:block];
78
+ [timer schedule];
79
+ return timer;
80
+ }
81
+
82
+ - (void)schedule {
83
+ [self reschedule];
84
+ dispatch_source_set_event_handler(_source, _wrappedBlock);
85
+ dispatch_resume(_source);
86
+ }
87
+
88
+ - (void)reschedule {
89
+ dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_delay * NSEC_PER_SEC));
90
+ // Leeway is 10% of timer delay
91
+ dispatch_source_set_timer(_source, start, DISPATCH_TIME_FOREVER,
92
+ (uint64_t)(_delay / 10) * NSEC_PER_SEC);
93
+ }
94
+
95
+ - (void)suspend {
96
+ dispatch_suspend(_source);
97
+ }
98
+
99
+ - (void)resume {
100
+ dispatch_resume(_source);
101
+ }
102
+
103
+ - (void)cancel {
104
+ dispatch_source_cancel(_source);
105
+ }
106
+
107
+ @end
@@ -0,0 +1,16 @@
1
+ //
2
+ // RNiBeacon.h
3
+ // RNiBeacon
4
+ //
5
+ // Created by MacKentoch on 17/02/2017.
6
+ // Copyright © 2017 Erwan DATIN. All rights reserved.
7
+ //
8
+
9
+ #import <Foundation/Foundation.h>
10
+
11
+ #import <React/RCTBridgeModule.h>
12
+ #import <React/RCTEventEmitter.h>
13
+
14
+ @interface RNiBeacon : RCTEventEmitter <RCTBridgeModule>
15
+
16
+ @end
@@ -0,0 +1,467 @@
1
+ //
2
+ // RNiBeacon.m
3
+ // RNiBeacon
4
+ //
5
+ // Created by MacKentoch on 17/02/2017.
6
+ // Copyright © 2017 Erwan DATIN. All rights reserved.
7
+ //
8
+
9
+ #import <CoreLocation/CoreLocation.h>
10
+
11
+ #import <React/RCTBridge.h>
12
+ #import <React/RCTConvert.h>
13
+ #import <React/RCTEventDispatcher.h>
14
+ #import "ESSBeaconScanner.h"
15
+ #import "ESSEddystone.h"
16
+
17
+ #import "RNiBeacon.h"
18
+
19
+ static NSString *const kEddystoneRegionID = @"EDDY_STONE_REGION_ID";
20
+ bool hasListeners = NO;
21
+
22
+ @interface RNiBeacon() <CLLocationManagerDelegate, ESSBeaconScannerDelegate>
23
+
24
+ @property (strong, nonatomic) CLLocationManager *locationManager;
25
+ @property (strong, nonatomic) ESSBeaconScanner *eddyStoneScanner;
26
+ @property (assign, nonatomic) BOOL dropEmptyRanges;
27
+
28
+ @end
29
+
30
+ @implementation RNiBeacon
31
+
32
+ // Will be called when this module's first listener is added.
33
+ - (void)startObserving {
34
+ hasListeners = YES;
35
+ }
36
+ // Will be called when this module's last listener is removed, or on dealloc.
37
+ - (void)stopObserving {
38
+ hasListeners = NO;
39
+ }
40
+
41
+ RCT_EXPORT_MODULE()
42
+
43
+ #pragma mark Initialization
44
+
45
+ - (instancetype)init
46
+ {
47
+ if (self = [super init]) {
48
+ self.locationManager = [[CLLocationManager alloc] init];
49
+
50
+ self.locationManager.delegate = self;
51
+ self.locationManager.pausesLocationUpdatesAutomatically = NO;
52
+ self.dropEmptyRanges = NO;
53
+
54
+ self.eddyStoneScanner = [[ESSBeaconScanner alloc] init];
55
+ self.eddyStoneScanner.delegate = self;
56
+ }
57
+
58
+ return self;
59
+ }
60
+
61
+ - (NSArray<NSString *> *)supportedEvents
62
+ {
63
+ return @[
64
+ @"authorizationStatusDidChange",
65
+ @"beaconsDidRange",
66
+ @"regionDidEnter",
67
+ @"regionDidExit",
68
+ @"didDetermineState"
69
+ ];
70
+ }
71
+
72
+ #pragma mark
73
+
74
+ -(CLBeaconRegion *) createBeaconRegion: (NSString *) identifier
75
+ uuid: (NSString *) uuid
76
+ major: (NSInteger) major
77
+ minor:(NSInteger) minor
78
+ {
79
+ NSUUID *beaconUUID = [[NSUUID alloc] initWithUUIDString:uuid];
80
+
81
+ unsigned short mj = (unsigned short) major;
82
+ unsigned short mi = (unsigned short) minor;
83
+
84
+ CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:beaconUUID major:mj
85
+ minor:mi
86
+ identifier:identifier];
87
+
88
+ NSLog(@"createBeaconRegion with: identifier - uuid - major - minor");
89
+ beaconRegion.notifyOnEntry = YES;
90
+ beaconRegion.notifyOnExit = YES;
91
+ beaconRegion.notifyEntryStateOnDisplay = YES;
92
+
93
+ return beaconRegion;
94
+ }
95
+
96
+ -(CLBeaconRegion *) createBeaconRegion: (NSString *) identifier
97
+ uuid: (NSString *) uuid
98
+ major: (NSInteger) major
99
+ {
100
+ NSUUID *beaconUUID = [[NSUUID alloc] initWithUUIDString:uuid];
101
+
102
+ unsigned short mj = (unsigned short) major;
103
+
104
+ CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:beaconUUID
105
+ major:mj
106
+ identifier:identifier];
107
+
108
+ NSLog(@"createBeaconRegion with: identifier - uuid - major");
109
+ beaconRegion.notifyOnEntry = YES;
110
+ beaconRegion.notifyOnExit = YES;
111
+ beaconRegion.notifyEntryStateOnDisplay = YES;
112
+
113
+ return beaconRegion;
114
+ }
115
+
116
+ -(CLBeaconRegion *) createBeaconRegion: (NSString *) identifier
117
+ uuid: (NSString *) uuid
118
+ {
119
+ NSUUID *beaconUUID = [[NSUUID alloc] initWithUUIDString:uuid];
120
+
121
+ CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:beaconUUID
122
+ identifier:identifier];
123
+
124
+ NSLog(@"createBeaconRegion with: identifier - uuid");
125
+ beaconRegion.notifyOnEntry = YES;
126
+ beaconRegion.notifyOnExit = YES;
127
+ beaconRegion.notifyEntryStateOnDisplay = YES;
128
+
129
+ return beaconRegion;
130
+ }
131
+
132
+ -(CLBeaconRegion *) convertDictToBeaconRegion: (NSDictionary *) dict
133
+ {
134
+ if (dict[@"minor"] == nil) {
135
+ if (dict[@"major"] == nil) {
136
+ return [self createBeaconRegion:[RCTConvert NSString:dict[@"identifier"]]
137
+ uuid:[RCTConvert NSString:dict[@"uuid"]]];
138
+ } else {
139
+ return [self createBeaconRegion:[RCTConvert NSString:dict[@"identifier"]]
140
+ uuid:[RCTConvert NSString:dict[@"uuid"]]
141
+ major:[RCTConvert NSInteger:dict[@"major"]]];
142
+ }
143
+ } else {
144
+ return [self createBeaconRegion:[RCTConvert NSString:dict[@"identifier"]]
145
+ uuid:[RCTConvert NSString:dict[@"uuid"]]
146
+ major:[RCTConvert NSInteger:dict[@"major"]]
147
+ minor:[RCTConvert NSInteger:dict[@"minor"]]];
148
+ }
149
+ }
150
+
151
+ -(NSDictionary *) convertBeaconRegionToDict: (CLBeaconRegion *) region
152
+ {
153
+ if (region.minor == nil) {
154
+ if (region.major == nil) {
155
+ return @{
156
+ @"identifier": region.identifier,
157
+ @"uuid": [region.proximityUUID UUIDString],
158
+ };
159
+ } else {
160
+ return @{
161
+ @"identifier": region.identifier,
162
+ @"uuid": [region.proximityUUID UUIDString],
163
+ @"major": region.major
164
+ };
165
+ }
166
+ } else {
167
+ return @{
168
+ @"identifier": region.identifier,
169
+ @"uuid": [region.proximityUUID UUIDString],
170
+ @"major": region.major,
171
+ @"minor": region.minor
172
+ };
173
+ }
174
+ }
175
+
176
+ -(NSString *)stringForProximity:(CLProximity)proximity {
177
+ switch (proximity) {
178
+ case CLProximityUnknown: return @"unknown";
179
+ case CLProximityFar: return @"far";
180
+ case CLProximityNear: return @"near";
181
+ case CLProximityImmediate: return @"immediate";
182
+ default: return @"";
183
+ }
184
+ }
185
+
186
+ RCT_EXPORT_METHOD(requestAlwaysAuthorization)
187
+ {
188
+ if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
189
+ [self.locationManager requestAlwaysAuthorization];
190
+ }
191
+ }
192
+
193
+ RCT_EXPORT_METHOD(requestWhenInUseAuthorization)
194
+ {
195
+ if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
196
+ [self.locationManager requestWhenInUseAuthorization];
197
+ }
198
+ }
199
+
200
+ RCT_EXPORT_METHOD(allowsBackgroundLocationUpdates:(BOOL)allow)
201
+ {
202
+ self.locationManager.allowsBackgroundLocationUpdates = allow;
203
+ }
204
+
205
+ RCT_EXPORT_METHOD(getAuthorizationStatus:(RCTResponseSenderBlock)callback)
206
+ {
207
+ callback(@[[self nameForAuthorizationStatus:[CLLocationManager authorizationStatus]]]);
208
+ }
209
+
210
+ RCT_EXPORT_METHOD(getMonitoredRegions:(RCTResponseSenderBlock)callback)
211
+ {
212
+ NSMutableArray *regionArray = [[NSMutableArray alloc] init];
213
+
214
+ for (CLBeaconRegion *region in self.locationManager.monitoredRegions) {
215
+ [regionArray addObject: [self convertBeaconRegionToDict: region]];
216
+ }
217
+
218
+ callback(@[regionArray]);
219
+ }
220
+
221
+ RCT_EXPORT_METHOD(startMonitoringForRegion:(NSDictionary *) dict)
222
+ {
223
+ [self.locationManager startMonitoringForRegion:[self convertDictToBeaconRegion:dict]];
224
+ }
225
+
226
+ RCT_EXPORT_METHOD(startRangingBeaconsInRegion:(NSDictionary *) dict)
227
+ {
228
+ if ([dict[@"identifier"] isEqualToString:kEddystoneRegionID]) {
229
+ [_eddyStoneScanner startScanning];
230
+ } else {
231
+ [self.locationManager startRangingBeaconsInRegion:[self convertDictToBeaconRegion:dict]];
232
+ }
233
+ }
234
+
235
+ RCT_EXPORT_METHOD(stopMonitoringForRegion:(NSDictionary *) dict)
236
+ {
237
+ [self.locationManager stopMonitoringForRegion:[self convertDictToBeaconRegion:dict]];
238
+ }
239
+
240
+ RCT_EXPORT_METHOD(stopRangingBeaconsInRegion:(NSDictionary *) dict)
241
+ {
242
+ if ([dict[@"identifier"] isEqualToString:kEddystoneRegionID]) {
243
+ [self.eddyStoneScanner stopScanning];
244
+ } else {
245
+ [self.locationManager stopRangingBeaconsInRegion:[self convertDictToBeaconRegion:dict]];
246
+ }
247
+ }
248
+
249
+ RCT_EXPORT_METHOD(requestStateForRegion:(NSDictionary *)dict)
250
+ {
251
+ if ([self.locationManager respondsToSelector:@selector(requestStateForRegion:)]) {
252
+ [self.locationManager requestStateForRegion:[self convertDictToBeaconRegion:dict]];
253
+ }
254
+ }
255
+
256
+ RCT_EXPORT_METHOD(startUpdatingLocation)
257
+ {
258
+ [self.locationManager startUpdatingLocation];
259
+ }
260
+
261
+ RCT_EXPORT_METHOD(stopUpdatingLocation)
262
+ {
263
+ [self.locationManager stopUpdatingLocation];
264
+ }
265
+
266
+ RCT_EXPORT_METHOD(shouldDropEmptyRanges:(BOOL)drop)
267
+ {
268
+ self.dropEmptyRanges = drop;
269
+ }
270
+
271
+ -(NSString *)nameForAuthorizationStatus:(CLAuthorizationStatus)authorizationStatus
272
+ {
273
+ switch (authorizationStatus) {
274
+ case kCLAuthorizationStatusAuthorizedAlways:
275
+ return @"authorizedAlways";
276
+
277
+ case kCLAuthorizationStatusAuthorizedWhenInUse:
278
+ return @"authorizedWhenInUse";
279
+
280
+ case kCLAuthorizationStatusDenied:
281
+ return @"denied";
282
+
283
+ case kCLAuthorizationStatusNotDetermined:
284
+ return @"notDetermined";
285
+
286
+ case kCLAuthorizationStatusRestricted:
287
+ return @"restricted";
288
+ }
289
+ }
290
+
291
+ -(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
292
+ {
293
+ NSString *statusName = [self nameForAuthorizationStatus:status];
294
+ if (self.bridge && hasListeners) {
295
+ [self sendEventWithName:@"authorizationStatusDidChange" body:statusName];
296
+ }
297
+ }
298
+
299
+ -(void)locationManager:(CLLocationManager *)manager rangingBeaconsDidFailForRegion:(CLBeaconRegion *)region withError:(NSError *)error
300
+ {
301
+ NSLog(@"Failed ranging region: %@", error);
302
+ }
303
+
304
+ -(void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error {
305
+ NSLog(@"Failed monitoring region: %@", error);
306
+ }
307
+
308
+ -(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
309
+ NSLog(@"Location manager failed: %@", error);
310
+ }
311
+
312
+ -(NSString *)stringForState:(CLRegionState)state {
313
+ switch (state) {
314
+ case CLRegionStateInside: return @"inside";
315
+ case CLRegionStateOutside: return @"outside";
316
+ case CLRegionStateUnknown: return @"unknown";
317
+ default: return @"unknown";
318
+ }
319
+ }
320
+
321
+ - (void) locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
322
+ {
323
+ NSDictionary *event = @{
324
+ @"state": [self stringForState:state],
325
+ @"identifier": region.identifier,
326
+ };
327
+ if (self.bridge && hasListeners) {
328
+ [self sendEventWithName:@"didDetermineState" body:event];
329
+ }
330
+ }
331
+
332
+ -(void) locationManager:(CLLocationManager *)manager didRangeBeacons:
333
+ (NSArray *)beacons inRegion:(CLBeaconRegion *)region
334
+ {
335
+ if (self.dropEmptyRanges && beacons.count == 0) {
336
+ return;
337
+ }
338
+ NSMutableArray *beaconArray = [[NSMutableArray alloc] init];
339
+
340
+ for (CLBeacon *beacon in beacons) {
341
+ [beaconArray addObject:@{
342
+ @"uuid": [beacon.proximityUUID UUIDString],
343
+ @"major": beacon.major,
344
+ @"minor": beacon.minor,
345
+
346
+ @"rssi": [NSNumber numberWithLong:beacon.rssi],
347
+ @"proximity": [self stringForProximity: beacon.proximity],
348
+ @"accuracy": [NSNumber numberWithDouble: beacon.accuracy],
349
+ @"distance": [NSNumber numberWithDouble: beacon.accuracy],
350
+ }];
351
+ }
352
+
353
+ NSDictionary *event = @{
354
+ @"region": @{
355
+ @"identifier": region.identifier,
356
+ @"uuid": [region.proximityUUID UUIDString],
357
+ },
358
+ @"beacons": beaconArray
359
+ };
360
+
361
+ if (self.bridge && hasListeners) {
362
+ [self sendEventWithName:@"beaconsDidRange" body:event];
363
+ }
364
+ }
365
+
366
+ -(void)locationManager:(CLLocationManager *)manager
367
+ didEnterRegion:(CLBeaconRegion *)region {
368
+
369
+ if (! [region respondsToSelector:@selector(proximityUUID)]) {
370
+ return;
371
+ }
372
+
373
+ NSDictionary *event = [self convertBeaconRegionToDict: region];
374
+
375
+ if (self.bridge && hasListeners) {
376
+ [self sendEventWithName:@"regionDidEnter" body:event];
377
+ }
378
+ }
379
+
380
+ -(void)locationManager:(CLLocationManager *)manager
381
+ didExitRegion:(CLBeaconRegion *)region {
382
+
383
+ if (! [region respondsToSelector:@selector(proximityUUID)]) {
384
+ return;
385
+ }
386
+
387
+ NSDictionary *event = [self convertBeaconRegionToDict: region];
388
+
389
+ if (self.bridge && hasListeners) {
390
+ [self sendEventWithName:@"regionDidExit" body:event];
391
+ }
392
+ }
393
+
394
+ + (BOOL)requiresMainQueueSetup
395
+ {
396
+ return YES;
397
+ }
398
+
399
+ - (void)beaconScanner:(ESSBeaconScanner *)scanner didRangeBeacon:(NSArray *)beacons {
400
+ [self notifyAboutBeaconChanges:beacons];
401
+ }
402
+
403
+ - (void)notifyAboutBeaconChanges:(NSArray *)beacons {
404
+ NSMutableArray *beaconArray = [[NSMutableArray alloc] init];
405
+
406
+ for (id key in beacons) {
407
+ ESSBeaconInfo *beacon = key;
408
+ NSDictionary *info = [self getEddyStoneInfo:beacon];
409
+ [beaconArray addObject:info];
410
+ }
411
+ NSDictionary *event = @{
412
+ @"region": @{
413
+ @"identifier": kEddystoneRegionID,
414
+ @"uuid": @"", // do not use for eddy stone
415
+ },
416
+ @"beacons": beaconArray
417
+ };
418
+ if (self.bridge && hasListeners) {
419
+ [self sendEventWithName:@"beaconsDidRange" body:event];
420
+ }
421
+ }
422
+
423
+ - (NSDictionary*)getEddyStoneInfo:(id)beaconInfo {
424
+ ESSBeaconInfo *info = beaconInfo;
425
+ NSNumber *distance = [self calculateDistance:info.txPower rssi:info.RSSI];
426
+ NSString *identifier = [self getEddyStoneUUID:info.beaconID.beaconID];
427
+ NSDictionary *beaconData = @{
428
+ @"identifier": identifier,
429
+ @"uuid": identifier,
430
+ @"rssi": info.RSSI,
431
+ @"txPower": info.txPower,
432
+ @"distance": distance,
433
+ };
434
+ return beaconData;
435
+ }
436
+
437
+ - (NSNumber*)calculateDistance:(NSNumber*)txPower rssi:(NSNumber*) rssi {
438
+ if ([rssi floatValue] >= 0){
439
+ return [NSNumber numberWithInt:-1];
440
+ }
441
+
442
+ float ratio = [rssi floatValue] / ([txPower floatValue] - 41);
443
+ if (ratio < 1.0) {
444
+ return [NSNumber numberWithFloat:pow(ratio, 10)];
445
+ }
446
+
447
+ float distance = (0.89976) * pow(ratio, 7.7095) + 0.111;
448
+ return [NSNumber numberWithFloat:distance];
449
+ }
450
+
451
+ - (NSString *)getEddyStoneUUID:(NSData*)data {
452
+ const unsigned char *dataBuffer = (const unsigned char *)[data bytes];
453
+ const int EDDYSTONE_UUID_LENGTH = 10;
454
+ if (!dataBuffer) {
455
+ return [NSString string];
456
+ }
457
+
458
+ NSMutableString *hexString = [NSMutableString stringWithCapacity:(data.length * 2)];
459
+ [hexString appendString:@"0x"];
460
+ for (int i = 0; i < EDDYSTONE_UUID_LENGTH; ++i) {
461
+ [hexString appendString:[NSString stringWithFormat:@"%02lx", (unsigned long)dataBuffer[i]]];
462
+ }
463
+
464
+ return [NSString stringWithString:hexString];
465
+ }
466
+
467
+ @end