Please check the following before submitting a new issue.
Please select affected platform(s)
Steps to reproduce
This reproduces in a newly created Flutter application with the default single ios/Runner/Info.plist. There are no flavors, extensions, custom plist paths, or permission-related environment variables.
- Create a clean project and add the current package:
flutter create --platforms=ios permission_handler_repro
cd permission_handler_repro
flutter pub add permission_handler:^13.0.1
This resolves permission_handler_apple 9.6.1.
- Add only the foreground location purpose string to
ios/Runner/Info.plist:
<key>NSLocationWhenInUseUsageDescription</key>
<string>Location is used while the app is open.</string>
Do not add NSLocationAlwaysAndWhenInUseUsageDescription.
- Request only the foreground permission:
await Permission.locationWhenInUse.request();
- Make sure no location macro overrides are present and build the release application:
unset PERMISSION_LOCATION
unset PERMISSION_LOCATION_ALWAYS
unset PERMISSION_LOCATION_WHENINUSE
flutter clean
flutter pub get
flutter build ios --release --no-codesign
- Inspect the built application:
/usr/libexec/PlistBuddy \
-c 'Print :NSLocationAlwaysAndWhenInUseUsageDescription' \
build/ios/iphoneos/Runner.app/Info.plist
strings build/ios/iphoneos/Runner.app/Runner \
| grep -E '^request(Always|WhenInUse)Authorization$'
The plist correctly contains no Always purpose string, but the binary contains requestAlwaysAuthorization.
The manifest result can also be inspected with verbose output and the manifest cache disabled:
PERMISSION_HANDLER_VERBOSE=1 \
swift package --manifest-cache none \
--package-path ios/Flutter/ephemeral/Packages/.packages/permission_handler_apple-9.6.1 \
dump-package
Relevant output:
PERMISSION_LOCATION=1
PERMISSION_LOCATION_ALWAYS=0
PERMISSION_LOCATION_WHENINUSE=1
- Archive and upload the application to App Store Connect. Validation reports ITMS-90683 and requests
NSLocationAlwaysAndWhenInUseUsageDescription.
Expected results
When the app declares only NSLocationWhenInUseUsageDescription and requests only Permission.locationWhenInUse:
- only foreground location support should be compiled;
- the release binary should contain
requestWhenInUseAuthorization;
- the release binary should not contain
requestAlwaysAuthorization;
- App Store Connect should not require
NSLocationAlwaysAndWhenInUseUsageDescription.
Actual results
SwiftPM enables both the generic and foreground macros:
PERMISSION_LOCATION=1
PERMISSION_LOCATION_ALWAYS=0
PERMISSION_LOCATION_WHENINUSE=1
The release binary contains:
requestAlwaysAuthorization
requestWhenInUseAuthorization
App Store Connect then reports:
ITMS-90683: Missing purpose string in Info.plist
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.
Adding that key would provide a misleading privacy declaration because the application neither needs nor requests Always location access.
This is not an Info.plist discovery or stale-cache issue: it reproduces in a clean, single-plist Flutter project, and verbose manifest output confirms that the intended plist was discovered.
Code sample
Code sample
```dart
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
void main() => runApp(const MaterialApp(home: ReproPage()));
class ReproPage extends StatelessWidget {
const ReproPage({super.key});
@OverRide
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: Permission.locationWhenInUse.request,
child: const Text('Request location when in use'),
),
),
);
}
}
### Screenshots or video
<details>
<summary>Screenshots or video demonstration</summary>
[Upload media here]
</details>
### Version
permission_handler: 13.0.1, permission_handler_apple: 9.6.1
### Flutter Doctor output
<details><summary>Doctor output</summary>
```console
[✓] Flutter (Channel stable, 3.47.1, on macOS 26.4 25E246 darwin-arm64, locale ru-KZ) [184ms]
• Flutter version 3.47.1 on channel stable at /Users/dev/fvm/versions/3.47.1
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 6655482ec0 (7 days ago), 2026-08-19 10:07:23 -0700
• Engine revision 5d53178869
• Dart version 3.13.1
• DevTools version 2.60.0
• Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android, enable-ios, cli-animations, enable-native-assets, enable-record-use, enable-swift-package-manager, omit-legacy-version-file, enable-lldb-debugging, enable-uiscene-migration
[✓] Android toolchain - develop for Android devices (Android SDK version 37.0.0) [846ms]
• Android SDK at /Users/dev/Library/Android/sdk
• Emulator version 36.6.11.0 (build_id 15507667) (CL:N/A)
• Platform android-37.0, build-tools 37.0.0
• ANDROID_HOME = /Users/dev/Library/Android/sdk
• Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
This is the JDK bundled with the latest Android Studio installation on this machine.
To manually set the JDK path, use: `flutter config --jdk-dir="path/to/jdk"`.
• Java version OpenJDK Runtime Environment (build 21.0.10+-117844308-b1163.108)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 26.6) [477ms]
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 17F113
• CocoaPods version 1.17.0
[✗] Chrome - develop for the web (Cannot find Chrome executable at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome) [3ms]
! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.
[✓] Connected device (2 available) [5,6s]
• Xs (mobile) • <redacted> • ios • iOS 18.3.1 22D72
• macOS (desktop) • macos • darwin-arm64 • macOS 26.4 25E246 darwin-arm64
[✓] Network resources [309ms]
• All expected network resources are available.
! Doctor found issues in 1 category.
Please check the following before submitting a new issue.
Please select affected platform(s)
Steps to reproduce
This reproduces in a newly created Flutter application with the default single
ios/Runner/Info.plist. There are no flavors, extensions, custom plist paths, or permission-related environment variables.This resolves
permission_handler_apple 9.6.1.ios/Runner/Info.plist:Do not add
NSLocationAlwaysAndWhenInUseUsageDescription.The plist correctly contains no Always purpose string, but the binary contains
requestAlwaysAuthorization.The manifest result can also be inspected with verbose output and the manifest cache disabled:
Relevant output:
NSLocationAlwaysAndWhenInUseUsageDescription.Expected results
When the app declares only
NSLocationWhenInUseUsageDescriptionand requests onlyPermission.locationWhenInUse:requestWhenInUseAuthorization;requestAlwaysAuthorization;NSLocationAlwaysAndWhenInUseUsageDescription.Actual results
SwiftPM enables both the generic and foreground macros:
The release binary contains:
App Store Connect then reports:
Adding that key would provide a misleading privacy declaration because the application neither needs nor requests Always location access.
This is not an Info.plist discovery or stale-cache issue: it reproduces in a clean, single-plist Flutter project, and verbose manifest output confirms that the intended plist was discovered.
Code sample
Code sample
```dart import 'package:flutter/material.dart'; import 'package:permission_handler/permission_handler.dart';void main() => runApp(const MaterialApp(home: ReproPage()));
class ReproPage extends StatelessWidget {
const ReproPage({super.key});
@OverRide
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: Permission.locationWhenInUse.request,
child: const Text('Request location when in use'),
),
),
);
}
}