-
-
Notifications
You must be signed in to change notification settings - Fork 662
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug]: Apple complains about the need for NSLocationAlwaysAndWhenInUseUsageDescription #1403
Comments
Dear @781flyingdutchman, Thanks for your input. I'll label this issue as an enhancement to keep track of it. Kind regards, |
…for 'always' permission, to prevent users getting rejected by Apple for not including NSLocationAlwaysAndWhenInUseUsageDescription even if they never require background location updates. The compile is conditional on the flag PERMISSION_LOCATION_ALWAYS being set in XCode under 'Preprocessor Macros'. If not set (the default) then the permission request for 'always' is not included in the binary, therefore not triggering a complaint by Apple. The request for 'always' (background) location updates is rare, so it is reasonable to have this turned off by default, and require some effort by the developer to activate this.
I've submitted a PR for this |
* Issue #1403 - On iOS, add conditional compile of the request for 'always' permission, to prevent users getting rejected by Apple for not including NSLocationAlwaysAndWhenInUseUsageDescription even if they never require background location updates. The compile is conditional on the flag PERMISSION_LOCATION_ALWAYS being set in XCode under 'Preprocessor Macros'. If not set (the default) then the permission request for 'always' is not included in the binary, therefore not triggering a complaint by Apple. The request for 'always' (background) location updates is rare, so it is reasonable to have this turned off by default, and require some effort by the developer to activate this. * Changed PERMISSION_LOCATION_ALWAYS to BYPASS_PERMISSION_LOCATION_ALWAYS such that the default behavior (no flag set) remains the same, and the change is non-breaking. Updated pubspec.yaml, README.md and CHANGELOG.md * Refinements to permission bypass for background location. Updates to CHANGELOG.md for geolocator and geolocator_apple Added code to Podfile for the examples in geolocator and geolocator_apple that - if uncommented - will bypass the permission request by automatically setting the bypass flag upon compilation. Updated README.md per suggestion
Solved in PR #1404, thanks @781flyingdutchman. |
@mvanbeusekom @781flyingdutchman The current library version does not address this issue. I encounter it consistently whenever attempting to release the app to the app store. So far, I've attempted to clean the Flutter project and have followed the two solutions outlined in the official library documentation, yet to no avail. This roadblock is hindering me from releasing the app on the Play Store. Your assistance in resolving this matter would be greatly appreciated. Please Help. post_install do |installer|
installer.pods_project.targets.each do |target|
if target.name == "geolocator_apple"
target.build_configurations.each do |config|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)', 'BYPASS_PERMISSION_LOCATION_ALWAYS=1']
end
end
end
end ITMS-90683: Missing purpose string in Info.plist - Your app’s code references one or more APIs that access sensitive user data, or the app has one or more entitlements that permit such access. The Info.plist file for the “Runner.app” bundle should contain a NSLocationAlwaysAndWhenInUseUsageDescription key with a user-facing purpose string explaining clearly and completely why your app needs the data. 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. For details, visit: https://developer.apple.com/documentation/uikit/protecting_the_user_s_privacy/requesting_access_to_protected_resources. |
That is strange: the use of compiler flags ensures that the code containing references to the API for background location is skipped (not compiled) so it does not appear in the binary that you submit to Apple. The fact that you get this response still from Apple suggests that the flag is not set correctly (by default, the code containing the API reference is compiled). As I mentioned to @mvanbeusekom the structure of the plugin makes it difficult for me to test, but what I can say is that if the flag is set correctly, then the code that references the sensitive API should show 'dimmed' in Xcode. Perhaps you can check if that's the case for you @yogeshelevn : the file is https://github.com/Baseflow/flutter-geolocator/blob/main/geolocator_apple/ios/Classes/Handlers/PermissionHandler.m, so find that file in your XCode project, and the lines that should show dimmed are 76-78 and 95-104. If they don't show dimmed after you have set the flag manually, then somehow you have not set the flag correctly! |
@781flyingdutchman I checked in my xcode project. line number from 76-78, 95-104 is dimmed as you mentioned still I am getting the issue. This is my PodFile and please do let me lnow it is correct or not. # Uncomment this line to define a global platform for your project
# platform :ios, '11.0'
platform :ios, '14.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|
# if target.name == "geolocator_apple"
# target.build_configurations.each do |config|
# config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)', 'BYPASS_PERMISSION_LOCATION_ALWAYS=1']
# end
# end
# end
# end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
if target.name == "geolocator_apple"
target.build_configurations.each do |config|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)', 'BYPASS_PERMISSION_LOCATION_ALWAYS=1']
end
end
target.build_configurations.each do |config|
config.build_settings['ONLY_ACTIVE_ARCH'] = 'NO'
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '14.0'
# You can remove unused permissions here
# for more infomation: 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)',
'PERMISSION_CONTACTS=1',
## dart: PermissionGroup.camera
'PERMISSION_CAMERA=1',
## dart: PermissionGroup.photos
'PERMISSION_PHOTOS=1',
## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
'PERMISSION_LOCATION=1',
'PERMISSION_NOTIFICATIONS=1',
## dart: PermissionGroup.mediaLibrary
'PERMISSION_MEDIA_LIBRARY=1',
]
end
awesome_pod_file = File.expand_path(File.join('plugins', 'awesome_notifications', 'ios', 'Scripts', 'AwesomePodFile'), '.symlinks')
require awesome_pod_file
update_awesome_pod_build_settings(installer)
end
awesome_pod_file = File.expand_path(File.join('plugins', 'awesome_notifications', 'ios', 'Scripts', 'AwesomePodFile'), '.symlinks')
require awesome_pod_file
update_awesome_main_target_settings('Runner', File.dirname(File.realpath(__FILE__)), flutter_root)
end https://drive.google.com/file/d/1EHP7dOXJQFmXE9M-6UOIwftIsZH_9k6X/view?usp=sharing |
Very strange. @mvanbeusekom do you have any idea how this could then still get compiled? Did you come across this issue with anyone else? |
Hi @yogeshelevn, I think the problem here is not with the configuration of the Unfortunately the At the moment there are two workarounds for you to take:
Alternatively I will research if we can add additional macros in the permission_handler plugin to allow more fine grained control. |
@yogeshelevn, we have just release version 11.3.1 of the permission_handler plugin which is updated to allow the use of only "When in use" permission. To configure this replace the # Uncomment this line to define a global platform for your project
# platform :ios, '11.0'
platform :ios, '14.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|
# if target.name == "geolocator_apple"
# target.build_configurations.each do |config|
# config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)', 'BYPASS_PERMISSION_LOCATION_ALWAYS=1']
# end
# end
# end
# end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
if target.name == "geolocator_apple"
target.build_configurations.each do |config|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)', 'BYPASS_PERMISSION_LOCATION_ALWAYS=1']
end
end
target.build_configurations.each do |config|
config.build_settings['ONLY_ACTIVE_ARCH'] = 'NO'
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '14.0'
# You can remove unused permissions here
# for more infomation: 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)',
'PERMISSION_CONTACTS=1',
## dart: PermissionGroup.camera
'PERMISSION_CAMERA=1',
## dart: PermissionGroup.photos
'PERMISSION_PHOTOS=1',
## dart: [PermissionGroup.location, PermissionGroup.locationWhenInUse]
'PERMISSION_LOCATION_WHENINUSE=1',
'PERMISSION_NOTIFICATIONS=1',
## dart: PermissionGroup.mediaLibrary
'PERMISSION_MEDIA_LIBRARY=1',
]
end
awesome_pod_file = File.expand_path(File.join('plugins', 'awesome_notifications', 'ios', 'Scripts', 'AwesomePodFile'), '.symlinks')
require awesome_pod_file
update_awesome_pod_build_settings(installer)
end
awesome_pod_file = File.expand_path(File.join('plugins', 'awesome_notifications', 'ios', 'Scripts', 'AwesomePodFile'), '.symlinks')
require awesome_pod_file
update_awesome_main_target_settings('Runner', File.dirname(File.realpath(__FILE__)), flutter_root)
end Hope this helps, if you have any problems please create an issue in the repo of the permission_handler plugin. |
Please check the following before submitting a new issue.
Please select affected platform(s)
Steps to reproduce
I have the NSLocationWhenInUseUsageDescription set, and don't want/expect my user to grant 'always' permission, so I have not set NSLocationAlwaysAndWhenInUseUsageDescription.
Expected results
No issue with Apple submission
Actual results
Apple rejects the app, because the plugin code in
PermissionHandler.m
line 76 contains a reference to the 'always' authorization[locationManager requestAlwaysAuthorization];
, even though I never request that (because NSLocationAlwaysAndWhenInUseUsageDescription is not set).You may have to implement an approach where users add a compile constant to the PodFile that allows you to conditionally compile the request for 'always' authorization (using
#if
, notif
). If it's not compiled, Apple won't complain.See here for how I've done this for a plugin I maintain. (commit)
Code sample
N/A
Screenshots or video
No response
Version
10.1.0
Flutter Doctor output
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.16.5, on macOS 14.2.1 23C71 darwin-arm64, locale en-US)
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 15.0.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2023.1)
[✓] Connected device (4 available)
[✓] Network resources
• No issues found!
The text was updated successfully, but these errors were encountered: