Browse Source

Add motion permission request

Jonathan Kim 7 years ago
parent
commit
ade27e993b

+ 2
- 1
RCTConvert+RNPStatus.h View File

@@ -32,7 +32,8 @@ typedef NS_ENUM(NSInteger, RNPType) {
32 32
     RNPTypeBluetooth,
33 33
     RNPTypeNotification,
34 34
     RNPTypeBackgroundRefresh,
35
-    RNPTypeSpeechRecognition
35
+    RNPTypeSpeechRecognition,
36
+    RNPTypeMotion
36 37
 };
37 38
 
38 39
 @interface RCTConvert (RNPStatus)

+ 2
- 1
RCTConvert+RNPStatus.m View File

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

+ 6
- 0
ReactNativePermissions.m View File

@@ -44,6 +44,7 @@
44 44
 #import "RNPContacts.h"
45 45
 #import "RNPBackgroundRefresh.h"
46 46
 #import "RNPSpeechRecognition.h"
47
+#import "RNPMotion.h"
47 48
 
48 49
 @interface ReactNativePermissions()
49 50
 @property (strong, nonatomic) RNPLocation *locationMgr;
@@ -141,6 +142,9 @@ RCT_REMAP_METHOD(getPermissionStatus, getPermissionStatus:(RNPType)type json:(id
141 142
         case RNPTypeSpeechRecognition:
142 143
             status = [RNPSpeechRecognition getStatus];
143 144
             break;
145
+        case RNPTypeMotion:
146
+            status = [RNPMotion getStatus];
147
+            break;
144 148
         default:
145 149
             break;
146 150
     }
@@ -173,6 +177,8 @@ RCT_REMAP_METHOD(requestPermission, permissionType:(RNPType)type json:(id)json r
173 177
             return [self requestNotification:json resolve:resolve];
174 178
         case RNPTypeSpeechRecognition:
175 179
             return [RNPSpeechRecognition request:resolve];
180
+        case RNPTypeMotion:
181
+            return [RNPMotion request:resolve];
176 182
         default:
177 183
             break;
178 184
     }

+ 6
- 0
ReactNativePermissions.xcodeproj/project.pbxproj View File

@@ -8,6 +8,7 @@
8 8
 
9 9
 /* Begin PBXBuildFile section */
10 10
 		281CD5911E26B0C8003A72B2 /* RNPSpeechRecognition.m in Sources */ = {isa = PBXBuildFile; fileRef = 281CD5901E26B0C7003A72B2 /* RNPSpeechRecognition.m */; };
11
+		483383101FAB6115005D5777 /* RNPMotion.m in Sources */ = {isa = PBXBuildFile; fileRef = 4833830E1FAB6114005D5777 /* RNPMotion.m */; };
11 12
 		9D46283E1D34719100346A5B /* RNPAudioVideo.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D46282F1D34719100346A5B /* RNPAudioVideo.m */; };
12 13
 		9D46283F1D34719100346A5B /* RNPBackgroundRefresh.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D4628311D34719100346A5B /* RNPBackgroundRefresh.m */; };
13 14
 		9D4628401D34719100346A5B /* RNPBluetooth.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D4628331D34719100346A5B /* RNPBluetooth.m */; };
@@ -35,6 +36,8 @@
35 36
 /* Begin PBXFileReference section */
