Explorar el Código

merged in upstream

Jason Gaare hace 8 años
padre
commit
9e5cd12b2f
Se han modificado 42 ficheros con 1241 adiciones y 216 borrados
  1. 8
    0
      .gitignore
  2. 1
    0
      .npmignore
  3. 3
    0
      Example/.babelrc
  4. 16
    13
      Example/.flowconfig
  5. 1
    0
      Example/.gitattributes
  6. 16
    3
      Example/.gitignore
  7. 51
    11
      Example/Example.js
  8. 12
    0
      Example/__tests__/index.android.js
  9. 12
    0
      Example/__tests__/index.ios.js
  10. 3
    3
      Example/android/app/build.gradle
  11. 1
    3
      Example/android/app/src/main/AndroidManifest.xml
  12. 9
    2
      Example/android/app/src/main/java/com/example/MainApplication.java
  13. 1
    1
      Example/android/build.gradle
  14. 2
    1
      Example/android/gradle/wrapper/gradle-wrapper.properties
  15. 54
    0
      Example/ios/Example-tvOS/Info.plist
  16. 24
    0
      Example/ios/Example-tvOSTests/Info.plist
  17. 541
    44
      Example/ios/Example.xcodeproj/project.pbxproj
  18. 129
    0
      Example/ios/Example.xcodeproj/xcshareddata/xcschemes/Example-tvOS.xcscheme
  19. 23
    6
      Example/ios/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme
  20. 2
    2
      Example/ios/Example/AppDelegate.m
  21. 20
    4
      Example/ios/Example/Info.plist
  22. 1
    1
      Example/ios/Example/main.m
  23. 2
    2
      Example/ios/ExampleTests/ExampleTests.m
  24. 21
    11
      Example/package.json
  25. 7
    2
      RCTConvert+RNPStatus.h
  26. 2
    1
      RCTConvert+RNPStatus.m
  27. 104
    36
      README.md
  28. 5
    2
      ReactNativePermissions.h
  29. 9
    4
      ReactNativePermissions.js
  30. 41
    8
      ReactNativePermissions.m
  31. 1
    0
      ReactNativePermissions.podspec
  32. 7
    1
      ReactNativePermissions.xcodeproj/project.pbxproj
  33. 0
    0
      ReactNativePermissions.xcodeproj/xcuserdata/Yonah.xcuserdatad/xcschemes/ReactNativePermissions.xcscheme
  34. 4
    4
      android/build.gradle
  35. 19
    8
      android/src/main/java/com/joshblour/reactnativepermissions/ReactNativePermissionsModule.java
  36. 1
    1
      package.json
  37. 1
    1
      permissions/RNPLocation.h
  38. 14
    9
      permissions/RNPLocation.m
  39. 12
    31
      permissions/RNPNotification.m
  40. 0
    1
      permissions/RNPPhoto.m
  41. 17
    0
      permissions/RNPSpeechRecognition.h
  42. 44
    0
      permissions/RNPSpeechRecognition.m

+ 8
- 0
.gitignore Ver fichero

1
 android/react-native-permissions.iml
1
 android/react-native-permissions.iml
2
 android/build
2
 android/build
3
+android/.idea
4
+npm-debug.log
5
+gradlew
6
+gradle-wrapper.properties
7
+gradle-wrapper.jar
8
+local.properties
9
+gradlew.bat
10
+android.iml

+ 1
- 0
.npmignore Ver fichero

1
+Example

+ 3
- 0
Example/.babelrc Ver fichero

1
+{
2
+"presets": ["react-native"]
3
+}

+ 16
- 13
Example/.flowconfig Ver fichero

1
 [ignore]
1
 [ignore]
2
+; We fork some components by platform
3
+.*/*[.]android.js
2
 
4
 
3
-# We fork some components by platform.
4
-.*/*.android.js
5
+; Ignore "BUCK" generated dirs
6
+<PROJECT_ROOT>/\.buckd/
5
 
7
 
6
-# Ignore templates with `@flow` in header
7
-.*/local-cli/generator.*
8
+; Ignore unexpected extra "@providesModule"
9
+.*/node_modules/.*/node_modules/fbjs/.*
8
 
10
 
9
-# Ignore malformed json
10
-.*/node_modules/y18n/test/.*\.json
11
+; Ignore duplicate module providers
12
+; For RN Apps installed via npm, "Libraries" folder is inside
13
+; "node_modules/react-native" but in the source repo it is in the root
14
+.*/Libraries/react-native/React.js
15
+.*/Libraries/react-native/ReactNative.js
11
 
16
 
12
 [include]
17
 [include]
13
 
18
 
19
 [options]
24
 [options]
20
 module.system=haste
25
 module.system=haste
21
 
26
 
22
-esproposal.class_static_fields=enable
23
-esproposal.class_instance_fields=enable
24
-
25
 experimental.strict_type_args=true
27
 experimental.strict_type_args=true
26
 
28
 
27
 munge_underscores=true
29
 munge_underscores=true
28
 
30
 
29
-module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub'
30
 module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
31
 module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
31
 
32
 
32
 suppress_type=$FlowIssue
33
 suppress_type=$FlowIssue
33
 suppress_type=$FlowFixMe
34
 suppress_type=$FlowFixMe
34
 suppress_type=$FixMe
35
 suppress_type=$FixMe
35
 
36
 
36
-suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(2[0-7]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
37
-suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(2[0-7]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
37
+suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(3[0-7]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
38
+suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(3[0-7]\\|1[0-9]\\|[1-2][0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
38
 suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
39
 suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
39
 
40
 
41
+unsafe.enable_getters_and_setters=true
42
+
40
 [version]
43
 [version]
41
-^0.27.0
44
+^0.37.0

+ 1
- 0
Example/.gitattributes Ver fichero

1
+*.pbxproj -text

+ 16
- 3
Example/.gitignore Ver fichero

22
 *.xcuserstate
22
 *.xcuserstate
23
 project.xcworkspace
23
 project.xcworkspace
24
 
24
 
25
-# Android/IJ
25
+# Android/IntelliJ
26
 #
26
 #
27
-*.iml
27
+build/
28
 .idea
28
 .idea
29
 .gradle
29
 .gradle
30
 local.properties
30
 local.properties
31
+*.iml
31
 
32
 
32
 # node.js
33
 # node.js
33
 #
34
 #
34
 node_modules/
35
 node_modules/
35
 npm-debug.log
36
 npm-debug.log
37
+yarn-error.log
36
 
38
 
37
 # BUCK
39
 # BUCK
38
 buck-out/
40
 buck-out/
39
 \.buckd/
41
 \.buckd/
40
 android/app/libs
42
 android/app/libs
41
-android/keystores/debug.keystore
43
+*.keystore
44
+
45
+# fastlane
46
+#
47
+# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
48
+# screenshots whenever they are needed.
49
+# For more information about the recommended setup visit:
50
+# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
51
+
52
+fastlane/report.xml
53
+fastlane/Preview.html
54
+fastlane/screenshots

+ 51
- 11
Example/Example.js Ver fichero

12
   View,
12
   View,
13
   Alert,
13
   Alert,
14
   AppState,
14
   AppState,
15
+  Platform,
15
 } from 'react-native';
16
 } from 'react-native';
16
 
17
 
17
 import Permissions from 'react-native-permissions'
18
 import Permissions from 'react-native-permissions'
40
     }
41
     }
41
   }
42
   }
42
 
43
 
44
+  _openSettings() {
45
+    return Permissions.openSettings()
46
+      .then(() => alert('back to app!!'))
47
+  }
48
+
43
   _updatePermissions(types) {
49
   _updatePermissions(types) {
44
     Permissions.checkMultiplePermissions(types)
50
     Permissions.checkMultiplePermissions(types)
51
+      .then(status => {
52
+        if (this.state.isAlways) {
53
+          return Permissions.getPermissionStatus('location', 'always')
54
+            .then(location => ({...status, location}))
55
+        }
56
+        return status
57
+      })
45
       .then(status => this.setState({ status }))
58
       .then(status => this.setState({ status }))
46
   }
59
   }
47
 
60
 
48
   _requestPermission(permission) {
61
   _requestPermission(permission) {
49
-    Permissions.requestPermission(permission)
62
+    var options
63
+
64
+    if (permission == 'location') {
65
+      options = this.state.isAlways ? 'always' : 'whenInUse'
66
+    }
67
+
68
+    Permissions.requestPermission(permission, options)
50
       .then(res => {
69
       .then(res => {
51
         this.setState({
70
         this.setState({
52
           status: {...this.state.status, [permission]: res}
71
           status: {...this.state.status, [permission]: res}
57
             "There was a problem getting your permission. Please enable it from settings.",
76
             "There was a problem getting your permission. Please enable it from settings.",
58
             [
77
             [
59
               {text: 'Cancel', style: 'cancel'},
78
               {text: 'Cancel', style: 'cancel'},
60
-              {text: 'Open Settings', onPress: Permissions.openSettings },
79
+              {text: 'Open Settings', onPress: this._openSettings.bind(this) },
61
             ]
80
             ]
62
           )
81
           )
63
         }
82
         }
64
       }).catch(e => console.warn(e))
83
       }).catch(e => console.warn(e))
65
   }
84
   }
66
 
85
 
86
+  _onLocationSwitchChange() {
87
+    this.setState({ isAlways: !this.state.isAlways })
88
+    this._updatePermissions(this.state.types)
89
+  }
90
+
67
   render() {
91
   render() {
68
     return (
92
     return (
69
       <View style={styles.container}>
93
       <View style={styles.container}>
94
+
70
         {this.state.types.map(p => (
95
         {this.state.types.map(p => (
71
           <TouchableHighlight 
96
           <TouchableHighlight 
72
             style={[styles.button, styles[this.state.status[p]]]}
97
             style={[styles.button, styles[this.state.status[p]]]}
74
             onPress={this._requestPermission.bind(this, p)}>
99
             onPress={this._requestPermission.bind(this, p)}>
75
             <View>
100
             <View>
76
               <Text style={styles.text}>
101
               <Text style={styles.text}>
77
-                {p}
102
+                {Platform.OS == 'ios' && p == 'location' ? `location ${this.state.isAlways ? 'always' : 'whenInUse'}` : p}
78
               </Text>
103
               </Text>
79
               <Text style={styles.subtext}>
104
               <Text style={styles.subtext}>
80
                 {this.state.status[p]}
105
                 {this.state.status[p]}
83
           </TouchableHighlight>
108
           </TouchableHighlight>
84
           )
109
           )
85
         )}
110
         )}
86
-        <TouchableHighlight 
87
-          style={styles.openSettings}
88
-          onPress={Permissions.openSettings}>
89
-          <Text style={styles.text}>Open settings</Text>
90
-        </TouchableHighlight>
111
+        <View style={styles.footer}>
112
+          <TouchableHighlight 
113
+            style={styles['footer_'+Platform.OS]}
114
+            onPress={this._onLocationSwitchChange.bind(this)}>
115
+            <Text style={styles.text}>Toggle location type</Text>
116
+          </TouchableHighlight>
117
+
118
+          <TouchableHighlight 
119
+            onPress={this._openSettings.bind(this)}>
120
+            <Text style={styles.text}>Open settings</Text>
121
+          </TouchableHighlight>
122
+        </View>
91
 
123
 
92
-        <Text>Note: microphone permissions may not work on iOS simulator. Also, toggling permissions from the settings menu may cause the app to crash. This is normal on iOS. Google "ios crash permission change"</Text>
124
+
125
+        <Text style={styles['footer_'+Platform.OS]}>
126
+          Note: microphone permissions may not work on iOS simulator. Also, toggling permissions from the settings menu may cause the app to crash. This is normal on iOS. Google "ios crash permission change"
127
+        </Text>
93
       </View>
128
       </View>
94
     );
129
     );
95
   }
130
   }
130
   restricted: {
165
   restricted: {
131
     backgroundColor: '#FFAB91'
166
     backgroundColor: '#FFAB91'
132
   },
167
   },
133
-  openSettings: {
168
+  footer: {
134
     padding: 10,
169
     padding: 10,
135
-    alignSelf: 'flex-end',
170
+    flexDirection: 'row',
171
+    justifyContent: 'space-between',
172
+  },
173
+  footer_android: {
174
+    height: 0,
175
+    width: 0,
136
   }
176
   }
137
 })
177
 })

+ 12
- 0
Example/__tests__/index.android.js Ver fichero

1
+import 'react-native';
2
+import React from 'react';
3
+import Index from '../index.android.js';
4
+
5
+// Note: test renderer must be required after react-native.
6
+import renderer from 'react-test-renderer';
7
+
8
+it('renders correctly', () => {
9
+  const tree = renderer.create(
10
+    <Index />
11
+  );
12
+});

+ 12
- 0
Example/__tests__/index.ios.js Ver fichero

1
+import 'react-native';
2
+import React from 'react';
3
+import Index from '../index.ios.js';
4
+
5
+// Note: test renderer must be required after react-native.
6
+import renderer from 'react-test-renderer';
7
+
8
+it('renders correctly', () => {
9
+  const tree = renderer.create(
10
+    <Index />
11
+  );
12
+});

+ 3
- 3
Example/android/app/build.gradle Ver fichero

88
 
88
 
89
     defaultConfig {
89
     defaultConfig {
90
         applicationId "com.example"
90
         applicationId "com.example"
91
-        minSdkVersion 22
91
+        minSdkVersion 21
92
         targetSdkVersion 23
92
         targetSdkVersion 23
93
         versionCode 1
93
         versionCode 1
94
         versionName "1.0"
94
         versionName "1.0"
135
 // Run this once to be able to run the application with BUCK
135
 // Run this once to be able to run the application with BUCK
136
 // puts all compile dependencies into folder libs for BUCK to use
136
 // puts all compile dependencies into folder libs for BUCK to use
137
 task copyDownloadableDepsToLibs(type: Copy) {
137
 task copyDownloadableDepsToLibs(type: Copy) {
138
-  from configurations.compile
139
-  into 'libs'
138
+    from configurations.compile
139
+    into 'libs'
140
 }
140
 }

+ 1
- 3
Example/android/app/src/main/AndroidManifest.xml Ver fichero

9
     <uses-permission android:name="android.permission.CAMERA"/>
9
     <uses-permission android:name="android.permission.CAMERA"/>
10
     <uses-permission android:name="android.permission.RECORD_AUDIO"/>
10
     <uses-permission android:name="android.permission.RECORD_AUDIO"/>
11
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
11
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
12
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
12
     <uses-permission android:name="android.permission.READ_CONTACTS"/>
13
     <uses-permission android:name="android.permission.READ_CONTACTS"/>
13
     <uses-permission android:name="android.permission.READ_CALENDAR"/>
14
     <uses-permission android:name="android.permission.READ_CALENDAR"/>
14
 
15
 
15
-    <uses-sdk
16
-        android:minSdkVersion="18"
17
-        android:targetSdkVersion="23" />
18
 
16
 
19
     <application
17
     <application
20
       android:name=".MainApplication"
18
       android:name=".MainApplication"

+ 9
- 2
Example/android/app/src/main/java/com/example/MainApplication.java Ver fichero

9
 import com.facebook.react.ReactPackage;
9
 import com.facebook.react.ReactPackage;
10
 import com.facebook.react.shell.MainReactPackage;
10
 import com.facebook.react.shell.MainReactPackage;
11
 import com.joshblour.reactnativepermissions.ReactNativePermissionsPackage;
11
 import com.joshblour.reactnativepermissions.ReactNativePermissionsPackage;
12
+import com.facebook.soloader.SoLoader;
12
 
13
 
13
 import java.util.Arrays;
14
 import java.util.Arrays;
14
 import java.util.List;
15
 import java.util.List;
17
 
18
 
18
   private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
19
   private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
19
     @Override
20
     @Override
20
-    protected boolean getUseDeveloperSupport() {
21
+    public boolean getUseDeveloperSupport() {
21
       return BuildConfig.DEBUG;
22
       return BuildConfig.DEBUG;
22
     }
23
     }
23
 
24
 
32
 
33
 
33
   @Override
34
   @Override
34
   public ReactNativeHost getReactNativeHost() {
35
   public ReactNativeHost getReactNativeHost() {
35
-      return mReactNativeHost;
36
+    return mReactNativeHost;
37
+  }
38
+
39
+  @Override
40
+  public void onCreate() {
41
+    super.onCreate();
42
+    SoLoader.init(this, /* native exopackage */ false);
36
   }
43
   }
37
 }
44
 }

+ 1
- 1
Example/android/build.gradle Ver fichero

5
         jcenter()
5
         jcenter()
6
     }
6
     }
7
     dependencies {
7
     dependencies {
8
-        classpath 'com.android.tools.build:gradle:1.3.1'
8
+        classpath 'com.android.tools.build:gradle:2.1.2'
9
 
9
 
10
         // NOTE: Do not place your application dependencies here; they belong
10
         // NOTE: Do not place your application dependencies here; they belong
11
         // in the individual module build.gradle files
11
         // in the individual module build.gradle files

+ 2
- 1
Example/android/gradle/wrapper/gradle-wrapper.properties Ver fichero

1
+#Fri Feb 03 16:27:32 CET 2017
1
 distributionBase=GRADLE_USER_HOME
2
 distributionBase=GRADLE_USER_HOME
2
 distributionPath=wrapper/dists
3
 distributionPath=wrapper/dists
3
 zipStoreBase=GRADLE_USER_HOME
4
 zipStoreBase=GRADLE_USER_HOME
4
 zipStorePath=wrapper/dists
5
 zipStorePath=wrapper/dists
5
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
6
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip

+ 54
- 0
Example/ios/Example-tvOS/Info.plist Ver fichero

1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+	<key>CFBundleDevelopmentRegion</key>
6
+	<string>en</string>
7
+	<key>CFBundleExecutable</key>
8
+	<string>$(EXECUTABLE_NAME)</string>
9
+	<key>CFBundleIdentifier</key>
10
+	<string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string>
11
+	<key>CFBundleInfoDictionaryVersion</key>
12
+	<string>6.0</string>
13
+	<key>CFBundleName</key>
14
+	<string>$(PRODUCT_NAME)</string>
15
+	<key>CFBundlePackageType</key>
16
+	<string>APPL</string>
17
+	<key>CFBundleShortVersionString</key>
18
+	<string>1.0</string>
19
+	<key>CFBundleSignature</key>
20
+	<string>????</string>
21
+	<key>CFBundleVersion</key>
22
+	<string>1</string>
23
+	<key>LSRequiresIPhoneOS</key>
24
+	<true/>
25
+	<key>UILaunchStoryboardName</key>
26
+	<string>LaunchScreen</string>
27
+	<key>UIRequiredDeviceCapabilities</key>
28
+	<array>
29
+		<string>armv7</string>
30
+	</array>
31
+	<key>UISupportedInterfaceOrientations</key>
32
+	<array>
33
+		<string>UIInterfaceOrientationPortrait</string>
34
+		<string>UIInterfaceOrientationLandscapeLeft</string>
35
+		<string>UIInterfaceOrientationLandscapeRight</string>
36
+	</array>
37
+	<key>UIViewControllerBasedStatusBarAppearance</key>
38
+	<false/>
39
+	<key>NSLocationWhenInUseUsageDescription</key>
40
+	<string></string>
41
+	<key>NSAppTransportSecurity</key>
42
+	<!--See http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/ -->
43
+	<dict>
44
+		<key>NSExceptionDomains</key>
45
+		<dict>
46
+			<key>localhost</key>
47
+			<dict>
48
+				<key>NSExceptionAllowsInsecureHTTPLoads</key>
49
+				<true/>
50
+			</dict>
51
+		</dict>
52
+	</dict>
53
+</dict>
54
+</plist>

+ 24
- 0
Example/ios/Example-tvOSTests/Info.plist Ver fichero

1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+	<key>CFBundleDevelopmentRegion</key>
6
+	<string>en</string>
7
+	<key>CFBundleExecutable</key>
8
+	<string>$(EXECUTABLE_NAME)</string>
9
+	<key>CFBundleIdentifier</key>
10
+	<string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string>
11
+	<key>CFBundleInfoDictionaryVersion</key>
12
+	<string>6.0</string>
13
+	<key>CFBundleName</key>
14
+	<string>$(PRODUCT_NAME)</string>
15
+	<key>CFBundlePackageType</key>
16
+	<string>BNDL</string>
17
+	<key>CFBundleShortVersionString</key>
18
+	<string>1.0</string>
19
+	<key>CFBundleSignature</key>
20
+	<string>????</string>
21
+	<key>CFBundleVersion</key>
22
+	<string>1</string>
23
+</dict>
24
+</plist>

+ 541
- 44
Example/ios/Example.xcodeproj/project.pbxproj Ver fichero

22
 		13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
22
 		13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
23
 		140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
23
 		140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
24
 		146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
24
 		146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
25
-		50F9604CB69B4BA6A44EA44F /* libReactNativePermissions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D9820CCF930F4ED1BE137DA6 /* libReactNativePermissions.a */; };
25
+		14902CDAB1064113A6B4C970 /* libReactNativePermissions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B27CA08432F04FFCB0256EA1 /* libReactNativePermissions.a */; };
26
+		2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
27
+		2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
28
+		2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
29
+		2D02E4C21E0B4AEC006451C7 /* libRCTAnimation-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation-tvOS.a */; };
30
+		2D02E4C31E0B4AEC006451C7 /* libRCTImage-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */; };
31
+		2D02E4C41E0B4AEC006451C7 /* libRCTLinking-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */; };
32
+		2D02E4C51E0B4AEC006451C7 /* libRCTNetwork-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */; };
33
+		2D02E4C61E0B4AEC006451C7 /* libRCTSettings-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E901DF850E9000B6D8A /* libRCTSettings-tvOS.a */; };
34
+		2D02E4C71E0B4AEC006451C7 /* libRCTText-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E941DF850E9000B6D8A /* libRCTText-tvOS.a */; };
35
+		2D02E4C81E0B4AEC006451C7 /* libRCTWebSocket-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */; };
36
+		2D02E4C91E0B4AEC006451C7 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3EA31DF850E9000B6D8A /* libReact.a */; };
37
+		2DCD954D1E0B4F2C00145EB5 /* ExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* ExampleTests.m */; };
38
+		5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */; };
26
 		832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
39
 		832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
27
 /* End PBXBuildFile section */
40
 /* End PBXBuildFile section */
28
 
41
 
90
 			remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
103
 			remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
91
 			remoteInfo = React;
104
 			remoteInfo = React;
92
 		};
105
 		};
106
+		2D02E4911E0B4A5D006451C7 /* PBXContainerItemProxy */ = {
107
+			isa = PBXContainerItemProxy;
108
+			containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
109
+			proxyType = 1;
110
+			remoteGlobalIDString = 2D02E47A1E0B4A5D006451C7;
111
+			remoteInfo = "Example-tvOS";
112
+		};
113
+		3DAD3E831DF850E9000B6D8A /* PBXContainerItemProxy */ = {
114
+			isa = PBXContainerItemProxy;
115
+			containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
116
+			proxyType = 2;
117
+			remoteGlobalIDString = 2D2A283A1D9B042B00D4039D;
118
+			remoteInfo = "RCTImage-tvOS";
119
+		};
120
+		3DAD3E871DF850E9000B6D8A /* PBXContainerItemProxy */ = {
121
+			isa = PBXContainerItemProxy;
122
+			containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
123
+			proxyType = 2;
124
+			remoteGlobalIDString = 2D2A28471D9B043800D4039D;
125
+			remoteInfo = "RCTLinking-tvOS";
126
+		};
127
+		3DAD3E8B1DF850E9000B6D8A /* PBXContainerItemProxy */ = {
128
+			isa = PBXContainerItemProxy;
129
+			containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */;
130
+			proxyType = 2;
131
+			remoteGlobalIDString = 2D2A28541D9B044C00D4039D;
132
+			remoteInfo = "RCTNetwork-tvOS";
133
+		};
134
+		3DAD3E8F1DF850E9000B6D8A /* PBXContainerItemProxy */ = {
135
+			isa = PBXContainerItemProxy;
136
+			containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */;
137
+			proxyType = 2;
138
+			remoteGlobalIDString = 2D2A28611D9B046600D4039D;
139
+			remoteInfo = "RCTSettings-tvOS";
140
+		};
141
+		3DAD3E931DF850E9000B6D8A /* PBXContainerItemProxy */ = {
142
+			isa = PBXContainerItemProxy;
143
+			containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
144
+			proxyType = 2;
145
+			remoteGlobalIDString = 2D2A287B1D9B048500D4039D;
146
+			remoteInfo = "RCTText-tvOS";
147
+		};
148
+		3DAD3E981DF850E9000B6D8A /* PBXContainerItemProxy */ = {
149
+			isa = PBXContainerItemProxy;
150
+			containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
151
+			proxyType = 2;
152
+			remoteGlobalIDString = 2D2A28881D9B049200D4039D;
153
+			remoteInfo = "RCTWebSocket-tvOS";
154
+		};
155
+		3DAD3EA21DF850E9000B6D8A /* PBXContainerItemProxy */ = {
156
+			isa = PBXContainerItemProxy;
157
+			containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
158
+			proxyType = 2;
159
+			remoteGlobalIDString = 2D2A28131D9B038B00D4039D;
160
+			remoteInfo = "React-tvOS";
161
+		};
162
+		3DAD3EA41DF850E9000B6D8A /* PBXContainerItemProxy */ = {
163
+			isa = PBXContainerItemProxy;
164
+			containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
165
+			proxyType = 2;
166
+			remoteGlobalIDString = 3D3C059A1DE3340900C268FA;
167
+			remoteInfo = yoga;
168
+		};
169
+		3DAD3EA61DF850E9000B6D8A /* PBXContainerItemProxy */ = {
170
+			isa = PBXContainerItemProxy;
171
+			containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
172
+			proxyType = 2;
173
+			remoteGlobalIDString = 3D3C06751DE3340C00C268FA;
174
+			remoteInfo = "yoga-tvOS";
175
+		};
176
+		3DAD3EA81DF850E9000B6D8A /* PBXContainerItemProxy */ = {
177
+			isa = PBXContainerItemProxy;
178
+			containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
179
+			proxyType = 2;
180
+			remoteGlobalIDString = 3D3CD9251DE5FBEC00167DC4;
181
+			remoteInfo = cxxreact;
182
+		};
183
+		3DAD3EAA1DF850E9000B6D8A /* PBXContainerItemProxy */ = {
184
+			isa = PBXContainerItemProxy;
185
+			containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
186
+			proxyType = 2;
187
+			remoteGlobalIDString = 3D3CD9321DE5FBEE00167DC4;
188
+			remoteInfo = "cxxreact-tvOS";
189
+		};
190
+		3DAD3EAC1DF850E9000B6D8A /* PBXContainerItemProxy */ = {
191
+			isa = PBXContainerItemProxy;
192
+			containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
193
+			proxyType = 2;
194
+			remoteGlobalIDString = 3D3CD90B1DE5FBD600167DC4;
195
+			remoteInfo = jschelpers;
196
+		};
197
+		3DAD3EAE1DF850E9000B6D8A /* PBXContainerItemProxy */ = {
198
+			isa = PBXContainerItemProxy;
199
+			containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
200
+			proxyType = 2;
201
+			remoteGlobalIDString = 3D3CD9181DE5FBD800167DC4;
202
+			remoteInfo = "jschelpers-tvOS";
203
+		};
204
+		5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */ = {
205
+			isa = PBXContainerItemProxy;
206
+			containerPortal = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */;
207
+			proxyType = 2;
208
+			remoteGlobalIDString = 134814201AA4EA6300B7C361;
209
+			remoteInfo = RCTAnimation;
210
+		};
211
+		5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */ = {
212
+			isa = PBXContainerItemProxy;
213
+			containerPortal = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */;
214
+			proxyType = 2;
215
+			remoteGlobalIDString = 2D2A28201D9B03D100D4039D;
216
+			remoteInfo = "RCTAnimation-tvOS";
217
+		};
93
 		78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = {
218
 		78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = {
94
 			isa = PBXContainerItemProxy;
219
 			isa = PBXContainerItemProxy;
95
 			containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
220
 			containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
104
 			remoteGlobalIDString = 58B5119B1A9E6C1200147676;
229
 			remoteGlobalIDString = 58B5119B1A9E6C1200147676;
105
 			remoteInfo = RCTText;
230
 			remoteInfo = RCTText;
106
 		};
231
 		};
107
-		9D1B45CC1D49EE8400459C66 /* PBXContainerItemProxy */ = {
232
+		9D8131C41E44834800F4B1D3 /* PBXContainerItemProxy */ = {
108
 			isa = PBXContainerItemProxy;
233
 			isa = PBXContainerItemProxy;
109
-			containerPortal = 783F116470084EEB95DCA092 /* ReactNativePermissions.xcodeproj */;
234
+			containerPortal = 8068EB7451414340B0AC0D03 /* ReactNativePermissions.xcodeproj */;
110
 			proxyType = 2;
235
 			proxyType = 2;
111
 			remoteGlobalIDString = 9D23B34F1C767B80008B4819;
236
 			remoteGlobalIDString = 9D23B34F1C767B80008B4819;
112
 			remoteInfo = ReactNativePermissions;
237
 			remoteInfo = ReactNativePermissions;
133
 		13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Example/Info.plist; sourceTree = "<group>"; };
258
 		13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Example/Info.plist; sourceTree = "<group>"; };
134
 		13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Example/main.m; sourceTree = "<group>"; };
259
 		13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Example/main.m; sourceTree = "<group>"; };
135
 		146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; };
260
 		146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; };
136
-		783F116470084EEB95DCA092 /* ReactNativePermissions.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = ReactNativePermissions.xcodeproj; path = "../node_modules/react-native-permissions/ReactNativePermissions.xcodeproj"; sourceTree = "<group>"; };
261
+		2D02E47B1E0B4A5D006451C7 /* Example-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
262
+		2D02E4901E0B4A5D006451C7 /* Example-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Example-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
263
+		5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimation.xcodeproj; path = "../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj"; sourceTree = "<group>"; };
137
 		78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; };
264
 		78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; };
265
+		8068EB7451414340B0AC0D03 /* ReactNativePermissions.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = ReactNativePermissions.xcodeproj; path = "../node_modules/react-native-permissions/ReactNativePermissions.xcodeproj"; sourceTree = "<group>"; };
138
 		832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
266
 		832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
139
-		D9820CCF930F4ED1BE137DA6 /* libReactNativePermissions.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libReactNativePermissions.a; sourceTree = "<group>"; };
267
+		B27CA08432F04FFCB0256EA1 /* libReactNativePermissions.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libReactNativePermissions.a; sourceTree = "<group>"; };
140
 /* End PBXFileReference section */
268
 /* End PBXFileReference section */
141
 
269
 
142
 /* Begin PBXFrameworksBuildPhase section */
270
 /* Begin PBXFrameworksBuildPhase section */
153
 			buildActionMask = 2147483647;
281
 			buildActionMask = 2147483647;
154
 			files = (
282
 			files = (
155
 				146834051AC3E58100842450 /* libReact.a in Frameworks */,
283
 				146834051AC3E58100842450 /* libReact.a in Frameworks */,
284
+				5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */,
156
 				00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */,
285
 				00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */,
157
 				00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */,
286
 				00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */,
158
 				00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */,
287
 				00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */,
162
 				832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */,
291
 				832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */,
163
 				00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */,
292
 				00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */,
164
 				139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */,
293
 				139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */,
165
-				50F9604CB69B4BA6A44EA44F /* libReactNativePermissions.a in Frameworks */,
294
+				14902CDAB1064113A6B4C970 /* libReactNativePermissions.a in Frameworks */,
295
+			);
296
+			runOnlyForDeploymentPostprocessing = 0;
297
+		};
298
+		2D02E4781E0B4A5D006451C7 /* Frameworks */ = {
299
+			isa = PBXFrameworksBuildPhase;
300
+			buildActionMask = 2147483647;
301
+			files = (
302
+				2D02E4C91E0B4AEC006451C7 /* libReact.a in Frameworks */,
303
+				2D02E4C21E0B4AEC006451C7 /* libRCTAnimation-tvOS.a in Frameworks */,
304
+				2D02E4C31E0B4AEC006451C7 /* libRCTImage-tvOS.a in Frameworks */,
305
+				2D02E4C41E0B4AEC006451C7 /* libRCTLinking-tvOS.a in Frameworks */,
306
+				2D02E4C51E0B4AEC006451C7 /* libRCTNetwork-tvOS.a in Frameworks */,
307
+				2D02E4C61E0B4AEC006451C7 /* libRCTSettings-tvOS.a in Frameworks */,
308
+				2D02E4C71E0B4AEC006451C7 /* libRCTText-tvOS.a in Frameworks */,
309
+				2D02E4C81E0B4AEC006451C7 /* libRCTWebSocket-tvOS.a in Frameworks */,
310
+			);
311
+			runOnlyForDeploymentPostprocessing = 0;
312
+		};
313
+		2D02E48D1E0B4A5D006451C7 /* Frameworks */ = {
314
+			isa = PBXFrameworksBuildPhase;
315
+			buildActionMask = 2147483647;
316
+			files = (
166
 			);
317
 			);
167
 			runOnlyForDeploymentPostprocessing = 0;
318
 			runOnlyForDeploymentPostprocessing = 0;
168
 		};
319
 		};
189
 			isa = PBXGroup;
340
 			isa = PBXGroup;
190
 			children = (
341
 			children = (
191
 				00C302C01ABCB91800DB3ED1 /* libRCTImage.a */,
342
 				00C302C01ABCB91800DB3ED1 /* libRCTImage.a */,
343
+				3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */,
192
 			);
344
 			);
193
 			name = Products;
345
 			name = Products;
194
 			sourceTree = "<group>";
346
 			sourceTree = "<group>";
197
 			isa = PBXGroup;
349
 			isa = PBXGroup;
198
 			children = (
350
 			children = (
199
 				00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */,
351
 				00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */,
352
+				3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */,
200
 			);
353
 			);
201
 			name = Products;
354
 			name = Products;
202
 			sourceTree = "<group>";
355
 			sourceTree = "<group>";
230
 			isa = PBXGroup;
383
 			isa = PBXGroup;
231
 			children = (
384
 			children = (
232
 				139105C11AF99BAD00B5F7CC /* libRCTSettings.a */,
385
 				139105C11AF99BAD00B5F7CC /* libRCTSettings.a */,
386
+				3DAD3E901DF850E9000B6D8A /* libRCTSettings-tvOS.a */,
233
 			);
387
 			);
234
 			name = Products;
388
 			name = Products;
235
 			sourceTree = "<group>";
389
 			sourceTree = "<group>";
238
 			isa = PBXGroup;
392
 			isa = PBXGroup;
239
 			children = (
393
 			children = (
240
 				139FDEF41B06529B00C62182 /* libRCTWebSocket.a */,
394
 				139FDEF41B06529B00C62182 /* libRCTWebSocket.a */,
395
+				3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */,
241
 			);
396
 			);
242
 			name = Products;
397
 			name = Products;
243
 			sourceTree = "<group>";
398
 			sourceTree = "<group>";
260
 			isa = PBXGroup;
415
 			isa = PBXGroup;
261
 			children = (
416
 			children = (
262
 				146834041AC3E56700842450 /* libReact.a */,
417
 				146834041AC3E56700842450 /* libReact.a */,
418
+				3DAD3EA31DF850E9000B6D8A /* libReact.a */,
419
+				3DAD3EA51DF850E9000B6D8A /* libyoga.a */,
420
+				3DAD3EA71DF850E9000B6D8A /* libyoga.a */,
421
+				3DAD3EA91DF850E9000B6D8A /* libcxxreact.a */,
422
+				3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */,
423
+				3DAD3EAD1DF850E9000B6D8A /* libjschelpers.a */,
424
+				3DAD3EAF1DF850E9000B6D8A /* libjschelpers.a */,
425
+			);
426
+			name = Products;
427
+			sourceTree = "<group>";
428
+		};
429
+		5E91572E1DD0AC6500FF2AA8 /* Products */ = {
430
+			isa = PBXGroup;
431
+			children = (
432
+				5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */,
433
+				5E9157351DD0AC6500FF2AA8 /* libRCTAnimation-tvOS.a */,
263
 			);
434
 			);
264
 			name = Products;
435
 			name = Products;
265
 			sourceTree = "<group>";
436
 			sourceTree = "<group>";
268
 			isa = PBXGroup;
439
 			isa = PBXGroup;
269
 			children = (
440
 			children = (
270
 				78C398B91ACF4ADC00677621 /* libRCTLinking.a */,
441
 				78C398B91ACF4ADC00677621 /* libRCTLinking.a */,
442
+				3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */,
271
 			);
443
 			);
272
 			name = Products;
444
 			name = Products;
273
 			sourceTree = "<group>";
445
 			sourceTree = "<group>";
275
 		832341AE1AAA6A7D00B99B32 /* Libraries */ = {
447
 		832341AE1AAA6A7D00B99B32 /* Libraries */ = {
276
 			isa = PBXGroup;
448
 			isa = PBXGroup;
277
 			children = (
449
 			children = (
450
+				5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */,
278
 				146833FF1AC3E56700842450 /* React.xcodeproj */,
451
 				146833FF1AC3E56700842450 /* React.xcodeproj */,
279
 				00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */,
452
 				00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */,
280
 				00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */,
453
 				00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */,
285
 				832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */,
458
 				832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */,
286
 				00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */,
459
 				00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */,
287
 				139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */,
460
 				139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */,
288
-				783F116470084EEB95DCA092 /* ReactNativePermissions.xcodeproj */,
461
+				8068EB7451414340B0AC0D03 /* ReactNativePermissions.xcodeproj */,
289
 			);
462
 			);
290
 			name = Libraries;
463
 			name = Libraries;
291
 			sourceTree = "<group>";
464
 			sourceTree = "<group>";
294
 			isa = PBXGroup;
467
 			isa = PBXGroup;
295
 			children = (
468
 			children = (
296
 				832341B51AAA6A8300B99B32 /* libRCTText.a */,
469
 				832341B51AAA6A8300B99B32 /* libRCTText.a */,
470
+				3DAD3E941DF850E9000B6D8A /* libRCTText-tvOS.a */,
297
 			);
471
 			);
298
 			name = Products;
472
 			name = Products;
299
 			sourceTree = "<group>";
473
 			sourceTree = "<group>";
315
 			children = (
489
 			children = (
316
 				13B07F961A680F5B00A75B9A /* Example.app */,
490
 				13B07F961A680F5B00A75B9A /* Example.app */,
317
 				00E356EE1AD99517003FC87E /* ExampleTests.xctest */,
491
 				00E356EE1AD99517003FC87E /* ExampleTests.xctest */,
492
+				2D02E47B1E0B4A5D006451C7 /* Example-tvOS.app */,
493
+				2D02E4901E0B4A5D006451C7 /* Example-tvOSTests.xctest */,
318
 			);
494
 			);
319
 			name = Products;
495
 			name = Products;
320
 			sourceTree = "<group>";
496
 			sourceTree = "<group>";
321
 		};
497
 		};
322
-		9D1B45BF1D49EE8300459C66 /* Products */ = {
498
+		9D8131A81E44834700F4B1D3 /* Products */ = {
323
 			isa = PBXGroup;
499
 			isa = PBXGroup;
324
 			children = (
500
 			children = (
325
-				9D1B45CD1D49EE8400459C66 /* libReactNativePermissions.a */,
501
+				9D8131C51E44834800F4B1D3 /* libReactNativePermissions.a */,
326
 			);
502
 			);
327
 			name = Products;
503
 			name = Products;
328
 			sourceTree = "<group>";
504
 			sourceTree = "<group>";
366
 			productReference = 13B07F961A680F5B00A75B9A /* Example.app */;
542
 			productReference = 13B07F961A680F5B00A75B9A /* Example.app */;
367
 			productType = "com.apple.product-type.application";
543
 			productType = "com.apple.product-type.application";
368
 		};
544
 		};
545
+		2D02E47A1E0B4A5D006451C7 /* Example-tvOS */ = {
546
+			isa = PBXNativeTarget;
547
+			buildConfigurationList = 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "Example-tvOS" */;
548
+			buildPhases = (
549
+				2D02E4771E0B4A5D006451C7 /* Sources */,
550
+				2D02E4781E0B4A5D006451C7 /* Frameworks */,
551
+				2D02E4791E0B4A5D006451C7 /* Resources */,
552
+				2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */,
553
+			);
554
+			buildRules = (
555
+			);
556
+			dependencies = (
557
+			);
558
+			name = "Example-tvOS";
559
+			productName = "Example-tvOS";
560
+			productReference = 2D02E47B1E0B4A5D006451C7 /* Example-tvOS.app */;
561
+			productType = "com.apple.product-type.application";
562
+		};
563
+		2D02E48F1E0B4A5D006451C7 /* Example-tvOSTests */ = {
564
+			isa = PBXNativeTarget;
565
+			buildConfigurationList = 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "Example-tvOSTests" */;
566
+			buildPhases = (
567
+				2D02E48C1E0B4A5D006451C7 /* Sources */,
568
+				2D02E48D1E0B4A5D006451C7 /* Frameworks */,
569
+				2D02E48E1E0B4A5D006451C7 /* Resources */,
570
+			);
571
+			buildRules = (
572
+			);
573
+			dependencies = (
574
+				2D02E4921E0B4A5D006451C7 /* PBXTargetDependency */,
575
+			);
576
+			name = "Example-tvOSTests";
577
+			productName = "Example-tvOSTests";
578
+			productReference = 2D02E4901E0B4A5D006451C7 /* Example-tvOSTests.xctest */;
579
+			productType = "com.apple.product-type.bundle.unit-test";
580
+		};
369
 /* End PBXNativeTarget section */
581
 /* End PBXNativeTarget section */
370
 
582
 
371
 /* Begin PBXProject section */
583
 /* Begin PBXProject section */
372
 		83CBB9F71A601CBA00E9B192 /* Project object */ = {
584
 		83CBB9F71A601CBA00E9B192 /* Project object */ = {
373
 			isa = PBXProject;
585
 			isa = PBXProject;
374
 			attributes = {
586
 			attributes = {
375
-				LastUpgradeCheck = 610;
587
+				LastUpgradeCheck = 0820;
376
 				ORGANIZATIONNAME = Facebook;
588
 				ORGANIZATIONNAME = Facebook;
377
 				TargetAttributes = {
589
 				TargetAttributes = {
378
 					00E356ED1AD99517003FC87E = {
590
 					00E356ED1AD99517003FC87E = {
386
 							};
598
 							};
387
 						};
599
 						};
388
 					};
600
 					};
601
+					2D02E47A1E0B4A5D006451C7 = {
602
+						CreatedOnToolsVersion = 8.2.1;
603
+						ProvisioningStyle = Automatic;
604
+					};
605
+					2D02E48F1E0B4A5D006451C7 = {
606
+						CreatedOnToolsVersion = 8.2.1;
607
+						ProvisioningStyle = Automatic;
608
+						TestTargetID = 2D02E47A1E0B4A5D006451C7;
609
+					};
389
 				};
610
 				};
390
 			};
611
 			};
391
 			buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Example" */;
612
 			buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Example" */;
404
 					ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */;
625
 					ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */;
405
 					ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */;
626
 					ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */;
406
 				},
627
 				},
628
+				{
629
+					ProductGroup = 5E91572E1DD0AC6500FF2AA8 /* Products */;
630
+					ProjectRef = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */;
631
+				},
407
 				{
632
 				{
408
 					ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */;
633
 					ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */;
409
 					ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */;
634
 					ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */;
441
 					ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */;
666
 					ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */;
442
 				},
667
 				},
443
 				{
668
 				{
444
-					ProductGroup = 9D1B45BF1D49EE8300459C66 /* Products */;
445
-					ProjectRef = 783F116470084EEB95DCA092 /* ReactNativePermissions.xcodeproj */;
669
+					ProductGroup = 9D8131A81E44834700F4B1D3 /* Products */;
670
+					ProjectRef = 8068EB7451414340B0AC0D03 /* ReactNativePermissions.xcodeproj */;
446
 				},
671
 				},
447
 			);
672
 			);
448
 			projectRoot = "";
673
 			projectRoot = "";
449
 			targets = (
674
 			targets = (
450
 				13B07F861A680F5B00A75B9A /* Example */,
675
 				13B07F861A680F5B00A75B9A /* Example */,
451
 				00E356ED1AD99517003FC87E /* ExampleTests */,
676
 				00E356ED1AD99517003FC87E /* ExampleTests */,
677
+				2D02E47A1E0B4A5D006451C7 /* Example-tvOS */,
678
+				2D02E48F1E0B4A5D006451C7 /* Example-tvOSTests */,
452
 			);
679
 			);
453
 		};
680
 		};
454
 /* End PBXProject section */
681
 /* End PBXProject section */
510
 			remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */;
737
 			remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */;
511
 			sourceTree = BUILT_PRODUCTS_DIR;
738
 			sourceTree = BUILT_PRODUCTS_DIR;
512
 		};
739
 		};
740
+		3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */ = {
741
+			isa = PBXReferenceProxy;
742
+			fileType = archive.ar;
743
+			path = "libRCTImage-tvOS.a";
744
+			remoteRef = 3DAD3E831DF850E9000B6D8A /* PBXContainerItemProxy */;
745
+			sourceTree = BUILT_PRODUCTS_DIR;
746
+		};
747
+		3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */ = {
748
+			isa = PBXReferenceProxy;
749
+			fileType = archive.ar;
750
+			path = "libRCTLinking-tvOS.a";
751
+			remoteRef = 3DAD3E871DF850E9000B6D8A /* PBXContainerItemProxy */;
752
+			sourceTree = BUILT_PRODUCTS_DIR;
753
+		};
754
+		3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */ = {
755
+			isa = PBXReferenceProxy;
756
+			fileType = archive.ar;
757
+			path = "libRCTNetwork-tvOS.a";
758
+			remoteRef = 3DAD3E8B1DF850E9000B6D8A /* PBXContainerItemProxy */;
759
+			sourceTree = BUILT_PRODUCTS_DIR;
760
+		};
761
+		3DAD3E901DF850E9000B6D8A /* libRCTSettings-tvOS.a */ = {
762
+			isa = PBXReferenceProxy;
763
+			fileType = archive.ar;
764
+			path = "libRCTSettings-tvOS.a";
765
+			remoteRef = 3DAD3E8F1DF850E9000B6D8A /* PBXContainerItemProxy */;
766
+			sourceTree = BUILT_PRODUCTS_DIR;
767
+		};
768
+		3DAD3E941DF850E9000B6D8A /* libRCTText-tvOS.a */ = {
769
+			isa = PBXReferenceProxy;
770
+			fileType = archive.ar;
771
+			path = "libRCTText-tvOS.a";
772
+			remoteRef = 3DAD3E931DF850E9000B6D8A /* PBXContainerItemProxy */;
773
+			sourceTree = BUILT_PRODUCTS_DIR;
774
+		};
775
+		3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */ = {
776
+			isa = PBXReferenceProxy;
777
+			fileType = archive.ar;
778
+			path = "libRCTWebSocket-tvOS.a";
779
+			remoteRef = 3DAD3E981DF850E9000B6D8A /* PBXContainerItemProxy */;
780
+			sourceTree = BUILT_PRODUCTS_DIR;
781
+		};
782
+		3DAD3EA31DF850E9000B6D8A /* libReact.a */ = {
783
+			isa = PBXReferenceProxy;
784
+			fileType = archive.ar;
785
+			path = libReact.a;
786
+			remoteRef = 3DAD3EA21DF850E9000B6D8A /* PBXContainerItemProxy */;
787
+			sourceTree = BUILT_PRODUCTS_DIR;
788
+		};
789
+		3DAD3EA51DF850E9000B6D8A /* libyoga.a */ = {
790
+			isa = PBXReferenceProxy;
791
+			fileType = archive.ar;
792
+			path = libyoga.a;
793
+			remoteRef = 3DAD3EA41DF850E9000B6D8A /* PBXContainerItemProxy */;
794
+			sourceTree = BUILT_PRODUCTS_DIR;
795
+		};
796
+		3DAD3EA71DF850E9000B6D8A /* libyoga.a */ = {
797
+			isa = PBXReferenceProxy;
798
+			fileType = archive.ar;
799
+			path = libyoga.a;
800
+			remoteRef = 3DAD3EA61DF850E9000B6D8A /* PBXContainerItemProxy */;
801
+			sourceTree = BUILT_PRODUCTS_DIR;
802
+		};
803
+		3DAD3EA91DF850E9000B6D8A /* libcxxreact.a */ = {
804
+			isa = PBXReferenceProxy;
805
+			fileType = archive.ar;
806
+			path = libcxxreact.a;
807
+			remoteRef = 3DAD3EA81DF850E9000B6D8A /* PBXContainerItemProxy */;
808
+			sourceTree = BUILT_PRODUCTS_DIR;
809
+		};
810
+		3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */ = {
811
+			isa = PBXReferenceProxy;
812
+			fileType = archive.ar;
813
+			path = libcxxreact.a;
814
+			remoteRef = 3DAD3EAA1DF850E9000B6D8A /* PBXContainerItemProxy */;
815
+			sourceTree = BUILT_PRODUCTS_DIR;
816
+		};
817
+		3DAD3EAD1DF850E9000B6D8A /* libjschelpers.a */ = {
818
+			isa = PBXReferenceProxy;
819
+			fileType = archive.ar;
820
+			path = libjschelpers.a;
821
+			remoteRef = 3DAD3EAC1DF850E9000B6D8A /* PBXContainerItemProxy */;
822
+			sourceTree = BUILT_PRODUCTS_DIR;
823
+		};
824
+		3DAD3EAF1DF850E9000B6D8A /* libjschelpers.a */ = {
825
+			isa = PBXReferenceProxy;
826
+			fileType = archive.ar;
827
+			path = libjschelpers.a;
828
+			remoteRef = 3DAD3EAE1DF850E9000B6D8A /* PBXContainerItemProxy */;
829
+			sourceTree = BUILT_PRODUCTS_DIR;
830
+		};
831
+		5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */ = {
832
+			isa = PBXReferenceProxy;
833
+			fileType = archive.ar;
834
+			path = libRCTAnimation.a;
835
+			remoteRef = 5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */;
836
+			sourceTree = BUILT_PRODUCTS_DIR;
837
+		};
838
+		5E9157351DD0AC6500FF2AA8 /* libRCTAnimation-tvOS.a */ = {
839
+			isa = PBXReferenceProxy;
840
+			fileType = archive.ar;
841
+			path = "libRCTAnimation-tvOS.a";
842
+			remoteRef = 5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */;
843
+			sourceTree = BUILT_PRODUCTS_DIR;
844
+		};
513
 		78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = {
845
 		78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = {
514
 			isa = PBXReferenceProxy;
846
 			isa = PBXReferenceProxy;
515
 			fileType = archive.ar;
847
 			fileType = archive.ar;
524
 			remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */;
856
 			remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */;
525
 			sourceTree = BUILT_PRODUCTS_DIR;
857
 			sourceTree = BUILT_PRODUCTS_DIR;
526
 		};
858
 		};
527
-		9D1B45CD1D49EE8400459C66 /* libReactNativePermissions.a */ = {
859
+		9D8131C51E44834800F4B1D3 /* libReactNativePermissions.a */ = {
528
 			isa = PBXReferenceProxy;
860
 			isa = PBXReferenceProxy;
529
 			fileType = archive.ar;
861
 			fileType = archive.ar;
530
 			path = libReactNativePermissions.a;
862
 			path = libReactNativePermissions.a;
531
-			remoteRef = 9D1B45CC1D49EE8400459C66 /* PBXContainerItemProxy */;
863
+			remoteRef = 9D8131C41E44834800F4B1D3 /* PBXContainerItemProxy */;
532
 			sourceTree = BUILT_PRODUCTS_DIR;
864
 			sourceTree = BUILT_PRODUCTS_DIR;
533
 		};
865
 		};
534
 /* End PBXReferenceProxy section */
866
 /* End PBXReferenceProxy section */
550
 			);
882
 			);
551
 			runOnlyForDeploymentPostprocessing = 0;
883
 			runOnlyForDeploymentPostprocessing = 0;
552
 		};
884
 		};
885
+		2D02E4791E0B4A5D006451C7 /* Resources */ = {
886
+			isa = PBXResourcesBuildPhase;
887
+			buildActionMask = 2147483647;
888
+			files = (
889
+				2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */,
890
+			);
891
+			runOnlyForDeploymentPostprocessing = 0;
892
+		};
893
+		2D02E48E1E0B4A5D006451C7 /* Resources */ = {
894
+			isa = PBXResourcesBuildPhase;
895
+			buildActionMask = 2147483647;
896
+			files = (
897
+			);
898
+			runOnlyForDeploymentPostprocessing = 0;
899
+		};
553
 /* End PBXResourcesBuildPhase section */
900
 /* End PBXResourcesBuildPhase section */
554
 
901
 
555
 /* Begin PBXShellScriptBuildPhase section */
902
 /* Begin PBXShellScriptBuildPhase section */
567
 			shellPath = /bin/sh;
914
 			shellPath = /bin/sh;
568
 			shellScript = "export NODE_BINARY=node\n../node_modules/react-native/packager/react-native-xcode.sh";
915
 			shellScript = "export NODE_BINARY=node\n../node_modules/react-native/packager/react-native-xcode.sh";
569
 		};
916
 		};
917
+		2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */ = {
918
+			isa = PBXShellScriptBuildPhase;
919
+			buildActionMask = 2147483647;
920
+			files = (
921
+			);
922
+			inputPaths = (
923
+			);
924
+			name = "Bundle React Native Code And Images";
925
+			outputPaths = (
926
+			);
927
+			runOnlyForDeploymentPostprocessing = 0;
928
+			shellPath = /bin/sh;
929
+			shellScript = "export NODE_BINARY=node\n../node_modules/react-native/packager/react-native-xcode.sh";
930
+		};
570
 /* End PBXShellScriptBuildPhase section */
931
 /* End PBXShellScriptBuildPhase section */
571
 
932
 
572
 /* Begin PBXSourcesBuildPhase section */
933
 /* Begin PBXSourcesBuildPhase section */
587
 			);
948
 			);
588
 			runOnlyForDeploymentPostprocessing = 0;
949
 			runOnlyForDeploymentPostprocessing = 0;
589
 		};
950
 		};
951
+		2D02E4771E0B4A5D006451C7 /* Sources */ = {
952
+			isa = PBXSourcesBuildPhase;
953
+			buildActionMask = 2147483647;
954
+			files = (
955
+				2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */,
956
+				2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */,
957
+			);
958
+			runOnlyForDeploymentPostprocessing = 0;
959
+		};
960
+		2D02E48C1E0B4A5D006451C7 /* Sources */ = {
961
+			isa = PBXSourcesBuildPhase;
962
+			buildActionMask = 2147483647;
963
+			files = (
964
+				2DCD954D1E0B4F2C00145EB5 /* ExampleTests.m in Sources */,
965
+			);
966
+			runOnlyForDeploymentPostprocessing = 0;
967
+		};
590
 /* End PBXSourcesBuildPhase section */
968
 /* End PBXSourcesBuildPhase section */
591
 
969
 
592
 /* Begin PBXTargetDependency section */
970
 /* Begin PBXTargetDependency section */
595
 			target = 13B07F861A680F5B00A75B9A /* Example */;
973
 			target = 13B07F861A680F5B00A75B9A /* Example */;
596
 			targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */;
974
 			targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */;
597
 		};
975
 		};
976
+		2D02E4921E0B4A5D006451C7 /* PBXTargetDependency */ = {
977
+			isa = PBXTargetDependency;
978
+			target = 2D02E47A1E0B4A5D006451C7 /* Example-tvOS */;
979
+			targetProxy = 2D02E4911E0B4A5D006451C7 /* PBXContainerItemProxy */;
980
+		};
598
 /* End PBXTargetDependency section */
981
 /* End PBXTargetDependency section */
599
 
982
 
600
 /* Begin PBXVariantGroup section */
983
 /* Begin PBXVariantGroup section */
619
 					"$(inherited)",
1002
 					"$(inherited)",
620
 				);
1003
 				);
621
 				INFOPLIST_FILE = ExampleTests/Info.plist;
1004
 				INFOPLIST_FILE = ExampleTests/Info.plist;
622
-				IPHONEOS_DEPLOYMENT_TARGET = 8.2;
1005
+				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
623
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
1006
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
624
 				LIBRARY_SEARCH_PATHS = (
1007
 				LIBRARY_SEARCH_PATHS = (
625
 					"$(inherited)",
1008
 					"$(inherited)",
626
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1009
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
627
 				);
1010
 				);
1011
+				OTHER_LDFLAGS = (
1012
+					"-ObjC",
1013
+					"-lc++",
1014
+				);
628
 				PRODUCT_NAME = "$(TARGET_NAME)";
1015
 				PRODUCT_NAME = "$(TARGET_NAME)";
629
 				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example";
1016
 				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example";
630
 			};
1017
 			};
636
 				BUNDLE_LOADER = "$(TEST_HOST)";
1023
 				BUNDLE_LOADER = "$(TEST_HOST)";
637
 				COPY_PHASE_STRIP = NO;
1024
 				COPY_PHASE_STRIP = NO;
638
 				INFOPLIST_FILE = ExampleTests/Info.plist;
1025
 				INFOPLIST_FILE = ExampleTests/Info.plist;
639
-				IPHONEOS_DEPLOYMENT_TARGET = 8.2;
1026
+				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
640
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
1027
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
641
 				LIBRARY_SEARCH_PATHS = (
1028
 				LIBRARY_SEARCH_PATHS = (
642
 					"$(inherited)",
1029
 					"$(inherited)",
643
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1030
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
644
 				);
1031
 				);
1032
+				OTHER_LDFLAGS = (
1033
+					"-ObjC",
1034
+					"-lc++",
1035
+				);
645
 				PRODUCT_NAME = "$(TARGET_NAME)";
1036
 				PRODUCT_NAME = "$(TARGET_NAME)";
646
 				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example";
1037
 				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example";
647
 			};
1038
 			};
651
 			isa = XCBuildConfiguration;
1042
 			isa = XCBuildConfiguration;
652
 			buildSettings = {
1043
 			buildSettings = {
653
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
1044
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
1045
+				CURRENT_PROJECT_VERSION = 1;
654
 				DEAD_CODE_STRIPPING = NO;
1046
 				DEAD_CODE_STRIPPING = NO;
655
-				HEADER_SEARCH_PATHS = (
656
-					"$(inherited)",
657
-					/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
658
-					"$(SRCROOT)/../node_modules/react-native/React/**",
659
-					"$(SRCROOT)/../node_modules/react-native-permissions/**",
660
-				);
661
 				INFOPLIST_FILE = Example/Info.plist;
1047
 				INFOPLIST_FILE = Example/Info.plist;
662
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
663
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
1048
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
664
 				OTHER_LDFLAGS = (
1049
 				OTHER_LDFLAGS = (
665
 					"$(inherited)",
1050
 					"$(inherited)",
667
 					"-lc++",
1052
 					"-lc++",
668
 				);
1053
 				);
669
 				PRODUCT_NAME = Example;
1054
 				PRODUCT_NAME = Example;
1055
+				VERSIONING_SYSTEM = "apple-generic";
670
 			};
1056
 			};
671
 			name = Debug;
1057
 			name = Debug;
672
 		};
1058
 		};
674
 			isa = XCBuildConfiguration;
1060
 			isa = XCBuildConfiguration;
