Skip to content
This repository has been archived by the owner on May 15, 2024. It is now read-only.

Added support for reduced accuracy detection on iOS 14 #1739

Merged
merged 7 commits into from Aug 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions DeviceTests/DeviceTests.Shared/Geolocation_Tests.cs
Expand Up @@ -69,11 +69,13 @@ public async Task Get_Location_With_Request_Is_Something()
});

var request = new GeolocationRequest(GeolocationAccuracy.Best);
request.RequestFullAccuracy = true;
var location = await Geolocation.GetLocationAsync(request);

Assert.NotNull(location);

Assert.True(location.Accuracy > 0);
Assert.False(location.ReducedAccuracy);
Assert.NotEqual(0.0, location.Latitude);
Assert.NotEqual(0.0, location.Longitude);

Expand Down
24 changes: 22 additions & 2 deletions Xamarin.Essentials/Geolocation/Geolocation.ios.macos.cs
Expand Up @@ -19,7 +19,14 @@ static async Task<Location> PlatformLastKnownLocationAsync()
var manager = new CLLocationManager();
var location = manager.Location;

return location?.ToLocation();
var reducedAccuracy = false;
#if __IOS__
if (Platform.HasOSVersion(14, 0))
{
reducedAccuracy = manager.AccuracyAuthorization == CLAccuracyAuthorization.ReducedAccuracy;
}
#endif
return location?.ToLocation(reducedAccuracy);
}

static async Task<Location> PlatformLocationAsync(GeolocationRequest request, CancellationToken cancellationToken)
Expand Down Expand Up @@ -51,9 +58,22 @@ static async Task<Location> PlatformLocationAsync(GeolocationRequest request, Ca

manager.StartUpdatingLocation();

var reducedAccuracy = false;
#if __IOS__
if (Platform.HasOSVersion(14, 0))
{
if (request.RequestFullAccuracy && manager.AccuracyAuthorization == CLAccuracyAuthorization.ReducedAccuracy)
{
await manager.RequestTemporaryFullAccuracyAuthorizationAsync("XamarinEssentialsFullAccuracyUsageDescription");
}

reducedAccuracy = manager.AccuracyAuthorization == CLAccuracyAuthorization.ReducedAccuracy;
}
#endif

var clLocation = await tcs.Task;

return clLocation?.ToLocation();
return clLocation?.ToLocation(reducedAccuracy);

void HandleLocation(CLLocation location)
{
Expand Down
2 changes: 2 additions & 0 deletions Xamarin.Essentials/Geolocation/GeolocationRequest.shared.cs
Expand Up @@ -57,6 +57,8 @@ public GeolocationRequest(GeolocationAccuracy accuracy, TimeSpan timeout)

public GeolocationAccuracy DesiredAccuracy { get; set; }

public bool RequestFullAccuracy { get; set; }

public override string ToString() =>
$"{nameof(DesiredAccuracy)}: {DesiredAccuracy}, {nameof(Timeout)}: {Timeout}";
}
Expand Down
3 changes: 3 additions & 0 deletions Xamarin.Essentials/Types/Location.shared.cs
Expand Up @@ -58,6 +58,7 @@ public Location(Location point)
Altitude = point.Altitude;
Accuracy = point.Accuracy;
VerticalAccuracy = point.VerticalAccuracy;
ReducedAccuracy = point.ReducedAccuracy;
Speed = point.Speed;
Course = point.Course;
IsFromMockProvider = point.IsFromMockProvider;
Expand All @@ -75,6 +76,8 @@ public Location(Location point)

public double? VerticalAccuracy { get; set; }

public bool ReducedAccuracy { get; set; }

public double? Speed { get; set; }

public double? Course { get; set; }
Expand Down
1 change: 1 addition & 0 deletions Xamarin.Essentials/Types/LocationExtensions.android.cs
Expand Up @@ -34,6 +34,7 @@ public static partial class LocationExtensions
#else
default(float?),
#endif
ReducedAccuracy = false,
Course = location.HasBearing ? location.Bearing : default(double?),
Speed = location.HasSpeed ? location.Speed : default(double?),
#pragma warning disable CS0618 // Type or member is obsolete
Expand Down
Expand Up @@ -18,20 +18,22 @@ public static partial class LocationExtensions
Longitude = placemark.Location.Coordinate.Longitude,
Altitude = placemark.Location.Altitude,
AltitudeReferenceSystem = AltitudeReferenceSystem.Geoid,
Timestamp = DateTimeOffset.UtcNow
Timestamp = DateTimeOffset.UtcNow,
ReducedAccuracy = false,
};

internal static IEnumerable<Location> ToLocations(this IEnumerable<CLPlacemark> placemarks) =>
placemarks?.Select(a => a.ToLocation());

internal static Location ToLocation(this CLLocation location) =>
internal static Location ToLocation(this CLLocation location, bool reducedAccuracy) =>
new Location
{
Latitude = location.Coordinate.Latitude,
Longitude = location.Coordinate.Longitude,
Altitude = location.VerticalAccuracy < 0 ? default(double?) : location.Altitude,
Accuracy = location.HorizontalAccuracy,
VerticalAccuracy = location.VerticalAccuracy,
ReducedAccuracy = reducedAccuracy,
Timestamp = location.Timestamp.ToDateTime(),
#if __IOS__ || __WATCHOS__
Course = location.Course < 0 ? default(double?) : location.Course,
Expand Down
2 changes: 2 additions & 0 deletions Xamarin.Essentials/Types/LocationExtensions.uwp.cs
Expand Up @@ -34,6 +34,7 @@ public static partial class LocationExtensions
Altitude = location.Coordinate.Point.Position.Altitude,
Accuracy = location.Coordinate.Accuracy,
VerticalAccuracy = location.Coordinate.AltitudeAccuracy,
ReducedAccuracy = false,
Speed = (!location.Coordinate.Speed.HasValue || double.IsNaN(location.Coordinate.Speed.Value)) ? default : location.Coordinate.Speed,
Course = (!location.Coordinate.Heading.HasValue || double.IsNaN(location.Coordinate.Heading.Value)) ? default : location.Coordinate.Heading,
IsFromMockProvider = false,
Expand All @@ -49,6 +50,7 @@ public static partial class LocationExtensions
Altitude = coordinate.Point.Position.Altitude,
Accuracy = coordinate.Accuracy,
VerticalAccuracy = coordinate.AltitudeAccuracy,
ReducedAccuracy = false,
Speed = (!coordinate.Speed.HasValue || double.IsNaN(coordinate.Speed.Value)) ? default : coordinate.Speed,
Course = (!coordinate.Heading.HasValue || double.IsNaN(coordinate.Heading.Value)) ? default : coordinate.Heading,
AltitudeReferenceSystem = coordinate.Point.AltitudeReferenceSystem.ToEssentials()
Expand Down