From 408943370835f3c9d033f2ba266e95a9fca64c4f Mon Sep 17 00:00:00 2001 From: Jason Divock Date: Wed, 30 Mar 2022 14:17:26 -0600 Subject: [PATCH] docs --- README.md | 44 ++++++++++++++++++- docs/set-up-your-sdk.md | 29 +++++++++++++ src/utils/androidExpoPermissionsUtils.ts | 55 ++++++++++++++++++++++++ 3 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 src/utils/androidExpoPermissionsUtils.ts diff --git a/README.md b/README.md index 69463ad0..3b876c3e 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,9 @@ Stripe Terminal enables you to build your own in-person checkout to accept payme - [Manifest](#manifest) - [Usage With Expo](#usage-with-expo) - [Android](#android-2) + - [build.gradle](#buildgradle) + - [Permissions](#permissions-2) + - [iOS](#ios-2) - [Configuring the SDK](#configuring-the-sdk) - [Build](#build) - [Example Code](#example-code) @@ -205,6 +208,8 @@ Please read the [Android documentation](https://developer.android.com/about/vers ### Android +#### build.gradle + For android you'll need to massage your build files in order to properly compile. First in `android/build.gradle` by updating both `compileSdkVersion` and `targetSdkVersion` to at least `31`: ``` @@ -231,6 +236,37 @@ android.jetifier.blacklist=moshi-1.13.0.jar Depending on the version of jetifier in use. +#### Permissions + +Android will still require runtime permissions checks for location and BT access, we've provided an expo specific util to run these checks as follows: + +``` +import { requestNeededExpoAndroidPermissions } from 'stripe-terminal-react-native'; + +try { + const granted = await requestNeededExpoAndroidPermissions({ + accessFineLocation: { + title: 'Location Permission', + message: 'Stripe Terminal needs access to your location', + buttonPositive: 'Accept', + }, + }); + if (granted) { + // init SDK + } else { + console.error( + 'Location and BT services are required in order to connect to a reader.' + ); + } +} catch (e) { + console.error(e); +} +``` + +### iOS + +No special steps are required for iOS! + ### Configuring the SDK After [installing](#installation) the SDK, add the [config plugin](https://docs.expo.io/guides/config-plugins/) to the [`plugins`](https://docs.expo.io/versions/latest/config/app/#plugins) array of your `app.json` or `app.config.js`: @@ -258,9 +294,13 @@ After [installing](#installation) the SDK, add the [config plugin](https://docs. Rebuild your app as described in the ['Adding custom native code'](https://docs.expo.io/workflow/customizing/) guide with: ``` -expo run:ios +> expo prebuild + +and then + +> expo run:ios or -expo run:android +> expo run:android ``` # Example Code diff --git a/docs/set-up-your-sdk.md b/docs/set-up-your-sdk.md index 2f22723a..e9f89606 100644 --- a/docs/set-up-your-sdk.md +++ b/docs/set-up-your-sdk.md @@ -154,6 +154,8 @@ Please read the [Android documentation](https://developer.android.com/about/vers ### Android +#### build.gradle + For android you'll need to massage your build files in order to properly compile. First in `android/build.gradle` by updating both `compileSdkVersion` and `targetSdkVersion` to at least `31`: ``` @@ -180,6 +182,33 @@ android.jetifier.blacklist=moshi-1.13.0.jar Depending on the version of jetifier in use. +#### Permissions + +Android will still require runtime permissions checks for location and BT access, we've provided an expo specific util to run these checks as follows: + +``` +import { requestNeededExpoAndroidPermissions } from 'stripe-terminal-react-native'; + +try { + const granted = await requestNeededExpoAndroidPermissions({ + accessFineLocation: { + title: 'Location Permission', + message: 'Stripe Terminal needs access to your location', + buttonPositive: 'Accept', + }, + }); + if (granted) { + // init SDK + } else { + console.error( + 'Location and BT services are required in order to connect to a reader.' + ); + } +} catch (e) { + console.error(e); +} +``` + ### Configuring the SDK After [installing](#installation) the SDK, add the [config plugin](https://docs.expo.io/guides/config-plugins/) to the [`plugins`](https://docs.expo.io/versions/latest/config/app/#plugins) array of your `app.json` or `app.config.js`: diff --git a/src/utils/androidExpoPermissionsUtils.ts b/src/utils/androidExpoPermissionsUtils.ts new file mode 100644 index 00000000..6173b24a --- /dev/null +++ b/src/utils/androidExpoPermissionsUtils.ts @@ -0,0 +1,55 @@ +import { PermissionsAndroid, Platform } from 'react-native'; +import { PERMISSIONS, RESULTS, request } from 'react-native-permissions'; + +const defaultFineLocationParams = { + title: 'Location Permission', + message: 'Stripe Terminal needs access to your location', + buttonPositive: 'Accept', +}; + +type PermissionsProps = { + accessFineLocation?: { + title: string; + message: string; + buttonPositive: string; + }; +}; + +const isAndroid12orHigher = () => + Platform.OS === 'android' && Platform.Version >= 31; + +export async function requestNeededExpoAndroidPermissions({ + accessFineLocation = defaultFineLocationParams, +}: PermissionsProps | undefined = {}): Promise { + let hasGrantedLocationPermissions = false; + let hasGrantedBluetoothPermissions = false; + + const grantedFineLocation = await PermissionsAndroid.request( + PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION, + accessFineLocation || defaultFineLocationParams + ); + + if (hasGrantedPermission(grantedFineLocation)) { + hasGrantedLocationPermissions = true; + + if (isAndroid12orHigher()) { + // otherwise within expo we have to make use of react-native-permissions + const grantedBT = await request(PERMISSIONS.ANDROID.BLUETOOTH_CONNECT); + const grantedBTScan = await request(PERMISSIONS.ANDROID.BLUETOOTH_SCAN); + + if ( + hasGrantedPermission(grantedBT) && + hasGrantedPermission(grantedBTScan) + ) { + hasGrantedBluetoothPermissions = true; + } + } else { + hasGrantedBluetoothPermissions = true; + } + } + return hasGrantedBluetoothPermissions && hasGrantedLocationPermissions; +} + +const hasGrantedPermission = (status: string) => { + return status === RESULTS.GRANTED; +};