flutter-permission-handler icon indicating copy to clipboard operation
flutter-permission-handler copied to clipboard

[Bug]: Unable to request camera or photo permissions on iOS 18.0.1

Open tonyliao273 opened this issue 1 year ago • 4 comments

Please check the following before submitting a new issue.

Please select affected platform(s)

  • [ ] Android
  • [X] iOS
  • [ ] Windows

Steps to reproduce

When requesting camera or photo permissions, nothing happens. Requesting them again still does nothing, but the following error appears in the log

  1. Requesting camera or photo permissions results in no action.
  2. Requesting camera or photo permissions again still does nothing, but the following error is logged:

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: PlatformException(ERROR_ALREADY_REQUESTING_PERMISSIONS, A request for permissions is already running, please wait for it to finish before doing another request (note that you can request multiple permissions at the same time)., null, null) #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:648:7) #1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:334:18) #2 MethodChannelPermissionHandler.requestPermissions (package:permission_handler_platform_interface/src/method_channel/method_channel_permission_handler.dart:80:9) #3 PermissionActions.request (package:permission_handler/permission_handler.dart:109:10)

Note:

  1. This issue also occurs with photo permissions but works fine with notification permissions.
  2. The issue is consistently reproducible on iOS 18.0.1 but works as expected on iOS 16.0, 17.2.1, and 18.1.1.

Expected results

On iOS 18.0.1 devices, requesting camera or photo permissions will trigger the system permission UI or any callbacks.

Actual results

On iOS 18.0.1 devices, requesting camera or photo permissions does not trigger the system permission UI or any callbacks.

Code sample

Code sample
      showCupertinoModalPopup(
        context: context,
        builder: (context) => CupertinoActionSheet(
          actions: [
            CupertinoActionSheetAction(
              child: Text( ... ),
              onPressed: () async {
                // close the options modal
                Navigator.of(context).pop();
                // get image from camera
                Permission.camera.onDeniedCallback(() {
                  _showNoCameraPermissionDialog(context);
                }).onGrantedCallback(() async {
                  final url = await _getImageFromCamera();
                  if (url != null) {
                    Facade.instance.navigatorKey.currentContext
                        ?.push('/edit_image', extra: File(url.path));
                  }
                }).onPermanentlyDeniedCallback(() {
                  _showNoCameraPermissionDialog(context);
                }).onRestrictedCallback(() {
                  _showNoCameraPermissionDialog(context);
                }).onLimitedCallback(() {
                  _showNoCameraPermissionDialog(context);
                }).onProvisionalCallback(() {
                  _showNoCameraPermissionDialog(context);
                }).request();
              },
            ),
            CupertinoActionSheetAction(
              child: Text(...),
              onPressed: () async {
                // close the options modal
                Navigator.of(context).pop();
                Permission.photos.onDeniedCallback(() {
                  _showNoPhotoLibraryPermissionDialog(context);
                }).onGrantedCallback(() async {
                  // get image from gallery
                  final url = await _getImageFromGallery();
                  if (url != null) {
                    Facade.instance.navigatorKey.currentContext
                        ?.push('/edit_image', extra: File(url.path));
                  }
                }).onPermanentlyDeniedCallback(() {
                  _showNoPhotoLibraryPermissionDialog(context);
                }).onRestrictedCallback(() {
                  _showNoPhotoLibraryPermissionDialog(context);
                }).onLimitedCallback(() async {
                  // get image from gallery
                  final url = await _getImageFromGallery();
                  if (url != null) {
                    Facade.instance.navigatorKey.currentContext
                        ?.push('/edit_image', extra: File(url.path));
                  }
                }).onProvisionalCallback(() {
                  _showNoPhotoLibraryPermissionDialog(context);
                }).request();
              },
            ),
          ],
          cancelButton: CupertinoActionSheetAction(
            child: Text(...),
            onPressed: () {
              Navigator.of(context).pop();
            },
          ),
        ),
      );

void _showNoCameraPermissionDialog(BuildContext context) {
    showAlertDialog(
      context: context,
      title: ...,
      content: ...,
      cancelActionText: ...,
      defaultActionText: ...,
      onDefaultAction: () {
        openAppSettings();
      },
    );
  }

  void _showNoPhotoLibraryPermissionDialog(BuildContext context) {
    showAlertDialog(
      context: context,
      title: ...,
      content: ...,
      cancelActionText: ...,
      defaultActionText: ...,
      onDefaultAction: () {
        openAppSettings();
      },
    );
  }
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
    target.build_configurations.each do |config|
      config.build_settings['CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES'] = 'YES'
      config.build_settings['ENABLE_BITCODE'] = 'NO'
      # You can enable the permissions needed here. For example to enable camera
      # permission, just remove the `#` character in front so it looks like this:
      #
      # ## dart: PermissionGroup.camera
      # 'PERMISSION_CAMERA=1'
      #
      #  Preprocessor definitions can be found in: https://github.com/Baseflow/flutter-permission-handler/blob/master/permission_handler_apple/ios/Classes/PermissionHandlerEnums.h
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',

        ## dart: PermissionGroup.calendar
        # 'PERMISSION_EVENTS=1',

        ## dart: PermissionGroup.reminders
        # 'PERMISSION_REMINDERS=1',

        ## dart: PermissionGroup.contacts
        # 'PERMISSION_CONTACTS=1',

        ## dart: PermissionGroup.camera
        'PERMISSION_CAMERA=1',

        ## dart: PermissionGroup.microphone
        # 'PERMISSION_MICROPHONE=1',

        ## dart: PermissionGroup.speech
        # 'PERMISSION_SPEECH_RECOGNIZER=1',

        ## dart: PermissionGroup.photos
        'PERMISSION_PHOTOS=1',

        ## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
        # 'PERMISSION_LOCATION=1',

        ## dart: PermissionGroup.notification
        'PERMISSION_NOTIFICATIONS=1',

        ## dart: PermissionGroup.mediaLibrary
        # 'PERMISSION_MEDIA_LIBRARY=1',

        ## dart: PermissionGroup.sensors
        # 'PERMISSION_SENSORS=1',   

        ## dart: PermissionGroup.bluetooth
        # 'PERMISSION_BLUETOOTH=1',

        ## dart: PermissionGroup.appTrackingTransparency
        # 'PERMISSION_APP_TRACKING_TRANSPARENCY=1',

        ## dart: PermissionGroup.criticalAlerts
        # 'PERMISSION_CRITICAL_ALERTS=1'
      ]
    end
  end

Screenshots or video

iOS 18.0.1

https://github.com/user-attachments/assets/700e7482-25c4-4465-9016-5b1f0cd42621

iOS 16.0

https://github.com/user-attachments/assets/7ba45b44-f125-4ce7-bf46-18ce947422b5

Version

11.3.1

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.22.2, on macOS 15.1 24B83 darwin-arm64, locale zh-Hant-TW)
    • Flutter version 3.22.2 on channel stable at /Users/tonyliao/fvm/versions/3.22.2
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 761747bfc5 (6 months ago), 2024-06-05 22:15:13 +0200
    • Engine revision edd8546116
    • Dart version 3.4.3
    • DevTools version 2.34.3

[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.0)
    • Android SDK at /Users/tonyliao/Library/Android/sdk
    • Platform android-35, build-tools 35.0.0
    • ANDROID_HOME = /Users/tonyliao/Library/Android/sdk
    • ANDROID_SDK_ROOT = /Users/tonyliao/Library/Android/sdk
    • Java binary at: /Users/tonyliao/Applications/Android Studio Koala Feature Drop 2024.1.2 RC 1.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.11+0-17.0.11b1207.24-11852314)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 16.0)
    • Xcode at /Applications/Xcode-16.0.0.app/Contents/Developer
    • Build 16A242d
    • CocoaPods version 1.15.2

[✓] Android Studio (version 2022.3)
    • Android Studio at /Applications/Android Studio.Giraffe 2022.3.1.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)

[✓] Android Studio (version 2024.1)
    • Android Studio at /Users/tonyliao/Applications/Android Studio Koala Feature Drop 2024.1.2 RC 1.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.11+0-17.0.11b1207.24-11852314)

[!] Android Studio (version unknown)
    • Android Studio at /Users/tonyliao/Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    ✗ Unable to determine Android Studio version.
    • Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11572160)

[✓] VS Code (version 1.95.3)
    • VS Code at /Applications/Visual Studio Code-Arm64.app/Contents
    • Flutter extension version 3.102.0

[✓] Connected device (5 available)
    • Pixel 9 (mobile)                • 46271FDAQ111W1                           • android-arm64 • Android 15 (API 35)
    • CP081 iPhone 15 (mobile)        • 00008122-1119389E0A82201E                • ios           • iOS 18.0.1 22A3370
    • CP038 iPhone 8 (mobile)         • 85315293e171117d61bdca83470831a4a5185f84 • ios           • iOS 16.0 20A362
    • macOS (desktop)                 • macos                                    • darwin-arm64  • macOS 15.1 24B83 darwin-arm64
    • Mac Designed for iPad (desktop) • mac-designed-for-ipad                    • darwin        • macOS 15.1 24B83 darwin-arm64

[✓] Network resources
    • All expected network resources are available.