36 37
 		281CD5901E26B0C7003A72B2 /* RNPSpeechRecognition.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNPSpeechRecognition.m; path = permissions/RNPSpeechRecognition.m; sourceTree = SOURCE_ROOT; };
37 38
 		281CD5921E26B266003A72B2 /* RNPSpeechRecognition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNPSpeechRecognition.h; path = permissions/RNPSpeechRecognition.h; sourceTree = SOURCE_ROOT; };
39
+		4833830E1FAB6114005D5777 /* RNPMotion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNPMotion.m; path = permissions/RNPMotion.m; sourceTree = SOURCE_ROOT; };
40
+		4833830F1FAB6115005D5777 /* RNPMotion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNPMotion.h; path = permissions/RNPMotion.h; sourceTree = SOURCE_ROOT; };
38 41
 		9D23B34F1C767B80008B4819 /* libReactNativePermissions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libReactNativePermissions.a; sourceTree = BUILT_PRODUCTS_DIR; };
39 42
 		9D46282E1D34719100346A5B /* RNPAudioVideo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNPAudioVideo.h; path = permissions/RNPAudioVideo.h; sourceTree = SOURCE_ROOT; };
40 43
 		9D46282F1D34719100346A5B /* RNPAudioVideo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNPAudioVideo.m; path = permissions/RNPAudioVideo.m; sourceTree = SOURCE_ROOT; };
@@ -100,6 +103,8 @@
100 103
 		9D4628091D33C1EC00346A5B /* permissions */ = {
101 104
 			isa = PBXGroup;
102 105
 			children = (
106
+				4833830F1FAB6115005D5777 /* RNPMotion.h */,
107
+				4833830E1FAB6114005D5777 /* RNPMotion.m */,
103 108
 				9D46282E1D34719100346A5B /* RNPAudioVideo.h */,
104 109
 				9D46282F1D34719100346A5B /* RNPAudioVideo.m */,
105 110
 				9D4628301D34719100346A5B /* RNPBackgroundRefresh.h */,
@@ -186,6 +191,7 @@
186 191
 				9D4628401D34719100346A5B /* RNPBluetooth.m in Sources */,
187 192
 				9DE8D28B1CA31E95009CE8CC /* RCTConvert+RNPStatus.m in Sources */,
188 193
 				9D4628421D34719100346A5B /* RNPEvent.m in Sources */,
194
+				483383101FAB6115005D5777 /* RNPMotion.m in Sources */,
189 195
 				9DE8D2821CA3188D009CE8CC /* ReactNativePermissions.m in Sources */,
190 196
 				9D4628411D34719100346A5B /* RNPContacts.m in Sources */,
191 197
 				9D4628441D34719100346A5B /* RNPNotification.m in Sources */,

+ 14
- 0
permissions/RNPMotion.h View File

@@ -0,0 +1,14 @@
1
+//
2
+//  RNPMotion.h
3
+//  ReactNativePermissions
4
+//
5
+
6
+#import <Foundation/Foundation.h>
7
+#import "RCTConvert+RNPStatus.h"
8
+
9
+@interface RNPMotion : NSObject
10
+
11
++ (NSString *)getStatus;
12
++ (void)request:(void (^)(NSString *))completionHandler;
13
+
14
+@end

+ 67
- 0
permissions/RNPMotion.m View File

@@ -0,0 +1,67 @@
1
+//
2
+//  RNPMotion.m
3
+//  ReactNativePermissions
4
+//
5
+
6
+#import "RNPMotion.h"
7
+#import <CoreMotion/CoreMotion.h>
8
+
9
+@interface RNPMotion ()
10
+@property (nonatomic, strong) CMMotionActivityManager *activityManager;
11
+@property (nonatomic, strong) NSOperationQueue *motionActivityQueue;
12
+@end
13
+
14
+@implementation RNPMotion
15
+
16
++ (NSString *)getStatus
17
+{
18
+    if (![CMMotionActivityManager isActivityAvailable]) {
19
+        return RNPStatusRestricted;
20
+    }
21
+    
22
+    if (@available(iOS 11.0, *)) {
23
+        CMAuthorizationStatus status = [CMMotionActivityManager authorizationStatus];
24
+        
25
+        switch (status) {
26
+            case CMAuthorizationStatusAuthorized:
27
+                return RNPStatusAuthorized;
28
+            case CMAuthorizationStatusDenied:
29
+                return RNPStatusDenied;
30
+            case CMAuthorizationStatusNotDetermined:
31
+                return RNPStatusUndetermined;
32
+            case CMAuthorizationStatusRestricted:
33
+                return RNPStatusRestricted;
34
+            default:
35
+                return RNPStatusUndetermined;
36
+        }
37
+    } else {
38
+        return RNPStatusRestricted;
39
+    }
40
+}
41
+
42
++ (void)request:(void (^)(NSString *))completionHandler
43
+{
44
+    __block NSString *status = [self getMotionPermissionStatus];
45
+    
46
+    if ([status isEqual: RNPStatusUndetermined]) {
47
+        self.activityManager = [[CMMotionActivityManager alloc] init];
48
+        self.motionActivityQueue = [[NSOperationQueue alloc] init];
49
+        [self.activityManager queryActivityStartingFromDate:[NSDate distantPast] toDate:[NSDate date] toQueue:self.motionActivityQueue withHandler:^(NSArray *activities, NSError *error) {
50
+            if (error) {
51
+                status = RNPStatusDenied;
52
+            } else if (activities || !error) {
53
+                status = RNPStatusAuthorized;
54
+            }
55
+            
56
+            dispatch_async(dispatch_get_main_queue(), ^{
57
+                completionHandler(status);
58
+            });
59
+            
60
+            [self setActivityManager:nil];
61
+            [self setMotionActivityQueue:nil];
62
+        }];
63
+    } else {
64
+        completionHandler(status);
65
+    }
66
+}
67
+@end