Parcourir la source

Merge pull request #70 from trestrantham/master

Add support for iOS 10 speech recognition permission requests
Yonah Forst il y a 7 ans
Parent
révision
f401e694e3

+ 1
- 1
Example/ios/Example.xcodeproj/project.pbxproj Voir le fichier

@@ -584,7 +584,7 @@
584 584
 		83CBB9F71A601CBA00E9B192 /* Project object */ = {
585 585
 			isa = PBXProject;
586 586
 			attributes = {
587
-				LastUpgradeCheck = 610;
587
+				LastUpgradeCheck = 0820;
588 588
 				ORGANIZATIONNAME = Facebook;
589 589
 				TargetAttributes = {
590 590
 					00E356ED1AD99517003FC87E = {

+ 1
- 1
Example/ios/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme Voir le fichier

@@ -1,6 +1,6 @@
1 1
 <?xml version="1.0" encoding="UTF-8"?>
2 2
 <Scheme
3
-   LastUpgradeVersion = "0620"
3
+   LastUpgradeVersion = "0820"
4 4
    version = "1.3">
5 5
    <BuildAction
6 6
       parallelizeBuildables = "NO"

+ 2
- 1
RCTConvert+RNPStatus.h Voir le fichier

@@ -25,7 +25,8 @@ typedef NS_ENUM(NSInteger, RNPType) {
25 25
     RNPTypeReminder,
26 26
     RNPTypeBluetooth,
27 27
     RNPTypeNotification,
28
-    RNPTypeBackgroundRefresh
28
+    RNPTypeBackgroundRefresh,
29
+    RNPTypeSpeechRecognition
29 30
 };
30 31
 
31 32
 @interface RCTConvert (RNPStatus)

+ 2
- 1
RCTConvert+RNPStatus.m Voir le fichier

@@ -20,7 +20,8 @@ RCT_ENUM_CONVERTER(RNPType, (@{ @"location" : @(RNPTypeLocation),
20 20
                                 @"reminder" : @(RNPTypeReminder),
21 21
                                 @"bluetooth" : @(RNPTypeBluetooth),
22 22
                                 @"notification" : @(RNPTypeNotification),
23
-                                @"backgroundRefresh": @(RNPTypeBackgroundRefresh)
23
+                                @"backgroundRefresh": @(RNPTypeBackgroundRefresh),
24
+                                @"speechRecognition": @(RNPTypeSpeechRecognition)
24 25
                                 }),
25 26
                                 RNPTypeUnknown, integerValue)
26 27
 

+ 17
- 14
README.md Voir le fichier

@@ -12,6 +12,7 @@ The current supported permissions are:
12 12
 - Bluetooth *(iOS only)*
13 13
 - Push Notifications *(iOS only)*
14 14
 - Background Refresh *(iOS only)*
15
+- Speech Recognition *(iOS only)*
15 16
 
16 17
 
17 18
 | Version | React Native Support |
@@ -56,7 +57,7 @@ const Permissions = require('react-native-permissions');
56 57
     Permissions.checkMultiplePermissions(['camera', 'photo'])
57 58
       .then(response => {
58 59
         //response is an object mapping type to permission
59
-        this.setState({ 
60
+        this.setState({
60 61
           cameraPermission: response.camera,
61 62
           photoPermission: response.photo,
62 63
         })
@@ -64,7 +65,7 @@ const Permissions = require('react-native-permissions');
64 65
   }
65 66
 
66 67
   // this is a common pattern when asking for permissions.
67
-  // iOS only gives you once chance to show the permission dialog, 
68
+  // iOS only gives you once chance to show the permission dialog,
68 69
   // after which the user needs to manually enable them from settings.
69 70
   // the idea here is to explain why we need access and determine if
70 71
   // the user will say no, so that we don't blow our one chance.
@@ -75,7 +76,7 @@ const Permissions = require('react-native-permissions');
75 76
       'We need access so you can set your profile pic',
76 77
       [
77 78
         {text: 'No way', onPress: () => console.log('permission denied'), style: 'cancel'},
78
-        this.state.photoPermission == 'undetermined'? 
79
+        this.state.photoPermission == 'undetermined'?
79 80
           {text: 'OK', onPress: this._requestPermission.bind(this)}
80 81
           : {text: 'Open Settings', onPress: Permissions.openSettings}
81 82
       ]
@@ -110,6 +111,7 @@ Promises resolve into one of these statuses
110 111
 |`reminder`| ✔️ | ❌ |
111 112
 |`notification`| ✔️ | ❌ |
112 113
 |`backgroundRefresh`| ✔️ | ❌ |
114
+|`speechRecognition`| ✔️ | ❌ |
113 115
 |`storage`| ❌️ | ✔ |
114 116
 
115 117
 ###Methods
@@ -163,14 +165,15 @@ All required permissions also need to be included in the Manifest before they ca
163 165
 
164 166
 Permissions are automatically accepted for targetSdkVersion < 23 but you can still use `getPermissionStatus` to check if the user has disabled them from Settings.
165 167
 
166
-Here's a map of types to Android system permissions names:  
167
-`location` -> `android.permission.ACCESS_FINE_LOCATION`  
168
-`camera` -> `android.permission.CAMERA`  
169
-`microphone` -> `android.permission.RECORD_AUDIO`  
170
-`photo` -> `android.permission.READ_EXTERNAL_STORAGE`  
171
-`storage` -> `android.permission.READ_EXTERNAL_STORAGE`  
172
-`contacts` -> `android.permission.READ_CONTACTS`  
173
-`event` -> `android.permission.READ_CALENDAR`  
168
+Here's a map of types to Android system permissions names:
169
+`location` -> `android.permission.ACCESS_FINE_LOCATION`
170
+`camera` -> `android.permission.CAMERA`
171
+`microphone` -> `android.permission.RECORD_AUDIO`
172
+`photo` -> `android.permission.READ_EXTERNAL_STORAGE`
173
+`storage` -> `android.permission.READ_EXTERNAL_STORAGE`
174
+`contacts` -> `android.permission.READ_CONTACTS`
175
+`event` -> `android.permission.READ_CALENDAR`
176
+
174 177
 
175 178
 You can request write access to any of these types by also including the appropriate write permission in the Manifest. Read more here: https://developer.android.com/guide/topics/security/permissions.html#normal-dangerous
176 179
 
@@ -181,7 +184,7 @@ npm install --save react-native-permissions
181 184
 rnpm link
182 185
 ````
183 186
 
184
-###Or manualy linking   
187
+###Or manualy linking
185 188
 
186 189
 ####iOS
187 190
 * Run open node_modules/react-native-permissions
@@ -233,10 +236,10 @@ public class MainApplication extends Application implements ReactApplication {
233 236
 ##Troubleshooting
234 237
 
235 238
 #### Q: Android - `undefined is not a object (evaluating 'RNPermissions.requestPermissions')`
236
-A: `rnpm` may not have linked correctly. Follow the manual linking steps and make sure the library is linked 
239
+A: `rnpm` may not have linked correctly. Follow the manual linking steps and make sure the library is linked
237 240
 
238 241
 #### Q: iOS - app crashes as soon as I request permission
239 242
 A: starting with xcode 8, you need to add permission descriptions. see iOS notes for more details. Thanks to @jesperlndk for discovering this.
240 243
 
241 244
 #### Q: iOS - app crashes when I change permissions from settings
242
-A: This is normal. iOS restarts your app when your privacy settings change. Just google "ios crash permission change"
245
+A: This is normal. iOS restarts your app when your privacy settings change. Just google "ios crash permission change"

+ 1
- 0
ReactNativePermissions.js Voir le fichier

@@ -16,6 +16,7 @@ const RNPTypes = {
16 16
 		'bluetooth',
17 17
 		'notification',
18 18
 		'backgroundRefresh',
19
+		'speechRecognition',
19 20
 	],
20 21
 	android: [
21 22
 		'location',

+ 6
- 0
ReactNativePermissions.m Voir le fichier

@@ -22,6 +22,7 @@
22 22
 #import "RNPPhoto.h"
23 23
 #import "RNPContacts.h"
24 24
 #import "RNPBackgroundRefresh.h"
25
+#import "RNPSpeechRecognition.h"
25 26
 
26 27
 @interface ReactNativePermissions()
27 28
 @property (strong, nonatomic) RNPLocation *locationMgr;
@@ -104,6 +105,9 @@ RCT_REMAP_METHOD(getPermissionStatus, getPermissionStatus:(RNPType)type json:(id
104 105
         case RNPTypeBackgroundRefresh:
105 106
             status = [RNPBackgroundRefresh getStatus];
106 107
             break;
108
+        case RNPTypeSpeechRecognition:
109
+            status = [RNPSpeechRecognition getStatus];
110
+            break;
107 111
         default:
108 112
             break;
109 113
     }
@@ -134,6 +138,8 @@ RCT_REMAP_METHOD(requestPermission, permissionType:(RNPType)type json:(id)json r
134 138
             return [self requestBluetooth:resolve];
135 139
         case RNPTypeNotification:
136 140
             return [self requestNotification:json resolve:resolve];
141
+        case RNPTypeSpeechRecognition:
142
+            return [RNPSpeechRecognition request:resolve];
137 143
         default:
138 144
             break;
139 145
     }

+ 7
- 1
ReactNativePermissions.xcodeproj/project.pbxproj Voir le fichier

@@ -7,6 +7,7 @@
7 7
 	objects = {
8 8
 
9 9
 /* Begin PBXBuildFile section */
10
+		281CD5911E26B0C8003A72B2 /* RNPSpeechRecognition.m in Sources */ = {isa = PBXBuildFile; fileRef = 281CD5901E26B0C7003A72B2 /* RNPSpeechRecognition.m */; };
10 11
 		9D46283E1D34719100346A5B /* RNPAudioVideo.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D46282F1D34719100346A5B /* RNPAudioVideo.m */; };
11 12
 		9D46283F1D34719100346A5B /* RNPBackgroundRefresh.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D4628311D34719100346A5B /* RNPBackgroundRefresh.m */; };
12 13
 		9D4628401D34719100346A5B /* RNPBluetooth.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D4628331D34719100346A5B /* RNPBluetooth.m */; };
@@ -32,6 +33,8 @@
32 33
 /* End PBXCopyFilesBuildPhase section */
33 34
 
34 35
 /* Begin PBXFileReference section */
36
+		281CD5901E26B0C7003A72B2 /* RNPSpeechRecognition.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNPSpeechRecognition.m; path = permissions/RNPSpeechRecognition.m; sourceTree = SOURCE_ROOT; };
37
+		281CD5921E26B266003A72B2 /* RNPSpeechRecognition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNPSpeechRecognition.h; path = permissions/RNPSpeechRecognition.h; sourceTree = SOURCE_ROOT; };
35 38
 		9D23B34F1C767B80008B4819 /* libReactNativePermissions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libReactNativePermissions.a; sourceTree = BUILT_PRODUCTS_DIR; };
36 39
 		9D46282E1D34719100346A5B /* RNPAudioVideo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNPAudioVideo.h; path = permissions/RNPAudioVideo.h; sourceTree = SOURCE_ROOT; };
37 40
 		9D46282F1D34719100346A5B /* RNPAudioVideo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNPAudioVideo.m; path = permissions/RNPAudioVideo.m; sourceTree = SOURCE_ROOT; };
@@ -113,6 +116,8 @@
113 116
 				9D46283B1D34719100346A5B /* RNPNotification.m */,
114 117
 				9D46283C1D34719100346A5B /* RNPPhoto.h */,
115 118
 				9D46283D1D34719100346A5B /* RNPPhoto.m */,
119
+				281CD5921E26B266003A72B2 /* RNPSpeechRecognition.h */,
120
+				281CD5901E26B0C7003A72B2 /* RNPSpeechRecognition.m */,
116 121
 			);
117 122
 			name = permissions;
118 123
 			sourceTree = "<group>";
@@ -143,7 +148,7 @@
143 148
 		9D23B3471C767B80008B4819 /* Project object */ = {
144 149
 			isa = PBXProject;
145 150
 			attributes = {
146
-				LastUpgradeCheck = 0710;
151
+				LastUpgradeCheck = 0820;
147 152
 				ORGANIZATIONNAME = "Yonah Forst";
148 153
 				TargetAttributes = {
149 154
 					9D23B34E1C767B80008B4819 = {
@@ -175,6 +180,7 @@
175 180
 			files = (
176 181
 				9D46283F1D34719100346A5B /* RNPBackgroundRefresh.m in Sources */,
177 182
 				9D4628451D34719100346A5B /* RNPPhoto.m in Sources */,
183
+				281CD5911E26B0C8003A72B2 /* RNPSpeechRecognition.m in Sources */,
178 184
 				9D4628431D34719100346A5B /* RNPLocation.m in Sources */,
179 185
 				9D46283E1D34719100346A5B /* RNPAudioVideo.m in Sources */,
180 186
 				9D4628401D34719100346A5B /* RNPBluetooth.m in Sources */,

+ 17
- 0
permissions/RNPSpeechRecognition.h Voir le fichier

@@ -0,0 +1,17 @@
1
+//
2
+//  RNPSpeechRecognition.h
3
+//  ReactNativePermissions
4
+//
5
+//  Created by Tres Trantham on 1/11/17.
6
+//  Copyright © 2017 Yonah Forst. All rights reserved.
7
+//
8
+
9
+#import <Foundation/Foundation.h>
10
+#import "RCTConvert+RNPStatus.h"
11
+
12
+@interface RNPSpeechRecognition : NSObject
13
+
14
++ (NSString *)getStatus;
15
++ (void)request:(void (^)(NSString *))completionHandler;
16
+
17
+@end

+ 44
- 0
permissions/RNPSpeechRecognition.m Voir le fichier

@@ -0,0 +1,44 @@
1
+//
2
+//  RNPSpeechRecognition.m
3
+//  ReactNativePermissions
4
+//
5
+//  Created by Tres Trantham on 1/11/17.
6
+//  Copyright © 2017 Yonah Forst. All rights reserved.
7
+//
8
+
9
+#import "RNPSpeechRecognition.h"
10
+#import <Speech/Speech.h>
11
+
12
+@implementation RNPSpeechRecognition
13
+
14
++ (NSString *)getStatus
15
+{
16
+
17
+  int status = [SFSpeechRecognizer authorizationStatus];
18
+
19
+  switch (status) {
20
+      case SFSpeechRecognizerAuthorizationStatusAuthorized:
21
+          return RNPStatusAuthorized;
22
+      case SFSpeechRecognizerAuthorizationStatusDenied:
23
+          return RNPStatusDenied;
24
+      case SFSpeechRecognizerAuthorizationStatusRestricted:
25
+          return RNPStatusRestricted;
26
+      default:
27
+          return RNPStatusUndetermined;
28
+  }
29
+}
30
+
31
++ (void)request:(void (^)(NSString *))completionHandler
32
+{
33
+    void (^handler)(void) =  ^(void) {
34
+        dispatch_async(dispatch_get_main_queue(), ^{
35
+            completionHandler([self.class getStatus]);
36
+        });
37
+    };
38
+
39
+    [SFSpeechRecognizer requestAuthorization:^(SFSpeechRecognizerAuthorizationStatus status) {
40
+        handler();
41
+    }];
42
+}
43
+
44
+@end