tonyliao273 avatar Dec 12 '24 03:12 tonyliao273

You could try the following way and see if it works. This work for me.

  1. Add the following to your Podfile file:
post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      # You can remove unused permissions here
      # for more information: https://github.com/BaseflowIT/flutter-permission-handler/blob/master/permission_handler/ios/Classes/PermissionHandlerEnums.h
      # e.g. when you don't need camera permission, just add 'PERMISSION_CAMERA=0'
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',

        ## dart: PermissionGroup.calendar
         #'PERMISSION_EVENTS=1',
        
        ## dart: PermissionGroup.calendarFullAccess
         #'PERMISSION_EVENTS_FULL_ACCESS=1',

        ## dart: PermissionGroup.reminders
         #'PERMISSION_REMINDERS=1',

        ## dart: PermissionGroup.contacts
         #'PERMISSION_CONTACTS=1',

        ## dart: PermissionGroup.camera
        'PERMISSION_CAMERA=1',

        ## dart: PermissionGroup.microphone
         #'PERMISSION_MICROPHONE=1',

        ## dart: PermissionGroup.speech
         #'PERMISSION_SPEECH_RECOGNIZER=1',

        ## dart: PermissionGroup.photos
        'PERMISSION_PHOTOS=1',

        ## The 'PERMISSION_LOCATION' macro enables the `locationWhenInUse` and `locationAlways` permission. If
        ## the application only requires `locationWhenInUse`, only specify the `PERMISSION_LOCATION_WHENINUSE`
        ## macro.
        ##
        ## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
         #'PERMISSION_LOCATION=1',
         #'PERMISSION_LOCATION_WHENINUSE=0',

        ## dart: PermissionGroup.notification
         #'PERMISSION_NOTIFICATIONS=1',

        ## dart: PermissionGroup.mediaLibrary
         'PERMISSION_MEDIA_LIBRARY=1',

        ## dart: PermissionGroup.sensors
         #'PERMISSION_SENSORS=1',

        ## dart: PermissionGroup.bluetooth
         #'PERMISSION_BLUETOOTH=1',

        ## dart: PermissionGroup.appTrackingTransparency
         #'PERMISSION_APP_TRACKING_TRANSPARENCY=1',

        ## dart: PermissionGroup.criticalAlerts
         #'PERMISSION_CRITICAL_ALERTS=1',

        ## dart: PermissionGroup.criticalAlerts
         #'PERMISSION_ASSISTANT=1',
      ]
    end
    flutter_additional_ios_build_settings(target)
  end
end
  1. Remove the # character in front of the permission you want to use. For example, if you need access to the calendar make sure the code looks like this: 'PERMISSION_PHOTOS=1',
  2. flutter clean
  3. flutter pub get
  4. flutter run

doasinfinity avatar Dec 26 '24 07:12 doasinfinity

@doasinfinity I copied yours in my Podfile, but it still doesn't have permission to apply for tips, and the returned value is PermanentlyDenied.Is there any other solution?

COLOUREDGLAZES avatar Jan 18 '25 11:01 COLOUREDGLAZES

For me these was the problem thanks I had the same problems. I added to info.plist the keys but forgot the pod files.

bartalusCsaba avatar Mar 31 '25 12:03 bartalusCsaba

thanks man , it work for camera

this is my info.plist (iOS/Runner/info.plist)

	<key>NSPhotoLibraryUsageDescription</key>
    <string>Allow access to your Photos to share images and videos in your posts.</string>

    <key>NSPhotoLibraryAddUsageDescription</key>
    <string>Save published content or edited media back to your Photos library.</string>

    <key>NSCameraUsageDescription</key>
    <string>Take photos and videos directly in the app to share with your audience.</string>

this is my pods (iOS/Podfile)

# Uncomment this line to define a global platform for your project
# platform :ios, '12.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

project 'Runner', {
  'Debug' => :debug,
  'Profile' => :release,
  'Release' => :release,
}

def flutter_root
  generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
  unless File.exist?(generated_xcode_build_settings_path)
    raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
  end

  File.foreach(generated_xcode_build_settings_path) do |line|
    matches = line.match(/FLUTTER_ROOT\=(.*)/)
    return matches[1].strip if matches
  end
  raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end

require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)

flutter_ios_podfile_setup

target 'Runner' do
  use_frameworks!
  use_modular_headers!

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
  target 'RunnerTests' do
    inherit! :search_paths
  end
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
    target.build_configurations.each do |config|
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',

         ## dart: PermissionGroup.camera
         'PERMISSION_CAMERA=1',
      ]
    end
  end
end

houssam15 avatar Apr 24 '25 12:04 houssam15