675
 			buildSettings = {
1061
 			buildSettings = {
676
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
1062
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
677
-				HEADER_SEARCH_PATHS = (
678
-					"$(inherited)",
679
-					/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
680
-					"$(SRCROOT)/../node_modules/react-native/React/**",
681
-					"$(SRCROOT)/../node_modules/react-native-permissions/**",
682
-				);
1063
+				CURRENT_PROJECT_VERSION = 1;
683
 				INFOPLIST_FILE = Example/Info.plist;
1064
 				INFOPLIST_FILE = Example/Info.plist;
684
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
685
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
1065
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
686
 				OTHER_LDFLAGS = (
1066
 				OTHER_LDFLAGS = (
687
 					"$(inherited)",
1067
 					"$(inherited)",
689
 					"-lc++",
1069
 					"-lc++",
690
 				);
1070
 				);
691
 				PRODUCT_NAME = Example;
1071
 				PRODUCT_NAME = Example;
1072
+				VERSIONING_SYSTEM = "apple-generic";
1073
+			};
1074
+			name = Release;
1075
+		};
1076
+		2D02E4971E0B4A5E006451C7 /* Debug */ = {
1077
+			isa = XCBuildConfiguration;
1078
+			buildSettings = {
1079
+				ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
1080
+				ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
1081
+				CLANG_ANALYZER_NONNULL = YES;
1082
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
1083
+				CLANG_WARN_INFINITE_RECURSION = YES;
1084
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
1085
+				DEBUG_INFORMATION_FORMAT = dwarf;
1086
+				ENABLE_TESTABILITY = YES;
1087
+				GCC_NO_COMMON_BLOCKS = YES;
1088
+				INFOPLIST_FILE = "Example-tvOS/Info.plist";
1089
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
1090
+				LIBRARY_SEARCH_PATHS = (
1091
+					"$(inherited)",
1092
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1093
+				);
1094
+				OTHER_LDFLAGS = (
1095
+					"-ObjC",
1096
+					"-lc++",
1097
+				);
1098
+				PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.Example-tvOS";
1099
+				PRODUCT_NAME = "$(TARGET_NAME)";
1100
+				SDKROOT = appletvos;
1101
+				TARGETED_DEVICE_FAMILY = 3;
1102
+				TVOS_DEPLOYMENT_TARGET = 9.2;
1103
+			};
1104
+			name = Debug;
1105
+		};
1106
+		2D02E4981E0B4A5E006451C7 /* Release */ = {
1107
+			isa = XCBuildConfiguration;
1108
+			buildSettings = {
1109
+				ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
1110
+				ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
1111
+				CLANG_ANALYZER_NONNULL = YES;
1112
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
1113
+				CLANG_WARN_INFINITE_RECURSION = YES;
1114
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
1115
+				COPY_PHASE_STRIP = NO;
1116
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
1117
+				GCC_NO_COMMON_BLOCKS = YES;
1118
+				INFOPLIST_FILE = "Example-tvOS/Info.plist";
1119
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
1120
+				LIBRARY_SEARCH_PATHS = (
1121
+					"$(inherited)",
1122
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1123
+				);
1124
+				OTHER_LDFLAGS = (
1125
+					"-ObjC",
1126
+					"-lc++",
1127
+				);
1128
+				PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.Example-tvOS";
1129
+				PRODUCT_NAME = "$(TARGET_NAME)";
1130
+				SDKROOT = appletvos;
1131
+				TARGETED_DEVICE_FAMILY = 3;
1132
+				TVOS_DEPLOYMENT_TARGET = 9.2;
1133
+			};
1134
+			name = Release;
1135
+		};
1136
+		2D02E4991E0B4A5E006451C7 /* Debug */ = {
1137
+			isa = XCBuildConfiguration;
1138
+			buildSettings = {
1139
+				BUNDLE_LOADER = "$(TEST_HOST)";
1140
+				CLANG_ANALYZER_NONNULL = YES;
1141
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
1142
+				CLANG_WARN_INFINITE_RECURSION = YES;
1143
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
1144
+				DEBUG_INFORMATION_FORMAT = dwarf;
1145
+				ENABLE_TESTABILITY = YES;
1146
+				GCC_NO_COMMON_BLOCKS = YES;
1147
+				INFOPLIST_FILE = "Example-tvOSTests/Info.plist";
1148
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
1149
+				LIBRARY_SEARCH_PATHS = (
1150
+					"$(inherited)",
1151
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1152
+				);
1153
+				PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.Example-tvOSTests";
1154
+				PRODUCT_NAME = "$(TARGET_NAME)";
1155
+				SDKROOT = appletvos;
1156
+				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example-tvOS.app/Example-tvOS";
1157
+				TVOS_DEPLOYMENT_TARGET = 10.1;
1158
+			};
1159
+			name = Debug;
1160
+		};
1161
+		2D02E49A1E0B4A5E006451C7 /* Release */ = {
1162
+			isa = XCBuildConfiguration;
1163
+			buildSettings = {
1164
+				BUNDLE_LOADER = "$(TEST_HOST)";
1165
+				CLANG_ANALYZER_NONNULL = YES;
1166
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
1167
+				CLANG_WARN_INFINITE_RECURSION = YES;
1168
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
1169
+				COPY_PHASE_STRIP = NO;
1170
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
1171
+				GCC_NO_COMMON_BLOCKS = YES;
1172
+				INFOPLIST_FILE = "Example-tvOSTests/Info.plist";
1173
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
1174
+				LIBRARY_SEARCH_PATHS = (
1175
+					"$(inherited)",
1176
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
1177
+				);
1178
+				PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.Example-tvOSTests";
1179
+				PRODUCT_NAME = "$(TARGET_NAME)";
1180
+				SDKROOT = appletvos;
1181
+				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example-tvOS.app/Example-tvOS";
1182
+				TVOS_DEPLOYMENT_TARGET = 10.1;
692
 			};
1183
 			};
693
 			name = Release;
1184
 			name = Release;
694
 		};
1185
 		};
726
 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
1217
 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
727
 				GCC_WARN_UNUSED_FUNCTION = YES;
1218
 				GCC_WARN_UNUSED_FUNCTION = YES;
728
 				GCC_WARN_UNUSED_VARIABLE = YES;
1219
 				GCC_WARN_UNUSED_VARIABLE = YES;
729
-				HEADER_SEARCH_PATHS = (
730
-					"$(inherited)",
731
-					/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
732
-					"$(SRCROOT)/../node_modules/react-native/React/**",
733
-					"$(SRCROOT)/../node_modules/react-native-permissions/**",
734
-				);
735
-				IPHONEOS_DEPLOYMENT_TARGET = 7.0;
1220
+				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
736
 				MTL_ENABLE_DEBUG_INFO = YES;
1221
 				MTL_ENABLE_DEBUG_INFO = YES;
737
 				ONLY_ACTIVE_ARCH = YES;
1222
 				ONLY_ACTIVE_ARCH = YES;
738
 				SDKROOT = iphoneos;
1223
 				SDKROOT = iphoneos;
767
 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
1252
 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
768
 				GCC_WARN_UNUSED_FUNCTION = YES;
1253
 				GCC_WARN_UNUSED_FUNCTION = YES;
769
 				GCC_WARN_UNUSED_VARIABLE = YES;
1254
 				GCC_WARN_UNUSED_VARIABLE = YES;
770
-				HEADER_SEARCH_PATHS = (
771
-					"$(inherited)",
772
-					/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
773
-					"$(SRCROOT)/../node_modules/react-native/React/**",
774
-					"$(SRCROOT)/../node_modules/react-native-permissions/**",
775
-				);
776
-				IPHONEOS_DEPLOYMENT_TARGET = 7.0;
1255
+				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
777
 				MTL_ENABLE_DEBUG_INFO = NO;
1256
 				MTL_ENABLE_DEBUG_INFO = NO;
778
 				SDKROOT = iphoneos;
1257
 				SDKROOT = iphoneos;
779
 				VALIDATE_PRODUCT = YES;
1258
 				VALIDATE_PRODUCT = YES;
801
 			defaultConfigurationIsVisible = 0;
1280
 			defaultConfigurationIsVisible = 0;
802
 			defaultConfigurationName = Release;
1281
 			defaultConfigurationName = Release;
803
 		};
1282
 		};
1283
+		2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "Example-tvOS" */ = {
1284
+			isa = XCConfigurationList;
1285
+			buildConfigurations = (
1286
+				2D02E4971E0B4A5E006451C7 /* Debug */,
1287
+				2D02E4981E0B4A5E006451C7 /* Release */,
1288
+			);
1289
+			defaultConfigurationIsVisible = 0;
1290
+			defaultConfigurationName = Release;
1291
+		};
1292
+		2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "Example-tvOSTests" */ = {
1293
+			isa = XCConfigurationList;
1294
+			buildConfigurations = (
1295
+				2D02E4991E0B4A5E006451C7 /* Debug */,
1296
+				2D02E49A1E0B4A5E006451C7 /* Release */,
1297
+			);
1298
+			defaultConfigurationIsVisible = 0;
1299
+			defaultConfigurationName = Release;
1300
+		};
804
 		83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Example" */ = {
1301
 		83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Example" */ = {
805
 			isa = XCConfigurationList;
1302
 			isa = XCConfigurationList;
