App Permissions
Introduction
Advanced features in mobile apps often require permission from users. Apps need to respect the user’s privacy, so it is common practice for an app to request the user’s permission before storing media and data. To get permission, you can build a generic JavaScript action. This generic action will allow your app to ask for specific permissions before accessing a mobile capability, such as the device camera or location.
Prerequisites
- Complete the Prerequisites section of Deploy Your First Mendix Native Mobile App.
- Install Mendix Studio Pro 9.10.0 and above to use the Native Mobile App Builder and the latest Nanoflow Commons module.
- Make sure your Native Mobile Resources module is up to date.
- Make sure you are using Make It Native 9 app, and it is up-to-date.
Using a Generic Permission Action
A generic permission action can be used inside nanoflows in an existing app or in a new app. With a nanoflow open, you can find it in the Toolbox under the Native Mobile section.
Naming the Permission
When using the generic permission action you must choose the permission name you need. It should be one of the available permissions in NanoflowCommons.Enum_Permissions
enumeration.
CONTACTS_IOS
) and one for Android permission (READ_CONTACTS_ANDROID
).
Action Return Type Statuses
This action returns the status of the permission after the action, and it is of type NanoflowCommons.Enum_PermissionStatus
. The statuses are as follows:
Permission status | Notes |
---|---|
NanoflowCommons.Enum_PermissionStatus.granted |
The permission is granted after requesting it from the user, or it was already granted previously. |
NanoflowCommons.Enum_PermissionStatus.unavailable |
This feature is not available on this device. |
NanoflowCommons.Enum_PermissionStatus.denied |
The permission is denied but can still be requested. |
NanoflowCommons.Enum_PermissionStatus.blocked |
The permission is blocked. The user must open the app settings themselves and grant permission from there. |
NanoflowCommons.Enum_PermissionStatus.limited |
The permission is granted but with limitations. |
Permission Usage Example
This an example for requesting contact access permission for Android and iOS devices:
- Determine the user’s running platform (Android or iOS) by using the Get device info action (in the Toolbox’s Native mobile section).
- Branch your logic based on the current platform:
-
For the Android branch, use a Generic permission action with a permission name like {READ_CONTACTS_ANDROID}.
-
For the iOS branch, use a Generic permission action with a permission name like {CONTACTS_IOS}:
-
Building
Development
IOS
The following permissions can be tested using the iOS Make It Native app:
- CAMERA
- FACE_ID
- LOCATION_WHEN_IN_USE
- MICROPHONE
- PHOTO_LIBRARY
To test the remaining permissions you can build native app and update the native app with the required permissions.
Android
The following permissions can be tested using the Android Make It Native app:
- ACCESS_FINE_LOCATION
- BLUETOOTH_CONNECT
- BLUETOOTH_SCAN
- CALL_PHONE
- RECORD_AUDIO
- CAMERA
- READ_EXTERNAL_STORAGE
- WRITE_EXTERNAL_STORAGE
- SCHEDULE_EXACT_ALARM
To test the remaining permissions you can build a native app and update the native app with the required permissions.
Deployment
During deployment you must specify the permissions that your application has used to be able to request them from the user on production. To do that you can navigate to App permissions while using Native Builder UI and add the permissions you are using in your application for iOS and Android.
Updating Native App Permissions
iOS
Update your ios/podfile file with the needed permissions:
target 'YourAwesomeProject' do
# …
permissions_path = '../node_modules/react-native-permissions/ios'
pod 'Permission-AppTrackingTransparency', :path => "#{permissions_path}/AppTrackingTransparency"
pod 'Permission-BluetoothPeripheral', :path => "#{permissions_path}/BluetoothPeripheral"
pod 'Permission-Calendars', :path => "#{permissions_path}/Calendars"
pod 'Permission-Camera', :path => "#{permissions_path}/Camera"
pod 'Permission-Contacts', :path => "#{permissions_path}/Contacts"
pod 'Permission-FaceID', :path => "#{permissions_path}/FaceID"
pod 'Permission-LocationAccuracy', :path => "#{permissions_path}/LocationAccuracy"
pod 'Permission-LocationAlways', :path => "#{permissions_path}/LocationAlways"
pod 'Permission-LocationWhenInUse', :path => "#{permissions_path}/LocationWhenInUse"
pod 'Permission-MediaLibrary', :path => "#{permissions_path}/MediaLibrary"
pod 'Permission-Microphone', :path => "#{permissions_path}/Microphone"
pod 'Permission-Motion', :path => "#{permissions_path}/Motion"
pod 'Permission-Notifications', :path => "#{permissions_path}/Notifications"
pod 'Permission-PhotoLibrary', :path => "#{permissions_path}/PhotoLibrary"
pod 'Permission-PhotoLibraryAddOnly', :path => "#{permissions_path}/PhotoLibraryAddOnly"
pod 'Permission-Reminders', :path => "#{permissions_path}/Reminders"
pod 'Permission-Siri', :path => "#{permissions_path}/Siri"
pod 'Permission-SpeechRecognition', :path => "#{permissions_path}/SpeechRecognition"
pod 'Permission-StoreKit', :path => "#{permissions_path}/StoreKit"
end
To allow a Siri permission you will need to enable Siri capability in your app. This can be done one of two ways:
-
The first way is by navigating to Xcode > Signing & Capabilities > + > Siri and then enabling the capability
-
The second way is by updating the /ios/{app name}/{app name}.entitlements file as follows:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <!-- … --> <key>com.apple.developer.siri</key> <true/> </dict> </plist>
Android
Update the android/app/src/main/AndroidManifest.xml file with the needed permissions:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.myawesomeapp">
<!-- Keep only the permissions used in your app -->
<uses-permission android:name="android.permission.ACCEPT_HANDOVER" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
<uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL" />
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BODY_SENSORS" />
<uses-permission android:name="android.permission.BODY_SENSORS_BACKGROUND" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_MMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.USE_SIP" />
<uses-permission android:name="android.permission.UWB_RANGING" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALL_LOG" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<!-- … -->
</manifest>