Fix iOS beacon permissions for location and Bluetooth
iOS Permissions: - Add missing Info.plist keys for location and Bluetooth usage descriptions - Configure Podfile to enable PERMISSION_LOCATION and PERMISSION_BLUETOOTH - Fix beacon_permissions.dart to use correct iOS permission (Permission.bluetooth) instead of Android-only bluetoothScan/bluetoothConnect The permission_handler plugin requires platform-specific handling: - iOS: Uses Permission.bluetooth for Bluetooth access - Android: Uses Permission.bluetoothScan and Permission.bluetoothConnect 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
29646a8a04
commit
ef5609ba57
6 changed files with 51 additions and 18 deletions
|
|
@ -39,5 +39,14 @@ end
|
||||||
post_install do |installer|
|
post_install do |installer|
|
||||||
installer.pods_project.targets.each do |target|
|
installer.pods_project.targets.each do |target|
|
||||||
flutter_additional_ios_build_settings(target)
|
flutter_additional_ios_build_settings(target)
|
||||||
|
|
||||||
|
# Enable permissions for permission_handler
|
||||||
|
target.build_configurations.each do |config|
|
||||||
|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
|
||||||
|
'$(inherited)',
|
||||||
|
'PERMISSION_LOCATION=1',
|
||||||
|
'PERMISSION_BLUETOOTH=1',
|
||||||
|
]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,6 @@ SPEC CHECKSUMS:
|
||||||
StripePaymentsUI: 326376e23caa369d1f58041bdb858c89c2b17ed4
|
StripePaymentsUI: 326376e23caa369d1f58041bdb858c89c2b17ed4
|
||||||
StripeUICore: 17a4f3adb81ae05ab885e1b353022a430176eab1
|
StripeUICore: 17a4f3adb81ae05ab885e1b353022a430176eab1
|
||||||
|
|
||||||
PODFILE CHECKSUM: 3c63482e143d1b91d2d2560aee9fb04ecc74ac7e
|
PODFILE CHECKSUM: 585f1361913628fd422da91acb10f1ea62e8189d
|
||||||
|
|
||||||
COCOAPODS: 1.16.2
|
COCOAPODS: 1.16.2
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,6 @@
|
||||||
F2C711915F4DC721B46B55FB /* Pods-RunnerTests.release.xcconfig */,
|
F2C711915F4DC721B46B55FB /* Pods-RunnerTests.release.xcconfig */,
|
||||||
BF07229F38A392371BF2BB5F /* Pods-RunnerTests.profile.xcconfig */,
|
BF07229F38A392371BF2BB5F /* Pods-RunnerTests.profile.xcconfig */,
|
||||||
);
|
);
|
||||||
name = Pods;
|
|
||||||
path = Pods;
|
path = Pods;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
|
@ -490,6 +489,7 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
|
DEVELOPMENT_TEAM = 2UD2H98KPK;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
|
@ -674,6 +674,7 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
|
DEVELOPMENT_TEAM = 2UD2H98KPK;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
|
@ -696,6 +697,7 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
|
DEVELOPMENT_TEAM = 2UD2H98KPK;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
</Testables>
|
</Testables>
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Release"
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
|
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,14 @@
|
||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
</array>
|
</array>
|
||||||
|
<key>NSLocationWhenInUseUsageDescription</key>
|
||||||
|
<string>Payfrit needs your location to find nearby restaurant tables and beacons.</string>
|
||||||
|
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
|
||||||
|
<string>Payfrit needs your location to find nearby restaurant tables and beacons.</string>
|
||||||
|
<key>NSBluetoothAlwaysUsageDescription</key>
|
||||||
|
<string>Payfrit uses Bluetooth to detect table beacons for seamless ordering.</string>
|
||||||
|
<key>NSBluetoothPeripheralUsageDescription</key>
|
||||||
|
<string>Payfrit uses Bluetooth to detect table beacons for seamless ordering.</string>
|
||||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'dart:io';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
|
||||||
|
|
@ -6,22 +7,29 @@ class BeaconPermissions {
|
||||||
try {
|
try {
|
||||||
// Request location permission (required for Bluetooth scanning)
|
// Request location permission (required for Bluetooth scanning)
|
||||||
final locationStatus = await Permission.locationWhenInUse.request();
|
final locationStatus = await Permission.locationWhenInUse.request();
|
||||||
|
debugPrint('[BeaconPermissions] Location: $locationStatus');
|
||||||
|
|
||||||
// Request Bluetooth permissions (Android 12+)
|
bool bluetoothGranted = true;
|
||||||
|
|
||||||
|
if (Platform.isIOS) {
|
||||||
|
// iOS uses a single Bluetooth permission
|
||||||
|
final bluetoothStatus = await Permission.bluetooth.request();
|
||||||
|
debugPrint('[BeaconPermissions] Bluetooth (iOS): $bluetoothStatus');
|
||||||
|
bluetoothGranted = bluetoothStatus.isGranted;
|
||||||
|
} else {
|
||||||
|
// Android 12+ requires separate scan/connect permissions
|
||||||
final bluetoothScan = await Permission.bluetoothScan.request();
|
final bluetoothScan = await Permission.bluetoothScan.request();
|
||||||
final bluetoothConnect = await Permission.bluetoothConnect.request();
|
final bluetoothConnect = await Permission.bluetoothConnect.request();
|
||||||
|
debugPrint('[BeaconPermissions] BluetoothScan: $bluetoothScan, BluetoothConnect: $bluetoothConnect');
|
||||||
|
bluetoothGranted = bluetoothScan.isGranted && bluetoothConnect.isGranted;
|
||||||
|
}
|
||||||
|
|
||||||
final allGranted = locationStatus.isGranted &&
|
final allGranted = locationStatus.isGranted && bluetoothGranted;
|
||||||
bluetoothScan.isGranted &&
|
|
||||||
bluetoothConnect.isGranted;
|
|
||||||
|
|
||||||
if (allGranted) {
|
if (allGranted) {
|
||||||
debugPrint('[BeaconPermissions] ✅ All permissions granted');
|
debugPrint('[BeaconPermissions] ✅ All permissions granted');
|
||||||
} else {
|
} else {
|
||||||
debugPrint('[BeaconPermissions] ❌ Permissions denied: '
|
debugPrint('[BeaconPermissions] ❌ Permissions denied');
|
||||||
'location=$locationStatus, '
|
|
||||||
'bluetoothScan=$bluetoothScan, '
|
|
||||||
'bluetoothConnect=$bluetoothConnect');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return allGranted;
|
return allGranted;
|
||||||
|
|
@ -33,12 +41,18 @@ class BeaconPermissions {
|
||||||
|
|
||||||
static Future<bool> checkPermissions() async {
|
static Future<bool> checkPermissions() async {
|
||||||
final locationStatus = await Permission.locationWhenInUse.status;
|
final locationStatus = await Permission.locationWhenInUse.status;
|
||||||
|
|
||||||
|
bool bluetoothGranted = true;
|
||||||
|
if (Platform.isIOS) {
|
||||||
|
final bluetoothStatus = await Permission.bluetooth.status;
|
||||||
|
bluetoothGranted = bluetoothStatus.isGranted;
|
||||||
|
} else {
|
||||||
final bluetoothScan = await Permission.bluetoothScan.status;
|
final bluetoothScan = await Permission.bluetoothScan.status;
|
||||||
final bluetoothConnect = await Permission.bluetoothConnect.status;
|
final bluetoothConnect = await Permission.bluetoothConnect.status;
|
||||||
|
bluetoothGranted = bluetoothScan.isGranted && bluetoothConnect.isGranted;
|
||||||
|
}
|
||||||
|
|
||||||
return locationStatus.isGranted &&
|
return locationStatus.isGranted && bluetoothGranted;
|
||||||
bluetoothScan.isGranted &&
|
|
||||||
bluetoothConnect.isGranted;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<void> openSettings() async {
|
static Future<void> openSettings() async {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue