How to ask the user for permission to make a phone call for iOS in the Flutter application?
My application has code that makes a phone call, but first asks the user for permission. I need permission to be obtained directly during the call, if possible.
Future<void> _makePhoneCall() async {
if (Platform.isAndroid) {
final callPermissionStatus = await Permission.phone.request();
if (callPermissionStatus.isGranted) {
final String userPhone = contactPhone;
try {
const MethodChannel('caller').invokeMethod('makeCall', userPhone);
} on PlatformException catch (e) {
Fluttertoast.showToast(
msg: AppLocalizations.instance.translate("failedToCallTheNumber") +
("$contactPhone, ${e.message}"),
);
}
} else {
Fluttertoast.showToast(
msg: AppLocalizations.instance.translate("failedToCallTheNumber") +
("$contactPhone"),
);
}
} else if (Platform.isIOS) {
final callPermissionStatus = await Permission.phone.request();
if (callPermissionStatus.isGranted) {
final String userPhone = contactPhone;
try {
const MethodChannel('caller')
.invokeMethod('makeCall', userPhone);
} on PlatformException catch (e) {
Fluttertoast.showToast(
msg: AppLocalizations.instance.translate("failedToCallTheNumber") +
(" $contactPhone, ${e.message}"),
);
}
} else {
final String userPhone = contactPhone;
Fluttertoast.showToast(
msg: AppLocalizations.instance.translate("failedToCallTheNumber") +
(" $userPhone"),
);
}
}
}
This code works fine on Android, but on iOS there is no dialog box asking the user for permission. I'm using permission_handler: ^11.3.1
but in the documentation for permission_handler: ^11.3.1 I found a description for the "phone" - /// Permission for accessing the device's phone state (Android only). static const phone = PermissionWithService._(8);
What should I use instead of "phone" to open the phone call permission dialog for iOS? Or should I use another library rather than permission_handler?
My flutter doctor -
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.19.5, on macOS 14.4.1 23E224 darwin-arm64, locale ru-UA)
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 15.3)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2023.2)
[✓] VS Code (version 1.87.2)
[✓] VS Code (version 1.87.2)
[✓] Connected device (3 available)
[✓] Network resources
• No issues found!
if you replace in line - final callPermissionStatus = await Permission.phone.request();
- “phone” with “contacts” - then a dialog box appears asking for permission to access contacts.
I also added these lines to the info.plist
<key>LSApplicationQueriesSchemes</key>
<array>
<string>needed to make phone calls</string>
</array>
<key>NSCallKitUsageDescription</key>
<string>Call access permission is required to make calls.</string>
<key>NSContactsUsageDescription</key>
<string>Permission to access contacts is required to make calls.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Permission to access the microphone is required to make calls.</string>
I'm not sure if all these lines are needed, I tried to add everything to allow a phone call to be made.
Answers
In iOS, you don't directly ask for permission to make phone calls like you do in Android. Instead, you need to use a different approach due to platform restrictions. Here's how you can achieve this in your Flutter app:
-
Use URL Scheme: In iOS, you can make a phone call by opening the Phone app with a specific URL scheme. You can use the
url_launcher
package in Flutter to achieve this. First, addurl_launcher
to yourpubspec.yaml
file:dependencies: flutter: sdk: flutter url_launcher: ^6.0.12
-
Update Code: Update your
_makePhoneCall
method to useurl_launcher
to open the Phone app with the specified phone number:import 'package:url_launcher/url_launcher.dart'; Future<void> _makePhoneCall() async { final String userPhone = contactPhone; final String phoneNumber = 'tel:$userPhone'; try { if (await canLaunch(phoneNumber)) { await launch(phoneNumber); } else { Fluttertoast.showToast( msg: 'Could not launch $phoneNumber', ); } } catch (e) { Fluttertoast.showToast( msg: 'Error: $e', ); } }
-
Request Permission for URL Scheme: You don't need to explicitly request permission to make phone calls in iOS. Instead, you need to add the appropriate usage description in your
Info.plist
file. You've already added the necessary descriptions for microphone, contacts, and call access, which is good.<key>NSMicrophoneUsageDescription</key> <string>Permission to access the microphone is required to make calls.</string> <key>NSContactsUsageDescription</key> <string>Permission to access contacts is required to make calls.</string> <key>NSCallKitUsageDescription</key> <string>Call access permission is required to make calls.</string>
Make sure to replace contactPhone
with the actual phone number you want to call. With this approach, iOS users will be able to make phone calls directly from your app by tapping on the phone number, and they will not be prompted for permission to make the call.