Baseflow / flutter-permission-handler

Permission plugin for Flutter. This plugin provides a cross-platform (iOS, Android) API to request and check permissions.
https://baseflow.com
MIT License
2.06k stars 864 forks source link

Apple Connect reject my app with unuse permission #276

Closed fy5220 closed 1 year ago

fy5220 commented 4 years ago

🐛 Bug Report

ITMS-90683: Missing Purpose String in Info.plist - Your app's code references one or more APIs that access sensitive user data. The app's Info.plist file should contain a NSLocationAlwaysUsageDescription key with a user-facing purpose string explaining clearly and completely why your app needs the data. Starting Spring 2019, all apps submitted to the App Store that access user data are required to include a purpose string. If you're using external libraries or SDKs, they may reference APIs that require a purpose string. While your app might not use these APIs, a purpose string is still required. You can contact the developer of the library or SDK and request they release a version of their code that doesn't contain the APIs. Learn more (https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy).

ITMS-90683: Missing Purpose String in Info.plist - Your app's code references one or more APIs that access sensitive user data. The app's Info.plist file should contain a NSLocationWhenInUseUsageDescription key with a user-facing purpose string explaining clearly and completely why your app needs the data. Starting Spring 2019, all apps submitted to the App Store that access user data are required to include a purpose string. If you're using external libraries or SDKs, they may reference APIs that require a purpose string. While your app might not use these APIs, a purpose string is still required. You can contact the developer of the library or SDK and request they release a version of their code that doesn't contain the APIs. Learn more (https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy).

podfile

# Uncomment this line to define a global platform for your project
# platform :ios, '9.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 parse_KV_file(file, separator='=')
  file_abs_path = File.expand_path(file)
  if !File.exists? file_abs_path
    return [];
  end
  generated_key_values = {}
  skip_line_start_symbols = ["#", "/"]
  File.foreach(file_abs_path) do |line|
    next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
    plugin = line.split(pattern=separator)
    if plugin.length == 2
      podname = plugin[0].strip()
      path = plugin[1].strip()
      podpath = File.expand_path("#{path}", file_abs_path)
      generated_key_values[podname] = podpath
    else
      puts "Invalid plugin specification: #{line}"
    end
  end
  generated_key_values
end

target 'Runner' do
  use_frameworks!
  use_modular_headers!

  # Flutter Pod

  copied_flutter_dir = File.join(__dir__, 'Flutter')
  copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework')
  copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec')
  unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path)
    # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet.
    # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration.
    # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist.

    generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig')
    unless File.exist?(generated_xcode_build_settings_path)
      raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first"
    end
    generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path)
    cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR'];

    unless File.exist?(copied_framework_path)
      FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir)
    end
    unless File.exist?(copied_podspec_path)
      FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir)
    end
  end

  # Keep pod path relative so it can be checked into Podfile.lock.
  pod 'Flutter', :path => 'Flutter'

  # Plugin Pods

  # Prepcdare symlinks folder. We use symlinks to avoid having Podfile.lock
  # referring to absolute paths on developers' machines.
  system('rm -rf .symlinks')
  system('mkdir -p .symlinks/plugins')
  plugin_pods = parse_KV_file('../.flutter-plugins')
  plugin_pods.each do |name, path|
    symlink = File.join('.symlinks', 'plugins', name)
    File.symlink(path, symlink)
    pod name, :path => File.join(symlink, 'ios')
  end
end

# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
install! 'cocoapods', :disable_input_output_paths => true

# post_install do |installer|
#   installer.pods_project.targets.each do |target|
#     target.build_configurations.each do |config|
#       config.build_settings['ENABLE_BITCODE'] = 'NO'
#     end
#   end
# end

# PermissionHandler删除无用权限
post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['ENABLE_BITCODE'] = 'NO'
        config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
          '$(inherited)',

        ## 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.photos
          'PERMISSION_PHOTOS=0',

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

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

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

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

pubspec.yaml

environment:
  sdk: ">=2.4.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter

  flutter_localizations:
    sdk: flutter

  cupertino_icons: ^0.1.2

  dio: ^3.0.8
  dio_cookie_manager: ^1.0.0
  cookie_jar: ^1.0.0

  provider: ^3.2.0

  webview_flutter: ^0.3.19+2

  quiver: ^2.0.5

  open_file: ^2.1.1

  device_info: ^0.4.0+1

  package_info: ^0.4.0+6

  connectivity: ^0.4.6+2

  shared_preferences: ^0.5.6

  localstorage: ^3.0.1+4

  permission_handler: ^5.0.0+hotfix.4

  url_launcher: ^5.4.1

  decimal: ^0.3.5

  bot_toast: ^2.4.1

  flutter_spinkit: "^4.1.2"

  shimmer: ^1.0.1

  qrcode: ^1.0.4

  pull_to_refresh: ^1.5.8

  cached_network_image: ^2.0.0

  flutter_screenutil: ^0.5.0

  badges: ^1.1.1

  mp_chart: ^0.1.9

info.plist

only have

NSCameraUsageDescription

Version: ^5.0.0+hotfix.4

Platform:

orestesgaolin commented 4 years ago

I have the same issue with few other permissions

aliakkawi commented 4 years ago

If you do not need Location permissions of all type you can add the following in your Podfile 'PERMISSION_LOCATION=0' In my case i need only location while in use , so i cannot add this line of code.

orestesgaolin commented 4 years ago

Even though I have added this line in my podfile as stated in the readme I received warning from AppStore Connect that I need to provide NSLocationWhenInUseUsageDescription

terry8204 commented 4 years ago

I have the same problem.

terry8204 commented 4 years ago

does some one fixed the issue?

orestesgaolin commented 4 years ago

I'm experimenting with some approaches (adding to build settings of target, project, schemes etc.) but nothing successful for now.

The only thing that worked was just adding the necessary permission strings to Info.plist. I added dummy texts such as "The app doesn't require access to location" etc.

terry8204 commented 4 years ago

after added the dummy texts, does show any dummy text to end user?

orestesgaolin commented 4 years ago

No, the text will be shown only when you actually request the permission from the user

terry8204 commented 4 years ago

Thank you, the great action.

No, the text will be shown only when you actually request the permission from the user

aliakkawi commented 4 years ago

@orestesgaolin Thanks for your advice, but i guess Apple requires an explanation in App description or as a review note , why do we actually included this type of permission in out App. Did that happened to you?

orestesgaolin commented 4 years ago

From my experience I can tell that if you provide the permissions string similar to "We are not using location permission", "The camera permission is not required" or "The app doesn't require access to sensors" then the review is positive. As long as you don't ask for these permissions then it should be ok.

It's fairly common that some 3rd party libraries use references in code to some API requiring permission but aren't actually used (e.g. location). The Apple analysis will detect it in symbols and will require adding a corresponding permission string. If you are not using it then you shouldn't worry too much.

From a purist point of view, however, I would like to be able to remove these permissions if that's stated in the documentation of the plugin.

terry8204 commented 4 years ago

@aliakkawi the permission_handler lib added the permissions, so we can't remove the permissions.

terry8204 commented 4 years ago

I have commit to the apple connect review . wait the result.

aliakkawi commented 4 years ago

@terry8204 Wish you good luck, update us with the results please.

redbrickred commented 4 years ago

Opinion:

For cases where your app does not need a given permission and you have to have a description string, I suggest instructing the user to deny the permission. "This app does not require access to ...X. Please deny this request." (Bonus points for instructing the user to alert you.)

Why? In case we get a rogue flutter package/library with malware - you can at least try to limit what that code can do.

terry8204 commented 4 years ago

@aliakkawi good luck, has passed the apple review.

aliakkawi commented 4 years ago

@terry8204 Congratulation!, glad to hear that, thanks for updating us!.

qiuguian commented 4 years ago

add dummy texts such as "The app doesn't require access to location" ? Can the plugin fit to use permission when what we use?

qiuguian commented 4 years ago

Although add the unuse text can pass the apple review, it doesn't what we want, what do you think?

c3qo commented 3 years ago

I guess the connectivity plugin requires NSLocationAlwaysUsageDescription/NSLocationWhenInUseUsageDescription permission, not permission-handler.

rockarts commented 3 years ago

I wouldn't suggest using the approach of adding the permissions to your Info.plist if you're not using them. When users go to install your application on iOS 14 they'll see in the privacy details that your app is requesting all these permissions even though it isn't using them. It will lead users to pass on installing your app.

JeroenWeener commented 1 year ago

I am closing this issue as there has been no activity in over 2 years. For help with the Podfile, please refer to the up-to-date documentation here. If you are encountering this issue, feel free to open a new issue, linking this issue.