Is there an easy way to find packages that use permissions in flutter? Missing Purpose String in Info.plist submission problem
Asked Answered
L

3

12

During the submission to Apple of the application I was notified of the following ITMS-90683: Missing Purpose String in Info.plist.

NSBluetoothPeripheralUsageDescription
NSBluetoothAlwaysUsageDescription
NSLocationWhenInUseUsageDescription 

Previously the problem was related to the permission_handler package but with a script that is provided in the documentation it was possible to effectively exclude the permissions that the package touches but are not used by the application. After updating all the dependencies and adding many others, I find myself prompted to enter these other three permissions that I'm not really going to use. Is there a quick way to find which of these packages go to use? If there is no idea which package might require these permissions?

  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.2
  flutter_spinkit: ^5.0.0
  shared_preferences: ^2.0.4
  cached_network_image: 2.5.1
  cached_video_player: ^1.0.3
  rxdart: ^0.25.0
  flutter_inappwebview: ^5.1.0+4
  sqflite: ^2.0.0+2
  path: ^1.8.0
  pull_to_refresh: ^1.6.4
  font_awesome_flutter: ^8.12.0
  flutter_svg: ^0.19.3
  purchases_flutter: ^3.1.0
  url_launcher: ^6.0.2
  rflutter_alert: ^2.0.2
  modal_progress_hud: ^0.1.3
  sizer: ^1.1.8
  permission_handler: ^6.1.0
  image_gallery_saver: ^1.6.8
  http: ^0.13.0
  path_provider: ^2.0.1
  onesignal_flutter: ^3.0.0-beta1
  google_mobile_ads: ^0.11.0+3
  #Firebase dependencies
  firebase_core: ^1.0.1
  firebase_auth: ^1.0.1
  cloud_firestore: ^1.0.1
  firebase_crashlytics: ^1.0.0
  firebase_analytics: ^7.1.1 

I don't want to add justification for permissions that I'm not going to use. Thank you

EDIT 1: I am attaching the section of the Podfile that is requested by permission_handler. as indicated in the readme, the permissions that are actually used by my app have been commented (PHOTOS and NOTIFICATIONS)

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['IPHONEOS_DEPLOYMENT_TARGET'] = '10.0'
      config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'

    # You can remove unused permissions here
    # for more infomation: https://github.com/BaseflowIT/flutter-permission-handler/blob/develop/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.photos
      # 'PERMISSION_PHOTOS=0',

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

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

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

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

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

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

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

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

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

      ## dart: PermissionGroup.sensors
      'PERMISSION_SENSORS=0'
    ]
    end
  end
end

EDIT 2: Is it possible that the bluetooth permissions is a bug of the new flutter version 2.0.2? Flutter in debug mode, at the first launch of the iOS app, it always asked for permissions to detect nearby devices (even in the version I was using previously 1.22)

Lyra answered 17/3, 2021 at 16:58 Comment(5)
The quickest (though perhaps not most convenient) way would be to go to your .pub-cache folder and do a recursive search for those strings in any Info.plist files you can find. Take the matches and backtrack to the package root folder, and that will tell you which packages use those permissions.Allergic
Can you share your Pod file? Maybe you missed to exclude the bluetooth and location when in use permissions? Also, why are you importing two versions of the permission plugin? permission_handler: ^5.1.0+2 permission_handler: ^6.1.0 Just use the latest!Author
@Author I have updated the question with the Podfile permission's section. Is it possible that the bluetooth permissions is a bug of the new flutter version 2.0.2? Flutter in debug mode, at the first launch of the iOS app, it always asked for permissions to detect nearby devices (even in the version I was using previously 1.22)Lyra
I doubt that it's a bug in 2.0.2 and no one noticed that you can't publish to App store. Your Podfile looks fine.Author
This is the updated link to PermissionHandlerEnums.h file on flutter-permission-handler project: github.com/Baseflow/flutter-permission-handler/blob/master/…Volley
J
13

Try

## dart: PermissionGroup.bluetooth
'PERMISSION_BLUETOOTH=0'

It was added recently to permission_handler GitHub documentation: https://github.com/Baseflow/flutter-permission-handler

Joyous answered 19/3, 2021 at 5:41 Comment(1)
True! The permission_handler package from version 6.1.0 has added the permissions for bluetooth. This solves the two bluetooth dependencies. As for the permission NSLocationWhenInUseUsageDescription it continues to be present but appears to be a false positive. After 10 minutes from the first email 'ITMS-90683: Missing Purpose String' another email has arrived confirming the use in TestFlight. Thank you!Lyra
F
0

Another permission that they can also remove, and that is not in the documentation is:

## dart: PermissionGroup.photosAddOnly
'PERMISSION_PHOTOS_ADD_ONLY = 0',
Filiform answered 6/4, 2021 at 23:39 Comment(0)
T
0

I'll explain it using my example. I had a problem with the unwanted NSMicrophoneUsageDescription permission.

Open the iOS project in Xcode (the ios folder). Use global search to find a pod that has a function call used to request that permission. In my case, it was AVAudioApplication.requestRecordPermission called by the "audio_session" pod:

Xcode project search

It's pretty straightforward if it's a direct dependency, but if it's a transitive one, run flutter pub deps and find out a direct dependency that uses it. In my case, it was "package X -> just_audio -> audio_session":

├── X 1.0.0
│   ├── just_audio 0.9.34
│   │   ├── audio_session 0.1.16

Usually, packages provide an option to add preprocessor macros to exclude these calls during the compilation. You can also see it in the source code of plugins. Here the AUDIO_SESSION_MICROPHONE macro is used:

- (void)requestRecordPermission:(NSArray *)args result:(FlutterResult)result {
#if AUDIO_SESSION_MICROPHONE
    [[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) {
        result(@(granted));
    }];
#else
    result(FlutterMethodNotImplemented);
#endif
}

With permission_handler it's PERMISSION_.... In my case with just_audio it was AUDIO_SESSION_MICROPHONE. Add the needed macros to the project's Podfile:

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)',
        'AUDIO_SESSION_MICROPHONE=0',
      ]
    end
  end
end

If there's no way to provide a preprocessor macro that excludes the call to that package, ask a maintainer to implement it.

Transcendental answered 26/7, 2023 at 8:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.