806
 			buildConfigurations = (
1303
 			buildConfigurations = (

+ 129
- 0
Example/ios/Example.xcodeproj/xcshareddata/xcschemes/Example-tvOS.xcscheme Ver fichero

1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<Scheme
3
+   LastUpgradeVersion = "0820"
4
+   version = "1.3">
5
+   <BuildAction
6
+      parallelizeBuildables = "NO"
7
+      buildImplicitDependencies = "YES">
8
+      <BuildActionEntries>
9
+         <BuildActionEntry
10
+            buildForTesting = "YES"
11
+            buildForRunning = "YES"
12
+            buildForProfiling = "YES"
13
+            buildForArchiving = "YES"
14
+            buildForAnalyzing = "YES">
15
+            <BuildableReference
16
+               BuildableIdentifier = "primary"
17
+               BlueprintIdentifier = "2D2A28121D9B038B00D4039D"
18
+               BuildableName = "libReact.a"
19
+               BlueprintName = "React-tvOS"
20
+               ReferencedContainer = "container:../node_modules/react-native/React/React.xcodeproj">
21
+            </BuildableReference>
22
+         </BuildActionEntry>
23
+         <BuildActionEntry
24
+            buildForTesting = "YES"
25
+            buildForRunning = "YES"
26
+            buildForProfiling = "YES"
27
+            buildForArchiving = "YES"
28
+            buildForAnalyzing = "YES">
29
+            <BuildableReference
30
+               BuildableIdentifier = "primary"
31
+               BlueprintIdentifier = "2D02E47A1E0B4A5D006451C7"
32
+               BuildableName = "Example-tvOS.app"
33
+               BlueprintName = "Example-tvOS"
34
+               ReferencedContainer = "container:Example.xcodeproj">
35
+            </BuildableReference>
36
+         </BuildActionEntry>
37
+         <BuildActionEntry
38
+            buildForTesting = "YES"
39
+            buildForRunning = "YES"
40
+            buildForProfiling = "NO"
41
+            buildForArchiving = "NO"
42
+            buildForAnalyzing = "YES">
43
+            <BuildableReference
44
+               BuildableIdentifier = "primary"
45
+               BlueprintIdentifier = "2D02E48F1E0B4A5D006451C7"
46
+               BuildableName = "Example-tvOSTests.xctest"
47
+               BlueprintName = "Example-tvOSTests"
48
+               ReferencedContainer = "container:Example.xcodeproj">
49
+            </BuildableReference>
50
+         </BuildActionEntry>
51
+      </BuildActionEntries>
52
+   </BuildAction>
53
+   <TestAction
54
+      buildConfiguration = "Debug"
55
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
56
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
57
+      shouldUseLaunchSchemeArgsEnv = "YES">
58
+      <Testables>
59
+         <TestableReference
60
+            skipped = "NO">
61
+            <BuildableReference
62
+               BuildableIdentifier = "primary"
63
+               BlueprintIdentifier = "2D02E48F1E0B4A5D006451C7"
64
+               BuildableName = "Example-tvOSTests.xctest"
65
+               BlueprintName = "Example-tvOSTests"
66
+               ReferencedContainer = "container:Example.xcodeproj">
67
+            </BuildableReference>
68
+         </TestableReference>
69
+      </Testables>
70
+      <MacroExpansion>
71
+         <BuildableReference
72
+            BuildableIdentifier = "primary"
73
+            BlueprintIdentifier = "2D02E47A1E0B4A5D006451C7"
74
+            BuildableName = "Example-tvOS.app"
75
+            BlueprintName = "Example-tvOS"
76
+            ReferencedContainer = "container:Example.xcodeproj">
77
+         </BuildableReference>
78
+      </MacroExpansion>
79
+      <AdditionalOptions>
80
+      </AdditionalOptions>
81
+   </TestAction>
82
+   <LaunchAction
83
+      buildConfiguration = "Debug"
84
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
85
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
86
+      launchStyle = "0"
87
+      useCustomWorkingDirectory = "NO"
88
+      ignoresPersistentStateOnLaunch = "NO"
89
+      debugDocumentVersioning = "YES"
90
+      debugServiceExtension = "internal"
91
+      allowLocationSimulation = "YES">
92
+      <BuildableProductRunnable
93
+         runnableDebuggingMode = "0">
94
+         <BuildableReference
95
+            BuildableIdentifier = "primary"
96
+            BlueprintIdentifier = "2D02E47A1E0B4A5D006451C7"
97
+            BuildableName = "Example-tvOS.app"
98
+            BlueprintName = "Example-tvOS"
99
+            ReferencedContainer = "container:Example.xcodeproj">
100
+         </BuildableReference>
101
+      </BuildableProductRunnable>
102
+      <AdditionalOptions>
103
+      </AdditionalOptions>
104
+   </LaunchAction>
105
+   <ProfileAction
106
+      buildConfiguration = "Release"
107
+      shouldUseLaunchSchemeArgsEnv = "YES"
108
+      savedToolIdentifier = ""
109
+      useCustomWorkingDirectory = "NO"
110
+      debugDocumentVersioning = "YES">
111
+      <BuildableProductRunnable
112
+         runnableDebuggingMode = "0">
113
+         <BuildableReference
114
+            BuildableIdentifier = "primary"
115
+            BlueprintIdentifier = "2D02E47A1E0B4A5D006451C7"
116
+            BuildableName = "Example-tvOS.app"
117
+            BlueprintName = "Example-tvOS"
118
+            ReferencedContainer = "container:Example.xcodeproj">
119
+         </BuildableReference>
120
+      </BuildableProductRunnable>
121
+   </ProfileAction>
122
+   <AnalyzeAction
123
+      buildConfiguration = "Debug">
124
+   </AnalyzeAction>
125
+   <ArchiveAction
126
+      buildConfiguration = "Release"
127
+      revealArchiveInOrganizer = "YES">
128
+   </ArchiveAction>
129
+</Scheme>

+ 23
- 6
Example/ios/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme Ver fichero

1
 <?xml version="1.0" encoding="UTF-8"?>
1
 <?xml version="1.0" encoding="UTF-8"?>
2
 <Scheme
2
 <Scheme
3
-   LastUpgradeVersion = "0620"
3
+   LastUpgradeVersion = "0820"
4
    version = "1.3">
4
    version = "1.3">
5
    <BuildAction
5
    <BuildAction
6
-      parallelizeBuildables = "YES"
6
+      parallelizeBuildables = "NO"
7
       buildImplicitDependencies = "YES">
7
       buildImplicitDependencies = "YES">
8
       <BuildActionEntries>
8
       <BuildActionEntries>
9
+         <BuildActionEntry
10
+            buildForTesting = "YES"
11
+            buildForRunning = "YES"
12
+            buildForProfiling = "YES"
13
+            buildForArchiving = "YES"
14
+            buildForAnalyzing = "YES">
15
+            <BuildableReference
16
+               BuildableIdentifier = "primary"
17
+               BlueprintIdentifier = "83CBBA2D1A601D0E00E9B192"
18
+               BuildableName = "libReact.a"
19
+               BlueprintName = "React"
20
+               ReferencedContainer = "container:../node_modules/react-native/React/React.xcodeproj">
21
+            </BuildableReference>
22
+         </BuildActionEntry>
9
          <BuildActionEntry
23
          <BuildActionEntry
10
             buildForTesting = "YES"
24
             buildForTesting = "YES"
11
             buildForRunning = "YES"
25
             buildForRunning = "YES"
37
       </BuildActionEntries>
51
       </BuildActionEntries>
38
    </BuildAction>
52
    </BuildAction>
39
    <TestAction
53
    <TestAction
54
+      buildConfiguration = "Debug"
40
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
55
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
41
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
56
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
42
-      shouldUseLaunchSchemeArgsEnv = "YES"
43
-      buildConfiguration = "Debug">
57
+      shouldUseLaunchSchemeArgsEnv = "YES">
44
       <Testables>
58
       <Testables>
45
          <TestableReference
59
          <TestableReference
46
             skipped = "NO">
60
             skipped = "NO">
62
             ReferencedContainer = "container:Example.xcodeproj">
76
             ReferencedContainer = "container:Example.xcodeproj">
63
          </BuildableReference>
77
          </BuildableReference>
64
       </MacroExpansion>
78
       </MacroExpansion>
79
+      <AdditionalOptions>
80
+      </AdditionalOptions>
65
    </TestAction>
81
    </TestAction>
66
    <LaunchAction
82
    <LaunchAction
83
+      buildConfiguration = "Debug"
67
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
84
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
68
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
85
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
69
       launchStyle = "0"
86
       launchStyle = "0"
70
       useCustomWorkingDirectory = "NO"
87
       useCustomWorkingDirectory = "NO"
71
-      buildConfiguration = "Debug"
72
       ignoresPersistentStateOnLaunch = "NO"
88
       ignoresPersistentStateOnLaunch = "NO"
73
       debugDocumentVersioning = "YES"
89
       debugDocumentVersioning = "YES"
90
+      debugServiceExtension = "internal"
74
       allowLocationSimulation = "YES">
91
       allowLocationSimulation = "YES">
75
       <BuildableProductRunnable
92
       <BuildableProductRunnable
76
          runnableDebuggingMode = "0">
93
          runnableDebuggingMode = "0">
86
       </AdditionalOptions>
103
       </AdditionalOptions>
87
    </LaunchAction>
104
    </LaunchAction>
88
    <ProfileAction
105
    <ProfileAction
106
+      buildConfiguration = "Release"
89
       shouldUseLaunchSchemeArgsEnv = "YES"
107
       shouldUseLaunchSchemeArgsEnv = "YES"
90
       savedToolIdentifier = ""
108
       savedToolIdentifier = ""
91
       useCustomWorkingDirectory = "NO"
109
       useCustomWorkingDirectory = "NO"
92
-      buildConfiguration = "Release"
93
       debugDocumentVersioning = "YES">
110
       debugDocumentVersioning = "YES">
94
       <BuildableProductRunnable
111
       <BuildableProductRunnable
95
          runnableDebuggingMode = "0">
112
          runnableDebuggingMode = "0">

+ 2
- 2
Example/ios/Example/AppDelegate.m Ver fichero

9
 
9
 
10
 #import "AppDelegate.h"
10
 #import "AppDelegate.h"
11
 
11
 
12
-#import "RCTBundleURLProvider.h"
13
-#import "RCTRootView.h"
12
+#import <React/RCTBundleURLProvider.h>
13
+#import <React/RCTRootView.h>
14
 
14
 
15
 @implementation AppDelegate
15
 @implementation AppDelegate
16
 
16
 

+ 20
- 4
Example/ios/Example/Info.plist Ver fichero

8
 	<string>$(EXECUTABLE_NAME)</string>
8
 	<string>$(EXECUTABLE_NAME)</string>
9
 	<key>CFBundleIdentifier</key>
9
 	<key>CFBundleIdentifier</key>
10
 	<string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string>
10
 	<string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string>
11
-	<key>CFBundleInfoDictionaryVersion</key>
12
-	<string>6.0</string>
13
 	<key>CFBundleName</key>
11
 	<key>CFBundleName</key>
14
 	<string>$(PRODUCT_NAME)</string>
12
 	<string>$(PRODUCT_NAME)</string>
15
 	<key>CFBundlePackageType</key>
13
 	<key>CFBundlePackageType</key>
28
 		<dict>
26
 		<dict>
29
 			<key>localhost</key>
27
 			<key>localhost</key>
30
 			<dict>
28
 			<dict>
31
-				<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
29
+				<key>NSExceptionAllowsInsecureHTTPLoads</key>
32
 				<true/>
30
 				<true/>
33
 			</dict>
31
 			</dict>
34
 		</dict>
32
 		</dict>
35
 	</dict>
33
 	</dict>
34
+	<key>NSAppleMusicUsageDescription</key>
35
+	<string>test</string>
36
+	<key>NSBluetoothPeripheralUsageDescription</key>
37
+	<string>test</string>
38
+	<key>NSCalendarsUsageDescription</key>
39
+	<string>test</string>
40
+	<key>NSCameraUsageDescription</key>
41
+	<string>test</string>
42
+	<key>NSContactsUsageDescription</key>
43
+	<string>test</string>
44
+	<key>NSLocationAlwaysUsageDescription</key>
45
+	<string>test</string>
36
 	<key>NSLocationWhenInUseUsageDescription</key>
46
 	<key>NSLocationWhenInUseUsageDescription</key>
37
-	<string>We need your location</string>
47
+	<string>test</string>
48
+	<key>NSMicrophoneUsageDescription</key>
49
+	<string>6.0</string>
50
+	<key>NSPhotoLibraryUsageDescription</key>
51
+	<string>test</string>
52
+	<key>NSRemindersUsageDescription</key>
53
+	<string>test</string>
38
 	<key>UIBackgroundModes</key>
54
 	<key>UIBackgroundModes</key>
39
 	<array>
55
 	<array>
40
 		<string>bluetooth-peripheral</string>
56
 		<string>bluetooth-peripheral</string>

+ 1
- 1
Example/ios/Example/main.m Ver fichero

1
-  /**
1
+/**
2
  * Copyright (c) 2015-present, Facebook, Inc.
2
  * Copyright (c) 2015-present, Facebook, Inc.
3
  * All rights reserved.
3
  * All rights reserved.
4
  *
4
  *

+ 2
- 2
Example/ios/ExampleTests/ExampleTests.m Ver fichero

10
 #import <UIKit/UIKit.h>
10
 #import <UIKit/UIKit.h>
11
 #import <XCTest/XCTest.h>
11
 #import <XCTest/XCTest.h>
12
 
12
 
13
-#import "RCTLog.h"
14
-#import "RCTRootView.h"
13
+#import <React/RCTLog.h>
14
+#import <React/RCTRootView.h>
15
 
15
 
16
 #define TIMEOUT_SECONDS 600
16
 #define TIMEOUT_SECONDS 600
17
 #define TEXT_TO_LOOK_FOR @"Welcome to React Native!"
17
 #define TEXT_TO_LOOK_FOR @"Welcome to React Native!"

+ 21
- 11
Example/package.json Ver fichero

1
 {
1
 {
2
-  "name": "Example",
3
-  "version": "0.0.1",
4
-  "private": true,
5
-  "scripts": {
6
-    "start": "react-native start"
7
-  },
8
-  "dependencies": {
9
-    "react": "15.2.1",
10
-    "react-native": "^0.30.0",
2
+	"name": "Example",
3
+	"version": "0.0.1",
4
+	"private": true,
5
+	"scripts": {
6
+		"start": "react-native start",
7
+		"test": "jest"
8
+	},
9
+	"dependencies": {
10
+		"react": "15.4.2",
11
+		"react-native": "^0.41.0",
11
     "react-native-permissions": "../"
12
     "react-native-permissions": "../"
12
-  }
13
-}
13
+	},
14
+	"devDependencies": {
15
+		"babel-jest": "18.0.0",
16
+		"babel-preset-react-native": "1.9.1",
17
+		"jest": "18.1.0",
18
+		"react-test-renderer": "15.4.2"
19
+	},
20
+	"jest": {
21
+		"preset": "react-native"
22
+	}
23
+}

+ 7
- 2
RCTConvert+RNPStatus.h Ver fichero

6
 //  Copyright © 2016 Yonah Forst. All rights reserved.
6
 //  Copyright © 2016 Yonah Forst. All rights reserved.
7
 //
7
 //
8
 
8
 
9
-#import "RCTConvert.h"
9
+#if __has_include("RCTConvert.h")
10
+  #import "RCTConvert.h"
11
+#else
12
+  #import <React/RCTConvert.h>
13
+#endif
10
 
14
 
11
 static NSString* RNPStatusUndetermined = @"undetermined";
15
 static NSString* RNPStatusUndetermined = @"undetermined";
12
 static NSString* RNPStatusDenied = @"denied";
16
 static NSString* RNPStatusDenied = @"denied";
25
     RNPTypeReminder,
29
     RNPTypeReminder,
26
     RNPTypeBluetooth,
30
     RNPTypeBluetooth,
27
     RNPTypeNotification,
31
     RNPTypeNotification,
28
-    RNPTypeBackgroundRefresh
32
+    RNPTypeBackgroundRefresh,
33
+    RNPTypeSpeechRecognition
29
 };
34
 };
30
 
35
 
31
 @interface RCTConvert (RNPStatus)
36
 @interface RCTConvert (RNPStatus)

+ 2
- 1
RCTConvert+RNPStatus.m Ver fichero

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

+ 104
- 36
README.md Ver fichero

4
 The current supported permissions are:
4
 The current supported permissions are:
5
 - Location
5
 - Location
6
 - Camera
6
 - Camera
7
-- Microhone
7
+- Microphone
8
 - Photos
8
 - Photos
9
 - Contacts
9
 - Contacts
10
 - Events
10
 - Events
12
 - Bluetooth *(iOS only)*
12
 - Bluetooth *(iOS only)*
13
 - Push Notifications *(iOS only)*
13
 - Push Notifications *(iOS only)*
14
 - Background Refresh *(iOS only)*
14
 - Background Refresh *(iOS only)*
15
+- Speech Recognition *(iOS only)*
15
 
16
 
16
 
17
 
17
-###New in version 0.2.X
18
-- Android support 🎉🎉🍾
19
-- Example app
18
+| Version | React Native Support |
19
+|---|---|
20
+| 0.2.7 | 0.40.0 - 0.41.0 |
21
+| 0.2.5 | 0.33.0 - 0.39.0 |
22
+*Complies with [react-native-version-support-table](https://github.com/dangnelson/react-native-version-support-table)*
23
+
24
+## General Usage
25
+```
26
+npm install --save react-native-permissions
27
+rnpm link
28
+```
29
+
30
+Add permissions to manifest for android and info.plist for ios (xcode >=8). See notes below for more details.
20
 
31
 
21
-##General Usage
22
 ```js
32
 ```js
23
 const Permissions = require('react-native-permissions');
33
 const Permissions = require('react-native-permissions');
24
 
34
 
47
     Permissions.checkMultiplePermissions(['camera', 'photo'])
57
     Permissions.checkMultiplePermissions(['camera', 'photo'])
48
       .then(response => {
58
       .then(response => {
49
         //response is an object mapping type to permission
59
         //response is an object mapping type to permission
50
-        this.setState({ 
60
+        this.setState({
51
           cameraPermission: response.camera,
61
           cameraPermission: response.camera,
52
           photoPermission: response.photo,
62
           photoPermission: response.photo,
53
         })
63
         })
55
   }
65
   }
56
 
66
 
57
   // this is a common pattern when asking for permissions.
67
   // this is a common pattern when asking for permissions.
58
-  // iOS only gives you once chance to show the permission dialog, 
68
+  // iOS only gives you once chance to show the permission dialog,
59
   // after which the user needs to manually enable them from settings.
69
   // after which the user needs to manually enable them from settings.
60
   // the idea here is to explain why we need access and determine if
70
   // the idea here is to explain why we need access and determine if
61
   // the user will say no, so that we don't blow our one chance.
71
   // the user will say no, so that we don't blow our one chance.
66
       'We need access so you can set your profile pic',
76
       'We need access so you can set your profile pic',
67
       [
77
       [
68
         {text: 'No way', onPress: () => console.log('permission denied'), style: 'cancel'},
78
         {text: 'No way', onPress: () => console.log('permission denied'), style: 'cancel'},
69
-        this.state.photoPermission == 'undetermined'? 
79
+        this.state.photoPermission == 'undetermined'?
70
           {text: 'OK', onPress: this._requestPermission.bind(this)}
80
           {text: 'OK', onPress: this._requestPermission.bind(this)}
71
           : {text: 'Open Settings', onPress: Permissions.openSettings}
81
           : {text: 'Open Settings', onPress: Permissions.openSettings}
72
       ]
82
       ]
75
 //...
85
 //...
76
 ```
86
 ```
77
 
87
 
78
-##API
88
+## API
79
 
89
 
80
-###Permission statuses
90
+### Permission statuses
81
 Promises resolve into one of these statuses
91
 Promises resolve into one of these statuses
82
 
92
 
83
 | Return value | Notes|
93
 | Return value | Notes|
84
 |---|---|
94
 |---|---|
85
 |`authorized`| user has authorized this permission |
95
 |`authorized`| user has authorized this permission |
86
-|`denied`| user has denied permissions at least once. On iOS this means that the user will not be prompted again. Android users can be promted multiple times until they select 'Never ask me again'|
87
-|`restricted`| iOS only|
96
+|`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 promted multiple times until they select 'Never ask me again'|
97
+|`restricted`| *(iOS only)* 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. |
88
 |`undetermined`| user has not yet been prompted with a permission dialog |
98
 |`undetermined`| user has not yet been prompted with a permission dialog |
89
 
99
 
90
-###Supported permission types
100
+### Supported permission types
91
 
101
 
92
 | Name | iOS | Android |
102
 | Name | iOS | Android |
93
 |---|---|---|
103
 |---|---|---|
101
 |`reminder`| ✔️ | ❌ |
111
 |`reminder`| ✔️ | ❌ |
102
 |`notification`| ✔️ | ❌ |
112
 |`notification`| ✔️ | ❌ |
103
 |`backgroundRefresh`| ✔️ | ❌ |
113
 |`backgroundRefresh`| ✔️ | ❌ |
114
+|`speechRecognition`| ✔️ | ❌ |
115
+|`storage`| ❌️ | ✔ |
104
 
116
 
105
-###Methods
117
+### Methods
106
 | Method Name | Arguments | Notes
118
 | Method Name | Arguments | Notes
107
 |---|---|---|
119
 |---|---|---|
108
-| `getPermissionStatus` | `type` | - Returns a promise with the permission status. Note: for type `location`, iOS `AuthorizedAlways` and `AuthorizedWhenInUse` both return `authorized` |
109
-| `requestPermission` | `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. Note: see below for special cases|
120
+| `getPermissionStatus` | `type` | - Returns a promise with the permission status. See iOS Notes for special cases |
121
+| `requestPermission` | `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|
110
 | `checkMultiplePermissions` | `[types]` | - Accepts an array of permission types and returns a promise with an object mapping permission types to statuses |
122
 | `checkMultiplePermissions` | `[types]` | - Accepts an array of permission types and returns a promise with an object mapping permission types to statuses |
111
 | `getPermissionTypes` | *none* | - Returns an array of valid permission types  |
123
 | `getPermissionTypes` | *none* | - Returns an array of valid permission types  |
112
 | `openSettings` | *none* | - Switches the user to the settings page of your app (iOS 8.0 and later)  |
124
 | `openSettings` | *none* | - Switches the user to the settings page of your app (iOS 8.0 and later)  |
113
 | `canOpenSettings` | *none* | - Returns a boolean indicating if the device supports switching to the settings page |
125
 | `canOpenSettings` | *none* | - Returns a boolean indicating if the device supports switching to the settings page |
114
 
126
 
115
-###iOS Notes
127
+### iOS Notes
116
 Permission type `bluetooth` represents the status of the `CBPeripheralManager`. Don't use this if only need `CBCentralManager`
128
 Permission type `bluetooth` represents the status of the `CBPeripheralManager`. Don't use this if only need `CBCentralManager`
117
 
129
 
118
-`requestPermission` also accepts a second parameter for types `location` and `notification`.
119
-- `location`: the second parameter is a string, either `always` or `whenInUse`(default).
120
-- `notification`: the second parameter is an array with the desired alert types. Any combination of `alert`, `badge` and `sound` (default requests all three)
130
+Permission type `location` accepts a second parameter for `requestPermission` and `getPermissionStatus`;  the second parameter is a string, either `always` or `whenInUse`(default).
131
+
132
+Permission type `notification` accepts a second parameter for `requestPermission`. The second parameter is an array with the desired alert types. Any combination of `alert`, `badge` and `sound` (default requests all three)
133
+
121
 ```js
134
 ```js
122
 ///example
135
 ///example
136
+    Permissions.getPermissionStatus('location', 'always')
137
+      .then(response => {
138
+        this.setState({ locationPermission: response })
139
+      })
140
+
123
     Permissions.requestPermission('location', 'always')
141
     Permissions.requestPermission('location', 'always')
124
       .then(response => {
142
       .then(response => {
125
         this.setState({ locationPermission: response })
143
         this.setState({ locationPermission: response })
131
       })
149
       })
132
 ```
150
 ```
133
 
151
 
134
-###Android Notes
152
+You cannot request microphone permissions on the simulator.
153
+
154
+With Xcode 8, you now need to add usage descriptions for each permission you will request. Open Xcode > Info.plist > Add a key (starting with "Privacy - ...") with your kit specific permission.
155
+
156
+Example:
157
+If you need Contacts permission you have to add the key "Privacy - Contacts Usage Description".
158
+<img width="338" alt="3cde3b44-7ffd-11e6-918b-63888e33f983" src="https://cloud.githubusercontent.com/assets/1440796/18713019/271be540-8011-11e6-87fb-c3828c172dfc.png">
159
+
160
+### Android Notes
161
+
162
+Requires RN >= 0.29.0
163
+
135
 All required permissions also need to be included in the Manifest before they can be requested. Otherwise `requestPermission` will immediately return `denied`.
164
 All required permissions also need to be included in the Manifest before they can be requested. Otherwise `requestPermission` will immediately return `denied`.
136
 
165
 
137
 Permissions are automatically accepted for targetSdkVersion < 23 but you can still use `getPermissionStatus` to check if the user has disabled them from Settings.
166
 Permissions are automatically accepted for targetSdkVersion < 23 but you can still use `getPermissionStatus` to check if the user has disabled them from Settings.
138
 
167
 
139
-Here's a map of types to Android system permissions names:  
140
-`location` -> `android.permission.ACCESS_FINE_LOCATION`  
141
-`camera` -> `android.permission.CAMERA`  
142
-`microphone` -> `android.permission.RECORD_AUDIO`  
143
-`photo` -> `android.permission.READ_EXTERNAL_STORAGE`  
144
-`contacts` -> `android.permission.READ_CONTACTS`  
145
-`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
+
146
 
177
 
147
 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
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
148
 
179
 
149
-##Setup
180
+## Setup
150
 
181
 
151
 ````
182
 ````
152
 npm install --save react-native-permissions
183
 npm install --save react-native-permissions
153
 rnpm link
184
 rnpm link
154
 ````
185
 ````
155
 
186
 
156
-###Or manualy linking   
187
+### Or manualy linking
157
 
188
 
158
-####iOS
189
+#### iOS
159
 * Run open node_modules/react-native-permissions
190
 * Run open node_modules/react-native-permissions
160
 * Drag ReactNativePermissions.xcodeproj into the Libraries group of your app's Xcode project
191
 * Drag ReactNativePermissions.xcodeproj into the Libraries group of your app's Xcode project
161
 * Add libReactNativePermissions.a to `Build Phases -> Link Binary With Libraries.
192
 * Add libReactNativePermissions.a to `Build Phases -> Link Binary With Libraries.
162
 
193
 
163
-####Android
164
-#####Step 1 - Update Gradle Settings
194
+#### Android
195
+##### Step 1 - Update Gradle Settings
165
 
196
 
166
 ```
197
 ```
167
 // file: android/settings.gradle
198
 // file: android/settings.gradle
170
 include ':react-native-permissions'
201
 include ':react-native-permissions'
171
 project(':react-native-permissions').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-permissions/android')
202
 project(':react-native-permissions').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-permissions/android')
172
 ```
203
 ```
173
-#####Step 2 - Update Gradle Build
204
+##### Step 2 - Update Gradle Build
174
 
205
 
175
 ```
206
 ```
176
 // file: android/app/build.gradle
207
 // file: android/app/build.gradle
181
     compile project(':react-native-permissions')
212
     compile project(':react-native-permissions')
182
 }
213
 }
183
 ```
214
 ```
184
-#####Step 3 - Register React Package
215
+##### Step 3 - Register React Package
185
 ```
216
 ```
186
 ...
217
 ...
187
 import com.joshblour.reactnativepermissions.ReactNativePermissionsPackage; // <--- import
218
 import com.joshblour.reactnativepermissions.ReactNativePermissionsPackage; // <--- import
200
 
231
 
201
     ...
232
     ...
202
 }
233
 }
203
-```
234
+```
235
+## AppStore submission disclaimer
236
+
237
+If you need to submit you application to the AppStore, you need to add to your `Info.plist` all `*UsageDescription` keys with a string value explaining to the user how the app uses this data. **Even if you don't use them**.
238
+
239
+So before submitting your app to the `AppStore`, make sure that in your `Info.plist` you have the following keys:
240
+
241
+```
242
+
243
+<key>NSBluetoothPeripheralUsageDescription</key>
244
+<string>Some description</string>
245
+<key>NSCalendarsUsageDescription</key>
246
+<string>Some description</string>
247
+<key>NSCameraUsageDescription</key>
248
+<string>Some description</string>
249
+<key>NSLocationWhenInUseUsageDescription</key>
250
+<string>Some description</string>
251
+<key>NSPhotoLibraryUsageDescription</key>
252
+<string>Some description</string>
253
+
254
+```
255
+
256
+This is required because during the phase of `processing` in the `AppStore` submission, the system detects that you app contains code to request the permission `X` but don't have the `UsageDescription` key and rejects the build.
257
+
258
+> Please note that it will only be shown to the users the usage descriptions of the permissions you really require in your app.
259
+
260
+You can find more informations about this issue in #46.
261
+
262
+## Troubleshooting
263
+
264
+#### Q: Android - `undefined is not a object (evaluating 'RNPermissions.requestPermissions')`
265
+A: `rnpm` may not have linked correctly. Follow the manual linking steps and make sure the library is linked
266
+
267
+#### Q: iOS - app crashes as soon as I request permission
268
+A: starting with xcode 8, you need to add permission descriptions. see iOS notes for more details. Thanks to @jesperlndk for discovering this.
269
+
270
+#### Q: iOS - app crashes when I change permissions from settings
271
+A: This is normal. iOS restarts your app when your privacy settings change. Just google "ios crash permission change"

+ 5
- 2
ReactNativePermissions.h Ver fichero

5
 //  Created by Yonah Forst on 18/02/16.
5
 //  Created by Yonah Forst on 18/02/16.
6
 //  Copyright © 2016 Yonah Forst. All rights reserved.
6
 //  Copyright © 2016 Yonah Forst. All rights reserved.
7
 //
7
 //
8
-#import "RCTBridgeModule.h"
9
 
8
 
10
-#import <Foundation/Foundation.h>
9
+#if __has_include("RCTBridgeModule.h")
10
+  #import "RCTBridgeModule.h"
11
+#else
12
+  #import <React/RCTBridgeModule.h>
13
+#endif
11
 
14
 
12
 @interface ReactNativePermissions : NSObject <RCTBridgeModule>
15
 @interface ReactNativePermissions : NSObject <RCTBridgeModule>
13
 
16
 

+ 9
- 4
ReactNativePermissions.js Ver fichero

16
 		'bluetooth',
16
 		'bluetooth',
17
 		'notification',
17
 		'notification',
18
 		'backgroundRefresh',
18
 		'backgroundRefresh',
19
+		'speechRecognition',
19
 	],
20
 	],
20
 	android: [
21
 	android: [
21
 		'location',
22
 		'location',
23
 		'microphone',
24
 		'microphone',
24
 		'contacts',
25
 		'contacts',
25
 		'event',
26
 		'event',
26
-		'photos',
27
 		'notification',
27
 		'notification',
28
+		'photo',
29
+		'storage'
28
 	]
30
 	]
29
 }
31
 }
30
 
32
 
58
 	}
60
 	}
59
 
61
 
60
 
62
 
61
-	getPermissionStatus(permission) {
63
+	getPermissionStatus(permission, type) {
62
   	if (this.getPermissionTypes().indexOf(permission) >= 0) {
64
   	if (this.getPermissionTypes().indexOf(permission) >= 0) {
63
-			return RNPermissions.getPermissionStatus(permission)
65
+			return RNPermissions.getPermissionStatus(permission, type)
64
 		} else {
66
 		} else {
65
 			return Promise.reject(`ReactNativePermissions: ${permission} is not a valid permission type on ${Platform.OS}`)
67
 			return Promise.reject(`ReactNativePermissions: ${permission} is not a valid permission type on ${Platform.OS}`)
66
 		}
68
 		}
69
 	requestPermission(permission, type) {
71
 	requestPermission(permission, type) {
70
 		let options;
72
 		let options;
71
 
73
 
72
-		if (!this.getPermissionTypes().includes(permission)) {
74
+		if (this.getPermissionTypes().indexOf(permission) === -1) {
73
 			return Promise.reject(`ReactNativePermissions: ${permission} is not a valid permission type on ${Platform.OS}`)
75
 			return Promise.reject(`ReactNativePermissions: ${permission} is not a valid permission type on ${Platform.OS}`)
74
 		} else if (permission == 'backgroundRefresh'){
76
 		} else if (permission == 'backgroundRefresh'){
75
 			return Promise.reject('ReactNativePermissions: You cannot request backgroundRefresh')
77
 			return Promise.reject('ReactNativePermissions: You cannot request backgroundRefresh')
76
 		} else if (permission == 'location') {
78
 		} else if (permission == 'location') {
77
 			options = type || 'whenInUse'
79
 			options = type || 'whenInUse'
78
 		} else if (permission == 'notification') {
80
 		} else if (permission == 'notification') {
81
+			if (Platform.OS === 'android') {
82
+				return Promise.reject(`ReactNativePermissions: notification cannot be requested on Android`)
83
+			}
79
 			options = type || ['alert', 'badge', 'sound']
84
 			options = type || ['alert', 'badge', 'sound']
80
 		}
85
 		}
81
 
86
 

+ 41
- 8
ReactNativePermissions.m Ver fichero

10
 
10
 
11
 #import "ReactNativePermissions.h"
11
 #import "ReactNativePermissions.h"
12
 
12
 
13
-#import "RCTBridge.h"
14
-#import "RCTConvert.h"
15
-#import "RCTEventDispatcher.h"
13
+#if __has_include("RCTBridge.h")
14
+  #import "RCTBridge.h"
15
+#else
16
+  #import <React/RCTBridge.h>
17
+#endif
18
+
19
+#if __has_include("RCTConvert.h")
20
+  #import "RCTConvert.h"
21
+#else
22
+  #import <React/RCTConvert.h>
23
+#endif
24
+
25
+#if __has_include("RCTEventDispatcher.h")
26
+  #import "RCTEventDispatcher.h"
27
+#else
28
+  #import <React/RCTEventDispatcher.h>
29
+#endif
16
 
30
 
17
 #import "RNPLocation.h"
31
 #import "RNPLocation.h"
18
 #import "RNPBluetooth.h"
32
 #import "RNPBluetooth.h"
22
 #import "RNPPhoto.h"
36
 #import "RNPPhoto.h"
23
 #import "RNPContacts.h"
37
 #import "RNPContacts.h"
24
 #import "RNPBackgroundRefresh.h"
38
 #import "RNPBackgroundRefresh.h"
39
+#import "RNPSpeechRecognition.h"
25
 
40
 
26
 @interface ReactNativePermissions()
41
 @interface ReactNativePermissions()
27
 @property (strong, nonatomic) RNPLocation *locationMgr;
42
 @property (strong, nonatomic) RNPLocation *locationMgr;
58
     resolve(@(UIApplicationOpenSettingsURLString != nil));
73
     resolve(@(UIApplicationOpenSettingsURLString != nil));
59
 }
74
 }
60
 
75
 
61
-RCT_EXPORT_METHOD(openSettings)
76
+    
77
+RCT_EXPORT_METHOD(openSettings:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
62
 {
78
 {
63
     if (@(UIApplicationOpenSettingsURLString != nil)) {
79
     if (@(UIApplicationOpenSettingsURLString != nil)) {
80
+        
81
+        NSNotificationCenter * __weak center = [NSNotificationCenter defaultCenter];
82
+        id __block token = [center addObserverForName:UIApplicationDidBecomeActiveNotification
83
+                                               object:nil
84
+                                                queue:nil
85
+                                           usingBlock:^(NSNotification *note) {
86
+                                               [center removeObserver:token];
87
+                                               resolve(@YES);
88
+                                           }];
89
+        
64
         NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
90
         NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
65
         [[UIApplication sharedApplication] openURL:url];
91
         [[UIApplication sharedApplication] openURL:url];
66
     }
92
     }
67
 }
93
 }
68
 
94
 
69
-RCT_REMAP_METHOD(getPermissionStatus, getPermissionStatus:(RNPType)type resolve:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
95
+
96
+RCT_REMAP_METHOD(getPermissionStatus, getPermissionStatus:(RNPType)type json:(id)json resolve:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
70
 {
97
 {
71
     NSString *status;
98
     NSString *status;
72
     
99
     
73
     switch (type) {
100
     switch (type) {
74
             
101
             
75
-        case RNPTypeLocation:
76
-            status = [RNPLocation getStatus];
102
+        case RNPTypeLocation: {
103
+            NSString *locationPermissionType = [RCTConvert NSString:json];
104
+            status = [RNPLocation getStatusForType:locationPermissionType];
77
             break;
105
             break;
106
+        }
78
         case RNPTypeCamera:
107
         case RNPTypeCamera:
79
             status = [RNPAudioVideo getStatus:@"video"];
108
             status = [RNPAudioVideo getStatus:@"video"];
80
             break;
109
             break;
102
         case RNPTypeBackgroundRefresh:
131
         case RNPTypeBackgroundRefresh:
103
             status = [RNPBackgroundRefresh getStatus];
132
             status = [RNPBackgroundRefresh getStatus];
104
             break;
133
             break;
134
+        case RNPTypeSpeechRecognition:
135
+            status = [RNPSpeechRecognition getStatus];
136
+            break;
105
         default:
137
         default:
106
             break;
138
             break;
107
     }
139
     }
132
             return [self requestBluetooth:resolve];
164
             return [self requestBluetooth:resolve];
133
         case RNPTypeNotification:
165
         case RNPTypeNotification:
134
             return [self requestNotification:json resolve:resolve];
166
             return [self requestNotification:json resolve:resolve];
167
+        case RNPTypeSpeechRecognition:
168
+            return [RNPSpeechRecognition request:resolve];
135
         default:
169
         default:
136
             break;
170
             break;
137
     }
171
     }
139
 
173
 
140
 }
174
 }
141
 
175
 
142
-
143
 - (void) requestLocation:(id)json resolve:(RCTPromiseResolveBlock)resolve
176
 - (void) requestLocation:(id)json resolve:(RCTPromiseResolveBlock)resolve
144
 {
177
 {
145
     if (self.locationMgr == nil) {
178
     if (self.locationMgr == nil) {

+ 1
- 0
ReactNativePermissions.podspec Ver fichero

19
 
19
 
20
   s.preserve_paths      = 'docs', 'CHANGELOG.md', 'LICENSE', 'package.json', 'ReactNativePermissions.ios.js'
20
   s.preserve_paths      = 'docs', 'CHANGELOG.md', 'LICENSE', 'package.json', 'ReactNativePermissions.ios.js'
21
   s.source_files        = '**/*.{h,m}'
21
   s.source_files        = '**/*.{h,m}'
22
+  s.exclude_files       = 'Example/**/*'
22
 end
23
 end

+ 7
- 1
ReactNativePermissions.xcodeproj/project.pbxproj Ver fichero

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

ReactNativePermissions.xcodeproj/xcuserdata/Yonah.xcuserdatad/xcschemes/ReactNativeHeading.xcscheme → ReactNativePermissions.xcodeproj/xcuserdata/Yonah.xcuserdatad/xcschemes/ReactNativePermissions.xcscheme Ver fichero


+ 4
- 4
android/build.gradle Ver fichero

11
 apply plugin: 'com.android.library'
11
 apply plugin: 'com.android.library'
12
 
12
 
13
 android {
13
 android {
14
-    compileSdkVersion 24
15
-    buildToolsVersion "24.0.1"
14
+    compileSdkVersion 23
15
+    buildToolsVersion "25.0.2"
16
 
16
 
17
     defaultConfig {
17
     defaultConfig {
18
-        minSdkVersion 18
19
-        targetSdkVersion 24
18
+        minSdkVersion 16
19
+        targetSdkVersion 23
20
         versionCode 1
20
         versionCode 1
21
         versionName "1.0"
21
         versionName "1.0"
22
     }
22
     }

+ 19
- 8
android/src/main/java/com/joshblour/reactnativepermissions/ReactNativePermissionsModule.java Ver fichero

11
 
11
 
12
 import com.facebook.react.bridge.Callback;
12
 import com.facebook.react.bridge.Callback;
13
 import com.facebook.react.bridge.Promise;
13
 import com.facebook.react.bridge.Promise;
14
+import com.facebook.react.bridge.PromiseImpl;
14
 import com.facebook.react.bridge.ReactApplicationContext;
15
 import com.facebook.react.bridge.ReactApplicationContext;
15
 import com.facebook.react.bridge.ReactContextBaseJavaModule;
16
 import com.facebook.react.bridge.ReactContextBaseJavaModule;
16
 import com.facebook.react.bridge.ReactMethod;
17
 import com.facebook.react.bridge.ReactMethod;
18
 import com.facebook.react.bridge.ReadableArray;
19
 import com.facebook.react.bridge.ReadableArray;
19
 import com.facebook.react.modules.permissions.PermissionsModule;
20
 import com.facebook.react.modules.permissions.PermissionsModule;
20
 
21
 
22
+import java.util.Locale;
21
 
23
 
22
 public class ReactNativePermissionsModule extends ReactContextBaseJavaModule {
24
 public class ReactNativePermissionsModule extends ReactContextBaseJavaModule {
23
   private final ReactApplicationContext reactContext;
25
   private final ReactApplicationContext reactContext;
31
     MICROPHONE,
33
     MICROPHONE,
32
     CONTACTS,
34
     CONTACTS,
33
     EVENT,
35
     EVENT,
34
-    PHOTOS;
36
+    STORAGE,
37
+    PHOTO;
35
   }
38
   }
36
 
39
 
37
   public ReactNativePermissionsModule(ReactApplicationContext reactContext) {
40
   public ReactNativePermissionsModule(ReactApplicationContext reactContext) {
47
   }
50
   }
48
 
51
 
49
   @ReactMethod
52
   @ReactMethod
50
-  public void getPermissionStatus(String permissionString, Promise promise) {
53
+  public void getPermissionStatus(String permissionString, String nullForiOSCompat, Promise promise) {
51
     String permission = permissionForString(permissionString);
54
     String permission = permissionForString(permissionString);
52
 
55
 
53
     // check if permission is valid
56
     // check if permission is valid
92
   @ReactMethod
95
   @ReactMethod
93
   public void requestPermission(final String permissionString, String nullForiOSCompat, final Promise promise) {
96
   public void requestPermission(final String permissionString, String nullForiOSCompat, final Promise promise) {
94
     String permission = permissionForString(permissionString);
97
     String permission = permissionForString(permissionString);
95
-    mPermissionsModule.requestPermission(permission, new Callback() {
98
+    Callback resolve = new Callback() {
96
       @Override
99
       @Override
97
       public void invoke(Object... args) {
100
       public void invoke(Object... args) {
98
-        getPermissionStatus(permissionString, promise);
99
-//        promise.resolve((boolean)args[1] ? "authorized" : "denied");
101
+        getPermissionStatus(permissionString, "", promise);
100
       }
102
       }
101
-    }, null);
103
+    };
104
+    Callback reject = new Callback() {
105
+      @Override
106
+      public void invoke(Object... args) {
107
+        // NOOP
108
+      }
109
+    };
110
+
111
+    mPermissionsModule.requestPermission(permission, new PromiseImpl(resolve, reject));
102
   }
112
   }
103
 
113
 
104
 
114
 
120
   }
130
   }
121
 
131
 
122
   private String permissionForString(String permission) {
132
   private String permissionForString(String permission) {
123
-    switch (RNType.valueOf(permission.toUpperCase())) {
133
+    switch (RNType.valueOf(permission.toUpperCase(Locale.ENGLISH))) {
124
       case LOCATION:
134
       case LOCATION:
125
         return Manifest.permission.ACCESS_FINE_LOCATION;
135
         return Manifest.permission.ACCESS_FINE_LOCATION;
126
       case CAMERA:
136
       case CAMERA:
131
         return Manifest.permission.READ_CONTACTS;
141
         return Manifest.permission.READ_CONTACTS;
132
       case EVENT:
142
       case EVENT:
133
         return Manifest.permission.READ_CALENDAR;
143
         return Manifest.permission.READ_CALENDAR;
134
-      case PHOTOS:
144
+      case STORAGE:
145
+      case PHOTO:
135
         return Manifest.permission.READ_EXTERNAL_STORAGE;
146
         return Manifest.permission.READ_EXTERNAL_STORAGE;
136
       default:
147
       default:
137
         return permission;
148
         return permission;

+ 1
- 1
package.json Ver fichero

1
 {
1
 {
2
   "name": "react-native-permissions",
2
   "name": "react-native-permissions",
3
-  "version": "0.2.2",
3
+  "version": "0.3.0",
4
   "repository": {
4
   "repository": {
5
     "type": "git",
5
     "type": "git",
6
     "url": "https://github.com/joshblour/react-native-permissions.git"
6
     "url": "https://github.com/joshblour/react-native-permissions.git"

+ 1
- 1
permissions/RNPLocation.h Ver fichero

11
 
11
 
12
 @interface RNPLocation : NSObject
12
 @interface RNPLocation : NSObject
13
 
13
 
14
-+ (NSString *)getStatus;
14
++ (NSString *)getStatusForType:(NSString *)type;
15
 - (void)request:(NSString *)type completionHandler:(void (^)(NSString *))completionHandler;
15
 - (void)request:(NSString *)type completionHandler:(void (^)(NSString *))completionHandler;
16
 
16
 
17
 @end
17
 @end

+ 14
- 9
permissions/RNPLocation.m Ver fichero

17
 
17
 
18
 @implementation RNPLocation
18
 @implementation RNPLocation
19
 
19
 
20
-+ (NSString *)getStatus
20
++ (NSString *)getStatusForType:(NSString *)type
21
 {
21
 {
22
     int status = [CLLocationManager authorizationStatus];
22
     int status = [CLLocationManager authorizationStatus];
23
     switch (status) {
23
     switch (status) {
24
         case kCLAuthorizationStatusAuthorizedAlways:
24
         case kCLAuthorizationStatusAuthorizedAlways:
25
-        case kCLAuthorizationStatusAuthorizedWhenInUse:
26
             return RNPStatusAuthorized;
25
             return RNPStatusAuthorized;
26
+        case kCLAuthorizationStatusAuthorizedWhenInUse:
27
+            return [type isEqualToString:@"always"] ? RNPStatusDenied : RNPStatusAuthorized;
27
         case kCLAuthorizationStatusDenied:
28
         case kCLAuthorizationStatusDenied:
28
             return RNPStatusDenied;
29
             return RNPStatusDenied;
29
         case kCLAuthorizationStatusRestricted:
30
         case kCLAuthorizationStatusRestricted:
35
 
36
 
36
 - (void)request:(NSString*)type completionHandler:(void (^)(NSString *))completionHandler
37
 - (void)request:(NSString*)type completionHandler:(void (^)(NSString *))completionHandler
37
 {
38
 {
38
-    NSString *status = [RNPLocation getStatus];
39
+    NSString *status = [RNPLocation getStatusForType:nil];
39
     if (status == RNPStatusUndetermined) {
40
     if (status == RNPStatusUndetermined) {
40
         self.completionHandler = completionHandler;
41
         self.completionHandler = completionHandler;
41
-        
42
+
42
         if (self.locationManager == nil) {
43
         if (self.locationManager == nil) {
43
             self.locationManager = [[CLLocationManager alloc] init];
44
             self.locationManager = [[CLLocationManager alloc] init];
44
             self.locationManager.delegate = self;
45
             self.locationManager.delegate = self;
45
         }
46
         }
46
-        
47
+
47
         if ([type isEqualToString:@"always"]) {
48
         if ([type isEqualToString:@"always"]) {
48
             [self.locationManager requestAlwaysAuthorization];
49
             [self.locationManager requestAlwaysAuthorization];
49
         } else {
50
         } else {
50
             [self.locationManager requestWhenInUseAuthorization];
51
             [self.locationManager requestWhenInUseAuthorization];
51
         }
52
         }
52
     } else {
53
     } else {
53
-        completionHandler(status);
54
+        if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse && [type isEqualToString:@"always"]) {
55
+            completionHandler(RNPStatusDenied);
56
+        } else {
57
+            completionHandler(status);
58
+        }
54
     }
59
     }
55
 }
60
 }
56
 
61
 
60
             self.locationManager.delegate = nil;
65
             self.locationManager.delegate = nil;
61
             self.locationManager = nil;
66
             self.locationManager = nil;
62
         }
67
         }
63
-        
68
+
64
         if (self.completionHandler) {
69
         if (self.completionHandler) {
65
             //for some reason, checking permission right away returns denied. need to wait a tiny bit
70
             //for some reason, checking permission right away returns denied. need to wait a tiny bit
66
             dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
71
             dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
67
-                self.completionHandler([RNPLocation getStatus]);
72
+                self.completionHandler([RNPLocation getStatusForType:nil]);
68
                 self.completionHandler = nil;
73
                 self.completionHandler = nil;
69
             });
74
             });
70
-        }        
75
+        }
71
     }
76
     }
72
 }
77
 }
73
 @end
78
 @end

+ 12
- 31
permissions/RNPNotification.m Ver fichero

19
 + (NSString *)getStatus
19
 + (NSString *)getStatus
20
 {
20
 {
21
     BOOL didAskForPermission = [[NSUserDefaults standardUserDefaults] boolForKey:RNPDidAskForNotification];
21
     BOOL didAskForPermission = [[NSUserDefaults standardUserDefaults] boolForKey:RNPDidAskForNotification];
22
+    BOOL isRegistered = [[UIApplication sharedApplication] isRegisteredForRemoteNotifications];
23
+    BOOL isEnabled = [[[UIApplication sharedApplication] currentUserNotificationSettings] types] != UIUserNotificationTypeNone;
22
     
24
     
23
-    if (didAskForPermission) {
24
-        if ([[UIApplication sharedApplication] respondsToSelector:@selector(isRegisteredForRemoteNotifications)]) {
25
-            // iOS8+
26
-            BOOL isRegistered = [[UIApplication sharedApplication] isRegisteredForRemoteNotifications];
27
-            BOOL isEnabled = [[[UIApplication sharedApplication] currentUserNotificationSettings] types] != UIUserNotificationTypeNone;
28
-            if (isRegistered || isEnabled) {
29
-                return isEnabled ? RNPStatusAuthorized : RNPStatusDenied;
30
-            }
31
-            else {
32
-                return RNPStatusDenied;
33
-            }
34
-        } else {
35
-            if ([[UIApplication sharedApplication] enabledRemoteNotificationTypes] == UIRemoteNotificationTypeNone) {
36
-                return RNPStatusDenied;
37
-            }
38
-            else {
39
-                return RNPStatusAuthorized;
40
-            }
41
-        }
25
+    if (isRegistered || isEnabled) {
26
+        return isEnabled ? RNPStatusAuthorized : RNPStatusDenied;
42
     } else {
27
     } else {
43
-        return RNPStatusUndetermined;
28
+        return didAskForPermission ? RNPStatusDenied : RNPStatusUndetermined;
44
     }
29
     }
45
 }
30
 }
46
 
31
 
47
 - (void)request:(UIUserNotificationType)types completionHandler:(void (^)(NSString*))completionHandler
32
 - (void)request:(UIUserNotificationType)types completionHandler:(void (^)(NSString*))completionHandler
48
 {
33
 {
49
-    BOOL didAskForPermission = [[NSUserDefaults standardUserDefaults] boolForKey:RNPDidAskForNotification];
50
-    if (!didAskForPermission) {
34
+    NSString *status = [self.class getStatus];
35
+    
36
+    if (status == RNPStatusUndetermined) {
51
         self.completionHandler = completionHandler;
37
         self.completionHandler = completionHandler;
52
         
38
         
53
         [[NSNotificationCenter defaultCenter] addObserver:self
39
         [[NSNotificationCenter defaultCenter] addObserver:self
55
                                                      name:UIApplicationDidBecomeActiveNotification
41
                                                      name:UIApplicationDidBecomeActiveNotification
56
                                                    object:nil];
42
                                                    object:nil];
57
         
43
         
58
-        if ([[UIApplication sharedApplication] respondsToSelector:@selector(isRegisteredForRemoteNotifications)]) {
59
-            // iOS8+
60
-            UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
61
-            [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
62
-            [[UIApplication sharedApplication] registerForRemoteNotifications];
63
-        } else {
64
-            [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationType)types];
65
-        }
44
+        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
45
+        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
46
+        [[UIApplication sharedApplication] registerForRemoteNotifications];
66
         
47
         
67
         [[NSUserDefaults standardUserDefaults] setBool:YES forKey:RNPDidAskForNotification];
48
         [[NSUserDefaults standardUserDefaults] setBool:YES forKey:RNPDidAskForNotification];
68
         [[NSUserDefaults standardUserDefaults] synchronize];
49
         [[NSUserDefaults standardUserDefaults] synchronize];
69
     } else {
50
     } else {
70
-        completionHandler([self.class getStatus]);
51
+        completionHandler(status);
71
     }
52
     }
72
 }
53
 }
73
 
54
 

+ 0
- 1
permissions/RNPPhoto.m Ver fichero

7
 //
7
 //
8
 
8
 
9
 #import "RNPPhoto.h"
9
 #import "RNPPhoto.h"
10
-#import <AddressBook/AddressBook.h>
11
 #import <AssetsLibrary/AssetsLibrary.h>
10
 #import <AssetsLibrary/AssetsLibrary.h>
12
 
11
 
13
 @import Photos;
12
 @import Photos;

+ 17
- 0
permissions/RNPSpeechRecognition.h Ver fichero

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 Ver fichero

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