Browse Source

Merge branch '2.0.0' of github.com:yonahforst/react-native-permissions into 2.0.0

Mathieu Acthernoene 6 years ago
parent
commit
965042812d
1 changed files with 261 additions and 237 deletions
  1. 261
    237
      README.md

+ 261
- 237
README.md View File

6
 ![MIT](https://img.shields.io/dub/l/vibe-d.svg)
6
 ![MIT](https://img.shields.io/dub/l/vibe-d.svg)
7
 [![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
7
 [![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
8
 
8
 
9
-Request user permissions from React Native, iOS + Android
9
+Request user permissions on iOS and Android.
10
 
10
 
11
-| Version | React Native Support |
12
-| ------- | -------------------- |
13
-| 1.1.1   | 0.40 - 0.52          |
14
-| 0.2.5   | 0.33 - 0.39          |
15
-
16
-_Complies with
17
-[react-native-version-support-table](https://github.com/dangnelson/react-native-version-support-table)_
11
+### ⚠️  Branch WIP 2.0.0 : Go to [pull request #291](https://github.com/yonahforst/react-native-permissions/pull/291) for feedbacks.
18
 
12
 
19
-## ⚠️ Breaking changes in version 1.0.0
13
+## Support
20
 
14
 
21
-- Now using React Native's own JS `PermissionsAndroid` module on Android, which
22
-  is great because we no longer have to do any additional linking on Android
23
-- Updated API to be closer to React Native's `PermissionsAndroid`
24
-- Removed `openSettings()` support on Android (to stay linking-free). There are
25
-  several NPM modules available for this
26
-- `restricted` status now supported on Android, although it means something
27
-  different than iOS
15
+| version | react-native version |
16
+| ------- | -------------------- |
17
+| 2.0.0+  | 0.56.0+              |
18
+| 1.1.1   | 0.40.0 - 0.52.2      |
28
 
19
 
29
 ## Setup
20
 ## Setup
30
 
21
 
31
-```sh
32
-npm install --save react-native-permissions
22
+```bash
23
+$ npm install --save react-native-permissions
33
 # --- or ---
24
 # --- or ---
34
-yarn add react-native-permissions
25
+$ yarn add react-native-permissions
35
 ```
26
 ```
36
 
27
 
37
-_📌 Don't forget to add permissions to `AndroidManifest.xml` for android and
38
-`Info.plist` for iOS (Xcode >= 8). See [iOS Notes](#ios-notes) or [Android Notes](#android-notes) for more details._
39
-
40
-### Additional iOS setup
41
-
42
-#### Using cocoaPods
28
+### iOS specific
43
 
29
 
44
-Update the following line with your path to `node_modules/` and add it to your
45
-podfile:
30
+To allow installation of the needed permission handlers for your project (and only them), `react-native-permissions` uses CocoaPods. Update the following line with your path to `node_modules/` and add it to your podfile:
46
 
31
 
47
 ```ruby
32
 ```ruby
48
-pod 'ReactNativePermissions', :path => '../node_modules/react-native-permissions'
33
+target 'YourAwesomeProject' do
34
+
35
+  # …
36
+
37
+  pod 'RNPermissions', :path => '../node_modules/react-native-permissions', :subspecs => [
38
+    'Core',
39
+    ## Uncomment needed permissions
40
+    # 'BluetoothPeripheral',
41
+    # 'Calendars',
42
+    # 'Camera',
43
+    # 'Contacts',
44
+    # 'FaceID',
45
+    # 'LocationAlways',
46
+    # 'LocationWhenInUse',
47
+    # 'MediaLibrary',
48
+    # 'Microphone',
49
+    # 'Motion',
50
+    # 'Notifications',
51
+    # 'PhotoLibrary',
52
+    # 'Reminders',
53
+    # 'Siri',
54
+    # 'SpeechRecognition',
55
+    # 'StoreKit',
56
+  ]
57
+
58
+end
49
 ```
59
 ```
50
 
60
 
51
-#### Using react-native link
61
+### Android specific
52
 
62
 
53
-```sh
54
-react-native link react-native-permissions
55
-```
63
+1.  Add the following lines to `android/settings.gradle`:
56
 
64
 
57
-#### Using manual linking
65
+```gradle
66
+include ':react-native-permissions'
67
+project(':react-native-permissions').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-permissions/android')
68
+```
58
 
69
 
59
-1. In the XCode's "Project navigator", right click on your project's Libraries
60
-   folder ➜ `Add Files to <...>`
61
-2. Go to `node_modules` ➜ `react-native-permissions` ➜ select
62
-   `ReactNativePermissions.xcodeproj`
63
-3. Add `libReactNativePermissions.a` to `Build Phases` -> `Link Binary With Libraries`
70
+2.  Add the compile line to the dependencies in `android/app/build.gradle`:
64
 
71
 
65
-## Using
72
+```gradle
73
+dependencies {
74
+  // ...
75
+  implementation project(':react-native-permissions')
76
+}
77
+```
66
 
78
 
67
-```js
68
-import Permissions from "react-native-permissions";
69
-// OR const Permissions = require('react-native-permissions').default
70
-// if you use CommonJS module system
79
+3.  Add the import and link the package in `MainApplication.java`:
71
 
80
 
72
-//...
81
+```java
82
+import com.yonahforst.rnpermissions.RNPermissionsPackage; // <-- Add the RNLocalize import
73
 
83
 
74
-export default class extends React.Component {
75
-  //...
84
+public class MainApplication extends Application implements ReactApplication {
76
 
85
 
77
-  // Check the status of a single permission
78
-  componentDidMount() {
79
-    Permissions.check("photo").then(response => {
80
-      // Response is one of: 'authorized', 'denied', 'restricted', or 'undetermined'
81
-      this.setState({ photoPermission: response });
82
-    });
83
-  }
86
+  // …
84
 
87
 
85
-  // Request permission to access photos
86
-  _requestPermission = () => {
87
-    Permissions.request("photo").then(response => {
88
-      // Returns once the user has chosen to 'allow' or to 'not allow' access
89
-      // Response is one of: 'authorized', 'denied', 'restricted', or 'undetermined'
90
-      this.setState({ photoPermission: response });
91
-    });
92
-  };
93
-
94
-  // Check the status of multiple permissions
95
-  _checkCameraAndPhotos = () => {
96
-    Permissions.checkMultiple(["camera", "photo"]).then(response => {
97
-      //response is an object mapping type to permission
98
-      this.setState({
99
-        cameraPermission: response.camera,
100
-        photoPermission: response.photo,
101
-      });
102
-    });
103
-  };
104
-
105
-  // This is a common pattern when asking for permissions.
106
-  // iOS only gives you once chance to show the permission dialog,
107
-  // after which the user needs to manually enable them from settings.
108
-  // The idea here is to explain why we need access and determine if
109
-  // the user will say no, so that we don't blow our one chance.
110
-  // If the user already denied access, we can ask them to enable it from settings.
111
-  _alertForPhotosPermission() {
112
-    Alert.alert(
113
-      "Can we access your photos?",
114
-      "We need access so you can set your profile pic",
115
-      [
116
-        {
117
-          text: "No way",
118
-          onPress: () => console.log("Permission denied"),
119
-          style: "cancel",
120
-        },
121
-        this.state.photoPermission == "undetermined"
122
-          ? { text: "OK", onPress: this._requestPermission }
123
-          : { text: "Open Settings", onPress: Permissions.openSettings },
124
-      ],
88
+  @Override
89
+  protected List<ReactPackage> getPackages() {
90
+    return Arrays.<ReactPackage>asList(
91
+      new MainReactPackage(),
92
+      // …
93
+      new RNPermissionsPackage() // <-- Add it to the packages list
125
     );
94
     );
126
   }
95
   }
127
 
96
 
128
-  //...
97
+  // …
129
 }
98
 }
130
 ```
99
 ```
131
 
100
 
132
-## API
101
+_📌 Don't forget to add permissions to `AndroidManifest.xml` for android and
102
+`Info.plist` for iOS (Xcode >= 8)._
103
+
104
+## API (subject to changes)
133
 
105
 
134
 ### Permissions statuses
106
 ### Permissions statuses
135
 
107
 
136
 Promises resolve into one of these statuses:
108
 Promises resolve into one of these statuses:
137
 
109
 
138
-| Return value   | Notes                                                                                                                                                                                                                                                                  |
139
-| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
140
-| `authorized`   | User has authorized this permission                                                                                                                                                                                                                                    |
141
-| `denied`       | User has denied this permission at least once. On iOS this means that the user will not be prompted again. Android users can be prompted multiple times until they select 'Never ask me again'                                                                         |
142
-| `restricted`   | **iOS** - this means user is not able to grant this permission, either because it's not supported by the device or because it has been blocked by parental controls. **Android** - this means that the user has selected 'Never ask me again' while denying permission |
143
-| `undetermined` | User has not yet been prompted with a permission dialog                                                                                                                                                                                                                |
144
-
145
-### Supported permissions types
146
-
147
-The current supported permissions are:
148
-
149
-|                    | Type                | iOS | Android |
150
-| ------------------ | ------------------- | --- | ------- |
151
-| Location           | `location`          | ✔️  | ✔       |
152
-| Camera             | `camera`            | ✔️  | ✔       |
153
-| Microphone         | `microphone`        | ✔️  | ✔       |
154
-| Photos             | `photo`             | ✔️  | ✔       |
155
-| Contacts           | `contacts`          | ✔️  | ✔       |
156
-| Events             | `event`             | ✔️  | ✔       |
157
-| Bluetooth          | `bluetooth`         | ✔️  | ❌      |
158
-| Reminders          | `reminder`          | ✔️  | ❌      |
159
-| Push Notifications | `notification`      | ✔️  | ❌      |
160
-| Background Refresh | `backgroundRefresh` | ✔️  | ❌      |
161
-| Speech Recognition | `speechRecognition` | ✔️  | ❌      |
162
-| Media Library      | `mediaLibrary`      | ✔️  | ❌      |
163
-| Motion Activity    | `motion`            | ✔️  | ❌      |
164
-| Storage            | `storage`           | ❌️ | ✔       |
165
-| Phone Call         | `callPhone`         | ❌️ | ✔       |
166
-| Read SMS           | `readSms`           | ❌️ | ✔       |
167
-| Receive SMS        | `receiveSms`        | ❌️ | ✔       |
110
+| Return value              | Notes                                                              |
111
+| ------------------------- | ------------------------------------------------------------------ |
112
+| `RESULTS.UNAVAILABLE`     | This feature is not available on this device.                      |
113
+| `RESULTS.GRANTED`         | The permission is granted.                                         |
114
+| `RESULTS.DENIED`          | The permission has not been requested / is denied but requestable. |
115
+| `RESULTS.NEVER_ASK_AGAIN` | The permission is not requestable anymore.                         |
116
+
117
+### Supported permissions
118
+
119
+```js
120
+import { ANDROID_PERMISSIONS, IOS_PERMISSIONS } from "react-native-permissions";
121
+
122
+// For Android
123
+
124
+// same as PermissionsAndroid
125
+ANDROID_PERMISSIONS.READ_CALENDAR;
126
+ANDROID_PERMISSIONS.WRITE_CALENDAR;
127
+ANDROID_PERMISSIONS.CAMERA;
128
+ANDROID_PERMISSIONS.READ_CONTACTS;
129
+ANDROID_PERMISSIONS.WRITE_CONTACTS;
130
+ANDROID_PERMISSIONS.GET_ACCOUNTS;
131
+ANDROID_PERMISSIONS.ACCESS_FINE_LOCATION;
132
+ANDROID_PERMISSIONS.ACCESS_COARSE_LOCATION;
133
+ANDROID_PERMISSIONS.RECORD_AUDIO;
134
+ANDROID_PERMISSIONS.READ_PHONE_STATE;
135
+ANDROID_PERMISSIONS.CALL_PHONE;
136
+ANDROID_PERMISSIONS.READ_CALL_LOG;
137
+ANDROID_PERMISSIONS.WRITE_CALL_LOG;
138
+ANDROID_PERMISSIONS.ADD_VOICEMAIL;
139
+ANDROID_PERMISSIONS.USE_SIP;
140
+ANDROID_PERMISSIONS.PROCESS_OUTGOING_CALLS;
141
+ANDROID_PERMISSIONS.BODY_SENSORS;
142
+ANDROID_PERMISSIONS.SEND_SMS;
143
+ANDROID_PERMISSIONS.RECEIVE_SMS;
144
+ANDROID_PERMISSIONS.READ_SMS;
145
+ANDROID_PERMISSIONS.RECEIVE_WAP_PUSH;
146
+ANDROID_PERMISSIONS.RECEIVE_MMS;
147
+ANDROID_PERMISSIONS.READ_EXTERNAL_STORAGE;
148
+ANDROID_PERMISSIONS.WRITE_EXTERNAL_STORAGE;
149
+
150
+// new ones
151
+ANDROID_PERMISSIONS.ANSWER_PHONE_CALLS;
152
+ANDROID_PERMISSIONS.ACCEPT_HANDOVER;
153
+ANDROID_PERMISSIONS.READ_PHONE_NUMBERS;
154
+
155
+// For iOS
156
+
157
+IOS_PERMISSIONS.BLUETOOTH_PERIPHERAL;
158
+IOS_PERMISSIONS.CALENDARS;
159
+IOS_PERMISSIONS.CAMERA;
160
+IOS_PERMISSIONS.CONTACTS;
161
+IOS_PERMISSIONS.FACE_ID;
162
+IOS_PERMISSIONS.LOCATION_ALWAYS;
163
+IOS_PERMISSIONS.LOCATION_WHEN_IN_USE;
164
+IOS_PERMISSIONS.MEDIA_LIBRARY;
165
+IOS_PERMISSIONS.MICROPHONE;
166
+IOS_PERMISSIONS.MOTION;
167
+IOS_PERMISSIONS.NOTIFICATIONS;
168
+IOS_PERMISSIONS.PHOTO_LIBRARY;
169
+IOS_PERMISSIONS.REMINDERS;
170
+IOS_PERMISSIONS.SIRI;
171
+IOS_PERMISSIONS.SPEECH_RECOGNITION;
172
+IOS_PERMISSIONS.STOREKIT;
173
+```
168
 
174
 
169
 ### Methods
175
 ### Methods
170
 
176
 
171
-| Method Name         | Arguments | Notes                                                                                                                                                                                                                                                                            |
172
-| ------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
173
-| `check()`           | `type`    | - Returns a promise with the permission status. See iOS Notes for special cases                                                                                                                                                                                                  |
174
-| `request()`         | `type`    | - Accepts any permission type except `backgroundRefresh`. If the current status is `undetermined`, shows the permission dialog and returns a promise with the resulting status. Otherwise, immediately return a promise with the current status. See iOS Notes for special cases |
175
-| `checkMultiple()`   | `[types]` | - Accepts an array of permission types and returns a promise with an object mapping permission types to statuses                                                                                                                                                                 |
176
-| `getTypes()`        | _none_    | - Returns an array of valid permission types                                                                                                                                                                                                                                     |
177
-| `openSettings()`    | _none_    | - _(iOS only - 8.0 and later)_ Switches the user to the settings page of your app                                                                                                                                                                                                |
178
-| `canOpenSettings()` | _none_    | - _(iOS only)_ Returns a boolean indicating if the device supports switching to the settings page                                                                                                                                                                                |
177
+*types used in usage examples*
178
+
179
+```ts  
180
+type Permission =
181
+  | keyof ANDROID_PERMISSIONS
182
+  | keyof IOS_PERMISSIONS
183
+
184
+type PermissionStatus =
185
+  | "granted"
186
+  | "denied"
187
+  | "never_ask_again"
188
+  | "unavailable";
189
+
190
+type NotificationOption =
191
+  | "badge"
192
+  | "sound"
193
+  | "alert"
194
+  | "carPlay"
195
+  | "criticalAlert"
196
+  | "provisional";
197
+
198
+type Rationale = {
199
+  title: string;
200
+  message: string;
201
+  buttonPositive: string;
202
+  buttonNegative?: string;
203
+  buttonNeutral?: string;
204
+};
205
+```
179
 
206
 
180
-### iOS Notes
207
+#### check()
208
+
209
+Check one permission status.
210
+
211
+#### Method type
212
+
213
+```ts
214
+function check(permission: Permission): Promise<PermissionStatus>;
215
+```
181
 
216
 
182
-- Permission type `bluetooth` represents the status of the
183
-  `CBPeripheralManager`. Don't use this if only need `CBCentralManager`
184
-- Permission type `location` accepts a second parameter for `request()` and
185
-  `check()`; the second parameter is a string, either `always` or `whenInUse`
186
-  (default).
187
-- Permission type `notification` accepts a second parameter for `request()`. The
188
-  second parameter is an array with the desired alert types. Any combination of
189
-  `alert`, `badge` and `sound` (default requests all three).
190
-- If you are not requesting mediaLibrary then you can remove MediaPlayer.framework from the xcode project
217
+#### Usage example
191
 
218
 
192
 ```js
219
 ```js
193
-// example
194
-Permissions.check("location", { type: "always" }).then(response => {
195
-  this.setState({ locationPermission: response });
220
+import { check, IOS_PERMISSIONS, RESULTS } from "react-native-permissions";
221
+
222
+check(RNPermissions.IOS_PERMISSIONS.LOCATION_ALWAYS).then(result => {
223
+  switch (result) {
224
+    case RESULTS.UNAVAILABLE:
225
+      console.log("the feature is not available on this device");
226
+      break;
227
+    case RESULTS.GRANTED:
228
+      console.log("permission is granted");
229
+      break;
230
+    case RESULTS.DENIED:
231
+      console.log("permission is denied, but requestable");
232
+      break;
233
+    case RESULTS.NEVER_ASK_AGAIN:
234
+      console.log("permission is denied and not requestable");
235
+      break;
236
+  }
196
 });
237
 });
238
+```
239
+
240
+---
241
+
242
+#### checkMultiple()
243
+
244
+Check multiples permissions.
245
+
246
+#### Method type
197
 
247
 
198
-Permissions.request("location", { type: "always" }).then(response => {
199
-  this.setState({ locationPermission: response });
248
+```ts
249
+function checkMultiple<P: Permission>(permissions: P[]): Promise<{ [permission: P]: PermissionStatus }>;
250
+```
251
+
252
+#### Usage example
253
+
254
+```js
255
+import { checkMultiple, IOS_PERMISSIONS } from "react-native-permissions";
256
+
257
+checkMultiple([
258
+  IOS_PERMISSIONS.LOCATION_ALWAYS,
259
+  IOS_PERMISSIONS.MEDIA_LIBRARY,
260
+]).then(results => {
261
+  // results.LOCATION_ALWAYS
262
+  // results.MEDIA_LIBRARY
200
 });
263
 });
264
+```
265
+
266
+---
201
 
267
 
202
-Permissions.request("notification", { type: ["alert", "badge"] }).then(
203
-  response => {
204
-    this.setState({ notificationPermission: response });
205
-  },
206
-);
268
+#### request()
269
+
270
+Request one permission.
271
+
272
+#### Method type
273
+
274
+```ts
275
+function request(permission: string, config: RequestConfig = {}): Promise<PermissionStatus>;
207
 ```
276
 ```
208
 
277
 
209
-- You cannot request microphone permissions on the simulator.
210
-- With Xcode 8, you now need to add usage descriptions for each permission you
211
-  will request. Open Xcode ➜ `Info.plist` ➜ Add a key (starting with "Privacy -
212
-  ...") with your kit specific permission.
213
-
214
-Example: If you need Contacts permission you have to add the key `Privacy - Contacts Usage Description`.
215
-
216
-<img width="338" alt="3cde3b44-7ffd-11e6-918b-63888e33f983" src="https://cloud.githubusercontent.com/assets/1440796/18713019/271be540-8011-11e6-87fb-c3828c172dfc.png">
217
-
218
-#### App Store submission disclaimer
219
-
220
-If you need to submit you application to the AppStore, you need to add to your
221
-`Info.plist` all `*UsageDescription` keys with a string value explaining to the
222
-user how the app uses this data. **Even if you don't use them**.
223
-
224
-So before submitting your app to the App Store, make sure that in your
225
-`Info.plist` you have the following keys:
226
-
227
-```xml
228
-<key>NSBluetoothPeripheralUsageDescription</key>
229
-<string>Some description</string>
230
-<key>NSCalendarsUsageDescription</key>
231
-<string>Some description</string>
232
-<key>NSCameraUsageDescription</key>
233
-<string>Some description</string>
234
-<key>NSLocationWhenInUseUsageDescription</key>
235
-<string>Some description</string>
236
-<key>NSPhotoLibraryAddUsageDescription</key>
237
-<string>Some description</string>
238
-<key>NSPhotoLibraryUsageDescription</key>
239
-<string>Some description</string>
240
-<key>NSSpeechRecognitionUsageDescription</key>
241
-<string>Some description</string>
242
-<key>NSAppleMusicUsageDescription</key>
243
-<string>Some description</string>
244
-<key>NSMotionUsageDescription</key>
245
-<string>Some description</string>
278
+#### Usage example
279
+
280
+```js
281
+import { request, IOS_PERMISSIONS } from "react-native-permissions";
282
+
283
+request(IOS_PERMISSIONS.LOCATION_ALWAYS).then(result => {
284
+  // …
285
+});
246
 ```
286
 ```
247
 
287
 
248
-This is required because during the phase of processing in the App Store
249
-submission, the system detects that you app contains code to request the
250
-permission `X` but don't have the `UsageDescription` key and then it rejects the
251
-build.
288
+---
252
 
289
 
253
-> Please note that it will only be shown to the users the usage descriptions of
254
-> the permissions you really require in your app.
290
+#### requestMultiple()
255
 
291
 
256
-You can find more information about this issue in #46.
292
+Request multiples permissions.
257
 
293
 
258
-### Android Notes
294
+#### Method type
259
 
295
 
260
-- Uses React Native's own
261
-  [`PermissionsAndroid` JS API](http://facebook.github.io/react-native/docs/permissionsandroid.html).
262
-- All required permissions also need to be included in the `AndroidManifest.xml`
263
-  file before they can be requested. Otherwise `request()` will immediately
264
-  return `denied`.
265
-- You can request write access to any of these types by also including the
266
-  appropriate write permission in the `AndroidManifest.xml` file. Read more
267
-  [here](https://developer.android.com/guide/topics/security/permissions.html#normal-dangerous).
296
+```ts
297
+function requestMultiple<P: Permission>(permissions: P[]): Promise<{ [permission: P]: PermissionStatus }>;
298
+```
268
 
299
 
269
-- The optional rationale argument will show a dialog prompt.
300
+#### Usage example
270
 
301
 
271
 ```js
302
 ```js
272
-// example
273
-Permissions.request("camera", {
274
-  rationale: {
275
-    title: "Cool Photo App Camera Permission",
276
-    message:
277
-      "Cool Photo App needs access to your camera " +
278
-      "so you can take awesome pictures.",
279
-  },
280
-}).then(response => {
281
-  this.setState({ cameraPermission: response });
303
+import { requestMultiple, IOS_PERMISSIONS } from "react-native-permissions";
304
+
305
+requestMultiple([
306
+  IOS_PERMISSIONS.LOCATION_ALWAYS,
307
+  IOS_PERMISSIONS.MEDIA_LIBRARY,
308
+]).then(results => {
309
+  // results.LOCATION_ALWAYS
310
+  // results.MEDIA_LIBRARY
282
 });
311
 });
283
 ```
312
 ```
284
 
313
 
285
-- Permissions are automatically accepted for **targetSdkVersion < 23** but you
286
-  can still use `check()` to check if the user has disabled them from Settings.
314
+---
315
+
316
+#### openSettings()
287
 
317
 
288
-You might need to elevate the **targetSdkVersion** version in your
289
-`build.gradle`:
318
+Open application settings.
290
 
319
 
291
-```groovy
292
-android {
293
-  compileSdkVersion 23 // ← set at least 23
294
-  buildToolsVersion "23.0.1"  // ← set at least 23.0.0
320
+#### Method type
295
 
321
 
296
-  defaultConfig {
297
-    minSdkVersion 16
298
-    targetSdkVersion 23 // ← set at least 23
299
-    // ...
322
+```ts
323
+function openSettings(): Promise<boolean>;
300
 ```
324
 ```
301
 
325
 
302
-## Troubleshooting
326
+#### Usage example
303
 
327
 
304
-#### Q: iOS - App crashes as soon as I request permission
328
+```js
329
+import { openSettings } from "react-native-permissions";
305
 
330
 
306
-> A: Starting with Xcode 8, you need to add permission descriptions. See iOS
307
-> notes for more details. Thanks to [@jesperlndk](https://github.com/jesperlndk)
308
-> for discovering this.
331
+openSettings().catch(() => console.warn("cannot open settings");
332
+```
309
 
333
 
310
-#### Q: iOS - App crashes when I change permission from settings
334
+### iOS Notes
311
 
335
 
312
-> A: This is normal. iOS restarts your app when your privacy settings change.
313
-> Just google "iOS crash permission change"
336
+- Permission type `BLUETOOTH_PERIPHERAL` represents the status of the `CBPeripheralManager`.
337
+- If `notificationOptions` config array is omitted on `NOTIFICATIONS` request, it will request `alert`, `badge` and `sound`.