Skip to content

Commit e6a618a

Browse files
committed
add monitoring.ios md and js
1 parent de08141 commit e6a618a

4 files changed

Lines changed: 273 additions & 7 deletions

File tree

examples/samples/monitoring.ios.js

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
2+
import Beacons from 'react-native-beacons-manager';
3+
import moment from 'moment';
4+
5+
const TIME_FORMAT = 'MM/DD/YYYY hh:mm:ss';
6+
7+
class beaconMonitoringOnly extends Component {
8+
constructor(props) {
9+
super(props);
10+
11+
this.state = {
12+
// region information
13+
uuid: '7b44b47b-52a1-5381-90c2-f09b6838c5d4',
14+
identifier: 'some id',
15+
16+
regionEnterDatasource: new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}).cloneWithRows([]),
17+
regionExitDatasource: new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}).cloneWithRows([])
18+
};
19+
}
20+
21+
componentWillMount(){
22+
const { identifier, uuid } = this.state;
23+
//
24+
// ONLY non component state aware here in componentWillMount
25+
//
26+
27+
// OPTIONAL: listen to authorization change
28+
DeviceEventEmitter.addListener(
29+
'authorizationStatusDidChange',
30+
(info) => console.log('authorizationStatusDidChange: ', info)
31+
);
32+
33+
// MANDATORY: you have to request ALWAYS Authorization (not only when in use) when monitoring
34+
// you also have to add "Privacy - Location Always Usage Description" in your "Info.plist" file
35+
// otherwise monitoring won't work
36+
Beacons.requestAlwaysAuthorization();
37+
38+
// Define a region which can be identifier + uuid,
39+
// identifier + uuid + major or identifier + uuid + major + minor
40+
// (minor and major properties are numbers)
41+
const region = { identifier, uuid };
42+
// Range for beacons inside the region
43+
Beacons.startMonitoringForRegion(region);
44+
// update location to ba able to monitor:
45+
Beacons.startUpdatingLocation();
46+
}
47+
48+
componentDidMount() {
49+
//
50+
// component state aware here - attach events
51+
//
52+
53+
// monitoring:
54+
DeviceEventEmitter.addListener(
55+
'regionDidEnter',
56+
(data) => {
57+
console.log('monitoring - regionDidEnter data: ', data);
58+
const time = moment().format(TIME_FORMAT);
59+
this.setState({ regionEnterDatasource: this.state.rangingDataSource.cloneWithRows([{ identifier:data.identifier, uuid:data.uuid, minor:data.minor, major:data.major, time }]) });
60+
}
61+
);
62+
63+
DeviceEventEmitter.addListener(
64+
'regionDidExit',
65+
({ identifier, uuid, minor, major }) => {
66+
console.log('monitoring - regionDidExit data: ', { identifier, uuid, minor, major });
67+
const time = moment().format(TIME_FORMAT);
68+
this.setState({ regionExitDatasource: this.state.rangingDataSource.cloneWithRows([{ identifier, uuid, minor, major, time }]) });
69+
}
70+
);
71+
}
72+
73+
componentWillUnMount() {
74+
// stop monitoring beacons:
75+
Beacons.stopMonitoringForRegion();
76+
// stop updating locationManager:
77+
Beacons.stopUpdatingLocation();
78+
// remove all listeners in a row
79+
DeviceEventEmitter.remove();
80+
}
81+
82+
render() {
83+
const { bluetoothState, regionEnterDatasource, regionExitDatasource } = this.state;
84+
85+
return (
86+
<View style={styles.container}>
87+
<Text style={styles.headline}>
88+
monitoring enter information:
89+
</Text>
90+
<ListView
91+
dataSource={ regionEnterDatasource }
92+
enableEmptySections={ true }
93+
renderRow={this.renderMonitoringEnterRow}
94+
/>
95+
96+
<Text style={styles.headline}>
97+
monitoring exit information:
98+
</Text>
99+
<ListView
100+
dataSource={ regionExitDatasource }
101+
enableEmptySections={ true }
102+
renderRow={this.renderMonitoringLeaveRow}
103+
/>
104+
</View>
105+
);
106+
}
107+
108+
renderMonitoringEnterRow = ({ identifier, uuid, minor, major, time }) => {
109+
return (
110+
<View style={styles.row}>
111+
<Text style={styles.smallText}>
112+
Identifier: {identifier ? identifier : 'NA'}
113+
</Text>
114+
<Text style={styles.smallText}>
115+
UUID: {uuid ? uuid : 'NA'}
116+
</Text>
117+
<Text style={styles.smallText}>
118+
Major: {major ? major : ''}
119+
</Text>
120+
<Text style={styles.smallText}>
121+
Minor: { minor ? minor : ''}
122+
</Text>
123+
<Text style={styles.smallText}>
124+
time: { time ? time : 'NA'}
125+
</Text>
126+
</View>
127+
);
128+
}
129+
130+
renderMonitoringLeaveRow = ({ identifier, uuid, minor, major, time }) => {
131+
return (
132+
<View style={styles.row}>
133+
<Text style={styles.smallText}>
134+
Identifier: {identifier ? identifier : 'NA'}
135+
</Text>
136+
<Text style={styles.smallText}>
137+
UUID: {uuid ? uuid : 'NA'}
138+
</Text>
139+
<Text style={styles.smallText}>
140+
Major: {major ? major : ''}
141+
</Text>
142+
<Text style={styles.smallText}>
143+
Minor: { minor ? minor : ''}
144+
</Text>
145+
<Text style={styles.smallText}>
146+
time: { time ? time : 'NA'}
147+
</Text>
148+
</View>
149+
);
150+
}
151+
}

examples/samples/monitoring.ios.md

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# Fully detailed documentation for "monitoring beacons in iOS"
2+
3+
This documentation give a deeper explanation on how to monitor (*but monitoring only*) beacons in iOS.
4+
5+
This documentation is linked to the sample code [monitoring.ios.js](./monitoring.ios.js)
6+
7+
## 1- request authorization
8+
9+
When dealing with Beacons, you technically deal with native location ([see Apple documentation](https://developer.apple.com/reference/corelocation/cllocationmanager)).
10+
11+
Before starting ranging, iOS force you to ask for authorization in case of location services.
12+
13+
If you don't:
14+
- it won't generate an error
15+
- but nothing will happen until you have authorization
16+
17+
18+
> For monitoring you don't have the choice you have to request `Always` authorization wether you need background mode or not.
19+
20+
[See matching lines in sample example]()
21+
22+
### 1 `Beacons.requestAlwaysAuthorization();` (**background and foreground use-case**)
23+
24+
#### in your react native application
25+
Ensure to call
26+
27+
```javascript
28+
Beacons.requestAlwaysAuthorization();
29+
```
30+
31+
#### in your iOS project
32+
33+
To be effective your `info.plist` file should have `Privacy - Location Always Usage Description` key defined (*empty value or not. It is better to define a value to a custom / more user-friendly message*).
34+
35+
*You have to manually `add it` to your `info.plist`:*
36+
37+
![ios: request when in use authorization](../../images/plistRequireAlwaysUseAutorization.png)
38+
39+
## 2- start monitoring
40+
41+
Tell iOS what you want to range by defining a desired `region` object.
42+
43+
44+
```javascript
45+
// Define a region which can be identifier + uuid,
46+
// identifier + uuid + major or identifier + uuid + major + minor
47+
// (minor and major properties are numbers)
48+
const region = { identifier, uuid };
49+
50+
// Range for beacons inside the region
51+
Beacons.startMonitoringForRegion(region);
52+
```
53+
54+
## 3- get the position of the device
55+
56+
Monitoring needs you to get position of the device.
57+
58+
Just call:
59+
```javascript
60+
Beacons.startUpdatingLocation();
61+
```
62+
63+
[See matching lines in sample example]()
64+
65+
## 4- register events
66+
67+
Ranging now works.
68+
69+
You have to register events to know and use about data from enter region and leave region events.
70+
71+
```javascript
72+
73+
// Monitoring: Listen for device entering the defined region
74+
DeviceEventEmitter.addListener(
75+
'regionDidEnter',
76+
(data) => {
77+
console.log('monitoring - regionDidEnter data: ', data);
78+
const time = moment().format(TIME_FORMAT);
79+
this.setState({ regionEnterDatasource: this.state.rangingDataSource.cloneWithRows([{ identifier:data.identifier, uuid:data.uuid, minor:data.minor, major:data.major, time }]) });
80+
}
81+
);
82+
83+
// Monitoring: Listen for device leaving the defined region
84+
DeviceEventEmitter.addListener(
85+
'regionDidExit',
86+
({ identifier, uuid, minor, major }) => {
87+
console.log('monitoring - regionDidExit data: ', { identifier, uuid, minor, major });
88+
const time = moment().format(TIME_FORMAT);
89+
this.setState({ regionExitDatasource: this.state.rangingDataSource.cloneWithRows([{ identifier, uuid, minor, major, time }]) });
90+
}
91+
);
92+
```
93+
94+
**IMPORTANT:**
95+
- **`regionDidExit` will trigger `ONLY after` a timeout of `30 seconds` when having left region (= beacons no more detected)**
96+
97+
- **if you start the monotoring when already in region, `regionDidEnter` will not trigger first time. (leave region and wait at least 30 seconds then enter again the region)**
98+
99+
100+
[See matching lines in sample example]()
101+
102+
103+
## 5- on componentWillUnMount: unregister events and stop monitoring
104+
105+
A good practise is to ALWAYS unregister events in `componentWillUnMount`.
106+
107+
Tell iOS to stop ranging at the same time.
108+
109+
```javascript
110+
// stop monitoring beacons:
111+
Beacons.stopMonitoringForRegion();
112+
// stop updating locationManager:
113+
Beacons.stopUpdatingLocation();
114+
// remove all listeners in a row
115+
DeviceEventEmitter.remove();
116+
```
117+
118+
[See matching lines in sample example]()

examples/samples/ranging.ios.js

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import moment from 'moment';
44

55
const TIME_FORMAT = 'MM/DD/YYYY hh:mm:ss';
66

7-
class debugBeacon1 extends Component {
7+
class beaconRangingOnly extends Component {
88
constructor(props) {
99
super(props);
1010

@@ -33,16 +33,10 @@ class debugBeacon1 extends Component {
3333
// -> this is the authorization set by default by react-native init in the info.plist file
3434
// RANGING ONLY (this is not enough to make MONITORING working)
3535
Beacons.requestWhenInUseAuthorization();
36-
37-
// Always authorization request if whne in use is not enough for your needs:
38-
// Beacons.requestAlwaysAuthorization();
39-
40-
4136
// Define a region which can be identifier + uuid,
4237
// identifier + uuid + major or identifier + uuid + major + minor
4338
// (minor and major properties are numbers)
4439
const region = { identifier, uuid };
45-
4640
// Range for beacons inside the region
4741
Beacons.startRangingBeaconsInRegion(region);
4842
}

examples/samples/ranging.ios.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ DeviceEventEmitter.addListener(
9393
```
9494
9595
Note: beacons is an array of object:
96+
```javascript
97+
9698
{
9799
uuid,
98100
major,
@@ -101,6 +103,7 @@ Note: beacons is an array of object:
101103
proximity,
102104
accuracy,
103105
}
106+
```
104107
105108
[See matching lines in sample example](https://github.com/MacKentoch/react-native-beacons-manager/blob/master/examples/samples/ranging.ios.js#L55)
106109

0 commit comments

Comments
 (0)