Xamarin.iOS中Geolocator.Plugin定位失效问题求助
Hey there, let's break down what's going wrong with your Xamarin.iOS geolocation setup and fix it step by step!
Key Issues Causing the Crash
Let's start with the two most critical problems in your code and configuration:
UI Thread Deadlock
In yourMyViewExampleconstructor, you're usingTask.Run(() => api.GetDeviceCurrentLocation()).Resultto block the UI thread while waiting for the asynchronous location call. iOS has strict rules about UI thread responsiveness, and this blocking pattern almost always leads to a deadlock (and subsequent crash) because the async operation tries to return to the already-blocked UI thread.Invalid Info.plist Permission Keys
Your Info.plist contains an incorrect key:RequestWhenInUseAuthorization— this isn't a valid iOS system permission key. Additionally, you're missing the requiredNSLocationWhenInUseUsageDescription(needed for foreground location access), andNSLocationAlwaysUsageDescriptionis deprecated on iOS 11+.
Fixes to Apply
1. Fix the Async/Await Pattern (Eliminate Deadlock)
Move your location logic out of the page constructor and into the Appearing event, using proper async/await instead of blocking with .Result:
public partial class MyViewExample : ContentPage { public MyViewExample() { InitializeComponent(); // Subscribe to the Appearing event to run async logic after the page loads Appearing += OnPageAppearing; } private async void OnPageAppearing(object sender, EventArgs e) { // Unsubscribe to avoid repeated calls if the page appears multiple times Appearing -= OnPageAppearing; Service cs = new Service(); var myLocation = await cs.GetDeviceCurrentLocation(); // Use await to avoid blocking var myLatitude = myLocation.Latitude; var myLongitude = myLocation.Longitude; Debug.WriteLine($"Latitude is : {myLatitude} and Longitude is : {myLongitude}"); } }
2. Correct Info.plist Permissions
Update your Info.plist to use valid iOS location permission keys. Remove the invalid RequestWhenInUseAuthorization key, and add/keep the appropriate keys based on your needs:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <!-- ... your existing keys ... --> <key>UILaunchStoryboardName</key> <string>LaunchScreen</string> <!-- Required if you need background location access (iOS 11+) --> <key>NSLocationAlwaysAndWhenInUseUsageDescription</key> <string>This app needs access to your location when open and in the background</string> <!-- Required for foreground location access (works on all supported iOS versions) --> <key>NSLocationWhenInUseUsageDescription</key> <string>This app needs access to your location while in use</string> <key>CFBundleIdentifier</key> <string>my.app.development</string> </dict> </plist>
3. Additional Checks
- Update the Geolocator Plugin: Ensure you're using the latest version of
Plugin.Geolocator— older versions may have iOS-specific bugs. - Adjust Timeout: Your 3-second timeout in
GetPositionAsyncmight be too short, especially if the user is granting location permission for the first time. Try increasing it to 10 seconds:var position = await locator.GetPositionAsync(TimeSpan.FromSeconds(10)); - Verify Device Settings: Make sure location services are enabled on your test iOS device, and that your app has been granted location permissions (check Settings > [Your App] > Location).
These changes should resolve the crash by fixing the deadlock issue and ensuring iOS recognizes your location permission requests.
内容的提问来源于stack exchange,提问作者John

