iOS LocationService complete.
This commit is contained in:
parent
1fa48de667
commit
b9835a3e72
@ -48,12 +48,10 @@ namespace eShopOnContainers
|
||||
{
|
||||
await InitNavigation();
|
||||
}
|
||||
|
||||
if (_settingsService.AllowGpsLocation && !_settingsService.UseFakeLocation)
|
||||
{
|
||||
await GetGpsLocation();
|
||||
}
|
||||
|
||||
if (!_settingsService.UseMocks && !string.IsNullOrEmpty(_settingsService.AuthAccessToken))
|
||||
{
|
||||
await SendCurrentLocation();
|
||||
@ -74,9 +72,10 @@ namespace eShopOnContainers
|
||||
|
||||
if (locator.IsGeolocationEnabled && locator.IsGeolocationAvailable)
|
||||
{
|
||||
//locationService.AllowsBackgroundUpdates = true;
|
||||
locator.DesiredAccuracy = 50;
|
||||
|
||||
// Delay getting the position to ensure that the UI has finished updating
|
||||
await Task.Delay(2000);
|
||||
var position = await locator.GetPositionAsync();
|
||||
|
||||
_settingsService.Latitude = position.Latitude.ToString();
|
||||
|
@ -13,16 +13,16 @@ namespace eShopOnContainers.Core.Services.Basket
|
||||
BuyerId = "9245fe4a-d402-451c-b9ed-9c1a04247482",
|
||||
Items = new List<BasketItem>
|
||||
{
|
||||
new BasketItem { Id = "1", PictureUrl = Device.RuntimePlatform != Device.UWP ? "fake_product_01.png" : "Assets/fake_product_01.png", ProductId = Common.Common.MockCatalogItemId01, ProductName = ".NET Bot Blue Sweatshirt (M)", Quantity = 1, UnitPrice = 19.50M },
|
||||
new BasketItem { Id = "2", PictureUrl = Device.RuntimePlatform != Device.UWP ? "fake_product_04.png" : "Assets/fake_product_04.png", ProductId = Common.Common.MockCatalogItemId04, ProductName = ".NET Black Cupt", Quantity = 1, UnitPrice = 17.00M }
|
||||
new BasketItem { Id = "1", PictureUrl = Device.RuntimePlatform != Device.UWP ? "fake_product_01.png" : "Assets/fake_product_01.png", ProductId = Common.Common.MockCatalogItemId01, ProductName = ".NET Bot Blue Sweatshirt (M)", Quantity = 1, UnitPrice = 19.50M },
|
||||
new BasketItem { Id = "2", PictureUrl = Device.RuntimePlatform != Device.UWP ? "fake_product_04.png" : "Assets/fake_product_04.png", ProductId = Common.Common.MockCatalogItemId04, ProductName = ".NET Black Cupt", Quantity = 1, UnitPrice = 17.00M }
|
||||
}
|
||||
};
|
||||
|
||||
public async Task<CustomerBasket> GetBasketAsync(string guidUser, string token)
|
||||
{
|
||||
await Task.Delay(500);
|
||||
await Task.Delay(10);
|
||||
|
||||
if(string.IsNullOrEmpty(guidUser) || string.IsNullOrEmpty(token))
|
||||
if (string.IsNullOrEmpty(guidUser) || string.IsNullOrEmpty(token))
|
||||
{
|
||||
return new CustomerBasket();
|
||||
}
|
||||
@ -32,7 +32,7 @@ namespace eShopOnContainers.Core.Services.Basket
|
||||
|
||||
public async Task<CustomerBasket> UpdateBasketAsync(CustomerBasket customerBasket, string token)
|
||||
{
|
||||
await Task.Delay(500);
|
||||
await Task.Delay(10);
|
||||
|
||||
if (string.IsNullOrEmpty(token))
|
||||
{
|
||||
@ -46,7 +46,7 @@ namespace eShopOnContainers.Core.Services.Basket
|
||||
|
||||
public async Task ClearBasketAsync(string guidUser, string token)
|
||||
{
|
||||
await Task.Delay(500);
|
||||
await Task.Delay(10);
|
||||
|
||||
if (string.IsNullOrEmpty(token))
|
||||
{
|
||||
|
@ -24,40 +24,40 @@ namespace eShopOnContainers.Core.Services.Catalog
|
||||
|
||||
private ObservableCollection<CatalogItem> MockCatalog = new ObservableCollection<CatalogItem>
|
||||
{
|
||||
new CatalogItem { Id = Common.Common.MockCatalogItemId01, PictureUri = Device.RuntimePlatform != Device.UWP ? "fake_product_01.png" : "Assets/fake_product_01.png", Name = ".NET Bot Blue Sweatshirt (M)", Price = 19.50M, CatalogBrandId = 2, CatalogBrand = "Visual Studio", CatalogTypeId = 2, CatalogType = "T-Shirt" },
|
||||
new CatalogItem { Id = Common.Common.MockCatalogItemId02, PictureUri = Device.RuntimePlatform != Device.UWP ? "fake_product_02.png" : "Assets/fake_product_02.png", Name = ".NET Bot Purple Sweatshirt (M)", Price = 19.50M, CatalogBrandId = 2, CatalogBrand = "Visual Studio", CatalogTypeId = 2, CatalogType = "T-Shirt" },
|
||||
new CatalogItem { Id = Common.Common.MockCatalogItemId03, PictureUri = Device.RuntimePlatform != Device.UWP ? "fake_product_03.png" : "Assets/fake_product_03.png", Name = ".NET Bot Black Sweatshirt (M)", Price = 19.95M, CatalogBrandId = 2, CatalogBrand = "Visual Studio", CatalogTypeId = 2, CatalogType = "T-Shirt" },
|
||||
new CatalogItem { Id = Common.Common.MockCatalogItemId04, PictureUri = Device.RuntimePlatform != Device.UWP ? "fake_product_04.png" : "Assets/fake_product_04.png", Name = ".NET Black Cupt", Price = 17.00M, CatalogBrandId = 2, CatalogBrand = "Visual Studio", CatalogTypeId = 1, CatalogType = "Mug" },
|
||||
new CatalogItem { Id = Common.Common.MockCatalogItemId05, PictureUri = Device.RuntimePlatform != Device.UWP ? "fake_product_05.png" : "Assets/fake_product_05.png", Name = "Azure Black Sweatshirt (M)", Price = 19.50M, CatalogBrandId = 1, CatalogBrand = "Azure", CatalogTypeId = 2, CatalogType = "T-Shirt" }
|
||||
new CatalogItem { Id = Common.Common.MockCatalogItemId01, PictureUri = Device.RuntimePlatform != Device.UWP ? "fake_product_01.png" : "Assets/fake_product_01.png", Name = ".NET Bot Blue Sweatshirt (M)", Price = 19.50M, CatalogBrandId = 2, CatalogBrand = "Visual Studio", CatalogTypeId = 2, CatalogType = "T-Shirt" },
|
||||
new CatalogItem { Id = Common.Common.MockCatalogItemId02, PictureUri = Device.RuntimePlatform != Device.UWP ? "fake_product_02.png" : "Assets/fake_product_02.png", Name = ".NET Bot Purple Sweatshirt (M)", Price = 19.50M, CatalogBrandId = 2, CatalogBrand = "Visual Studio", CatalogTypeId = 2, CatalogType = "T-Shirt" },
|
||||
new CatalogItem { Id = Common.Common.MockCatalogItemId03, PictureUri = Device.RuntimePlatform != Device.UWP ? "fake_product_03.png" : "Assets/fake_product_03.png", Name = ".NET Bot Black Sweatshirt (M)", Price = 19.95M, CatalogBrandId = 2, CatalogBrand = "Visual Studio", CatalogTypeId = 2, CatalogType = "T-Shirt" },
|
||||
new CatalogItem { Id = Common.Common.MockCatalogItemId04, PictureUri = Device.RuntimePlatform != Device.UWP ? "fake_product_04.png" : "Assets/fake_product_04.png", Name = ".NET Black Cupt", Price = 17.00M, CatalogBrandId = 2, CatalogBrand = "Visual Studio", CatalogTypeId = 1, CatalogType = "Mug" },
|
||||
new CatalogItem { Id = Common.Common.MockCatalogItemId05, PictureUri = Device.RuntimePlatform != Device.UWP ? "fake_product_05.png" : "Assets/fake_product_05.png", Name = "Azure Black Sweatshirt (M)", Price = 19.50M, CatalogBrandId = 1, CatalogBrand = "Azure", CatalogTypeId = 2, CatalogType = "T-Shirt" }
|
||||
};
|
||||
|
||||
public async Task<ObservableCollection<CatalogItem>> GetCatalogAsync()
|
||||
{
|
||||
await Task.Delay(500);
|
||||
await Task.Delay(10);
|
||||
|
||||
return MockCatalog;
|
||||
}
|
||||
|
||||
public async Task<ObservableCollection<CatalogItem>> FilterAsync(int catalogBrandId, int catalogTypeId)
|
||||
{
|
||||
await Task.Delay(500);
|
||||
await Task.Delay(10);
|
||||
|
||||
return MockCatalog
|
||||
.Where(c => c.CatalogBrandId == catalogBrandId &&
|
||||
c.CatalogTypeId == catalogTypeId)
|
||||
c.CatalogTypeId == catalogTypeId)
|
||||
.ToObservableCollection();
|
||||
}
|
||||
|
||||
public async Task<ObservableCollection<CatalogBrand>> GetCatalogBrandAsync()
|
||||
{
|
||||
await Task.Delay(500);
|
||||
await Task.Delay(10);
|
||||
|
||||
return MockCatalogBrand;
|
||||
}
|
||||
|
||||
public async Task<ObservableCollection<CatalogType>> GetCatalogTypeAsync()
|
||||
{
|
||||
await Task.Delay(500);
|
||||
await Task.Delay(10);
|
||||
|
||||
return MockCatalogType;
|
||||
}
|
||||
|
@ -38,13 +38,13 @@ namespace eShopOnContainers.Core.Services.Marketing
|
||||
|
||||
public async Task<ObservableCollection<CampaignItem>> GetAllCampaignsAsync(string token)
|
||||
{
|
||||
await Task.Delay(500);
|
||||
await Task.Delay(10);
|
||||
return _mockCampaign;
|
||||
}
|
||||
|
||||
public async Task<CampaignItem> GetCampaignByIdAsync(int campaignId, string token)
|
||||
{
|
||||
await Task.Delay(500);
|
||||
await Task.Delay(10);
|
||||
return _mockCampaign.SingleOrDefault(c => c.Id == campaignId);
|
||||
}
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ namespace eShopOnContainers.Core.Services.Order
|
||||
|
||||
public async Task<ObservableCollection<Models.Orders.Order>> GetOrdersAsync(string token)
|
||||
{
|
||||
await Task.Delay(500);
|
||||
await Task.Delay(10);
|
||||
|
||||
if (!string.IsNullOrEmpty(token))
|
||||
{
|
||||
@ -88,7 +88,7 @@ namespace eShopOnContainers.Core.Services.Order
|
||||
|
||||
public async Task<Models.Orders.Order> GetOrderAsync(int orderId, string token)
|
||||
{
|
||||
await Task.Delay(500);
|
||||
await Task.Delay(10);
|
||||
|
||||
if (!string.IsNullOrEmpty(token))
|
||||
return MockOrders
|
||||
@ -99,7 +99,7 @@ namespace eShopOnContainers.Core.Services.Order
|
||||
|
||||
public async Task CreateOrderAsync(Models.Orders.Order newOrder, string token)
|
||||
{
|
||||
await Task.Delay(500);
|
||||
await Task.Delay(10);
|
||||
|
||||
if (!string.IsNullOrEmpty(token))
|
||||
{
|
||||
|
@ -28,7 +28,7 @@ namespace eShopOnContainers.Core.Services.User
|
||||
|
||||
public async Task<UserInfo> GetUserInfoAsync(string authToken)
|
||||
{
|
||||
await Task.Delay(500);
|
||||
await Task.Delay(10);
|
||||
return MockUserInfo;
|
||||
}
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ namespace eShopOnContainers.Core.ViewModels
|
||||
{
|
||||
try
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
await Task.Delay(10);
|
||||
|
||||
isAuthenticated = true;
|
||||
}
|
||||
@ -189,7 +189,7 @@ namespace eShopOnContainers.Core.ViewModels
|
||||
{
|
||||
IsBusy = true;
|
||||
|
||||
await Task.Delay(500);
|
||||
await Task.Delay(10);
|
||||
|
||||
LoginUrl = _identityService.CreateAuthorizationRequest();
|
||||
|
||||
|
@ -10,24 +10,19 @@ namespace eShopOnContainers.iOS.Services
|
||||
{
|
||||
internal class GeolocationSingleUpdateDelegate : CLLocationManagerDelegate
|
||||
{
|
||||
bool _haveHeading;
|
||||
bool _haveLocation;
|
||||
readonly Position _position = new Position();
|
||||
CLHeading _bestHeading;
|
||||
|
||||
readonly double _desiredAccuracy;
|
||||
readonly bool _includeHeading;
|
||||
readonly TaskCompletionSource<Position> _tcs;
|
||||
readonly CLLocationManager _manager;
|
||||
|
||||
public Task<Position> Task => _tcs?.Task;
|
||||
|
||||
public GeolocationSingleUpdateDelegate(CLLocationManager manager, double desiredAccuracy, bool includeHeading, int timeout, CancellationToken cancelToken)
|
||||
public GeolocationSingleUpdateDelegate(CLLocationManager manager, double desiredAccuracy, int timeout, CancellationToken cancelToken)
|
||||
{
|
||||
_manager = manager;
|
||||
_tcs = new TaskCompletionSource<Position>(manager);
|
||||
_desiredAccuracy = desiredAccuracy;
|
||||
_includeHeading = includeHeading;
|
||||
|
||||
if (timeout != Timeout.Infinite)
|
||||
{
|
||||
@ -76,8 +71,6 @@ namespace eShopOnContainers.iOS.Services
|
||||
}
|
||||
}
|
||||
|
||||
public override bool ShouldDisplayHeadingCalibration(CLLocationManager manager) => true;
|
||||
|
||||
public override void UpdatedLocation(CLLocationManager manager, CLLocation newLocation, CLLocation oldLocation)
|
||||
{
|
||||
if (newLocation.HorizontalAccuracy < 0)
|
||||
@ -97,31 +90,13 @@ namespace eShopOnContainers.iOS.Services
|
||||
{
|
||||
_position.Timestamp = new DateTimeOffset((DateTime)newLocation.Timestamp);
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception)
|
||||
{
|
||||
_position.Timestamp = DateTimeOffset.UtcNow;
|
||||
}
|
||||
_haveLocation = true;
|
||||
|
||||
if ((!_includeHeading || _haveHeading) && _position.Accuracy <= _desiredAccuracy)
|
||||
{
|
||||
_tcs.TrySetResult(new Position(_position));
|
||||
StopListening();
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdatedHeading(CLLocationManager manager, CLHeading newHeading)
|
||||
{
|
||||
if (newHeading.HeadingAccuracy < 0)
|
||||
return;
|
||||
if (_bestHeading != null && newHeading.HeadingAccuracy >= _bestHeading.HeadingAccuracy)
|
||||
return;
|
||||
|
||||
_bestHeading = newHeading;
|
||||
_position.Heading = newHeading.TrueHeading;
|
||||
_haveHeading = true;
|
||||
|
||||
if (_haveLocation && _position.Accuracy <= _desiredAccuracy)
|
||||
if (_position.Accuracy <= _desiredAccuracy)
|
||||
{
|
||||
_tcs.TrySetResult(new Position(_position));
|
||||
StopListening();
|
||||
@ -130,9 +105,6 @@ namespace eShopOnContainers.iOS.Services
|
||||
|
||||
private void StopListening()
|
||||
{
|
||||
if (CLLocationManager.HeadingAvailable)
|
||||
_manager.StopUpdatingHeading();
|
||||
|
||||
_manager.StopUpdatingLocation();
|
||||
}
|
||||
}
|
||||
|
@ -15,12 +15,6 @@ namespace eShopOnContainers.iOS.Services
|
||||
{
|
||||
public class LocationServiceImplementation : ILocationServiceImplementation
|
||||
{
|
||||
bool _deferringUpdates;
|
||||
readonly CLLocationManager _manager;
|
||||
Position _lastPosition;
|
||||
|
||||
public event EventHandler<PositionErrorEventArgs> PositionError;
|
||||
public event EventHandler<PositionEventArgs> PositionChanged;
|
||||
public double DesiredAccuracy { get; set; }
|
||||
public bool IsGeolocationAvailable => true;
|
||||
public bool IsGeolocationEnabled
|
||||
@ -32,21 +26,11 @@ namespace eShopOnContainers.iOS.Services
|
||||
}
|
||||
}
|
||||
|
||||
public bool SupportsHeading => CLLocationManager.HeadingAvailable;
|
||||
|
||||
public LocationServiceImplementation()
|
||||
{
|
||||
DesiredAccuracy = 100;
|
||||
//_manager = GetManager();
|
||||
//_manager.AuthorizationChanged += OnAuthorizationChanged;
|
||||
//_manager.Failed += OnFailed;
|
||||
//_manager.UpdatedLocation += OnUpdatedLocation;
|
||||
//_manager.UpdatedHeading += OnUpdatedHeading;
|
||||
//_manager.DeferredUpdatesFinished += OnDeferredUpdatesFinished;
|
||||
}
|
||||
|
||||
void OnDeferredUpdatesFinished(object sender, NSErrorEventArgs e) => _deferringUpdates = false;
|
||||
|
||||
#region Internal Implementation
|
||||
|
||||
async Task<bool> CheckPermissions(Permission permission)
|
||||
@ -78,7 +62,7 @@ namespace eShopOnContainers.iOS.Services
|
||||
|
||||
#region ILocationServiceImplementation
|
||||
|
||||
public async Task<Position> GetPositionAsync(TimeSpan? timeout, CancellationToken? cancelToken = null, bool includeHeading = false)
|
||||
public async Task<Position> GetPositionAsync(TimeSpan? timeout, CancellationToken? cancelToken = null)
|
||||
{
|
||||
var permission = Permission.LocationWhenInUse;
|
||||
var hasPermission = await CheckPermissions(permission);
|
||||
@ -96,53 +80,16 @@ namespace eShopOnContainers.iOS.Services
|
||||
var manager = GetManager();
|
||||
manager.DesiredAccuracy = DesiredAccuracy;
|
||||
|
||||
// Permit background updates if background location mode is enabled
|
||||
if (UIDevice.CurrentDevice.CheckSystemVersion(9, 0))
|
||||
{
|
||||
var backgroundModes = NSBundle.MainBundle.InfoDictionary[(NSString)"UIBackgroundModes"] as NSArray;
|
||||
manager.AllowsBackgroundLocationUpdates = backgroundModes != null && (backgroundModes.Contains((NSString)"Location") || backgroundModes.Contains((NSString)"location"));
|
||||
}
|
||||
|
||||
// Always prevent location update pausing since we're only listening for a single update
|
||||
if (UIDevice.CurrentDevice.CheckSystemVersion(6, 0))
|
||||
manager.PausesLocationUpdatesAutomatically = false;
|
||||
|
||||
tcs = new TaskCompletionSource<Position>(manager);
|
||||
var singleListener = new GeolocationSingleUpdateDelegate(manager, DesiredAccuracy, includeHeading, timeoutMilliseconds, cancelToken.Value);
|
||||
var singleListener = new GeolocationSingleUpdateDelegate(manager, DesiredAccuracy, timeoutMilliseconds, cancelToken.Value);
|
||||
manager.Delegate = singleListener;
|
||||
manager.StartUpdatingLocation();
|
||||
|
||||
if (includeHeading && SupportsHeading)
|
||||
manager.StartUpdatingHeading();
|
||||
|
||||
return await singleListener.Task;
|
||||
|
||||
//tcs = new TaskCompletionSource<Position>();
|
||||
//if (_lastPosition == null)
|
||||
//{
|
||||
// if (cancelToken != CancellationToken.None)
|
||||
// cancelToken.Value.Register(() => tcs.TrySetCanceled());
|
||||
|
||||
// EventHandler<PositionErrorEventArgs> gotError = null;
|
||||
// gotError = (s, e) =>
|
||||
// {
|
||||
// tcs.TrySetException(new GeolocationException(e.Error));
|
||||
// PositionError -= gotError;
|
||||
// };
|
||||
// PositionError += gotError;
|
||||
|
||||
// EventHandler<PositionEventArgs> gotPosition = null;
|
||||
// gotPosition = (s, e) =>
|
||||
// {
|
||||
// tcs.TrySetResult(e.Position);
|
||||
// PositionChanged += gotPosition;
|
||||
// };
|
||||
// PositionChanged += gotPosition;
|
||||
//}
|
||||
//else
|
||||
// tcs.SetResult(_lastPosition);
|
||||
|
||||
//return await tcs.Task;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -19,7 +19,6 @@ namespace eShopOnContainers.iOS.Services
|
||||
return PermissionStatus.Disabled;
|
||||
|
||||
var status = CLLocationManager.Status;
|
||||
|
||||
if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
|
||||
{
|
||||
switch (status)
|
||||
@ -77,22 +76,6 @@ namespace eShopOnContainers.iOS.Services
|
||||
locationManager.AuthorizationChanged += authCallback;
|
||||
|
||||
var info = NSBundle.MainBundle.InfoDictionary;
|
||||
//if (permission == Permission.Location)
|
||||
//{
|
||||
// if (info.ContainsKey(new NSString("NSLocationAlwaysUsageDescription")))
|
||||
// locationManager.RequestAlwaysAuthorization();
|
||||
// else if (info.ContainsKey(new NSString("NSLocationWhenInUseUsageDescription")))
|
||||
// locationManager.RequestWhenInUseAuthorization();
|
||||
// else
|
||||
// throw new UnauthorizedAccessException("On iOS 8.0 and higher you must set either NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription in your Info.plist file to enable Authorization Requests for Location updates!");
|
||||
//}
|
||||
//else if (permission == Permission.LocationAlways)
|
||||
//{
|
||||
// if (info.ContainsKey(new NSString("NSLocationAlwaysUsageDescription")))
|
||||
// locationManager.RequestAlwaysAuthorization();
|
||||
// else
|
||||
// throw new UnauthorizedAccessException("On iOS 8.0 and higher you must set either NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription in your Info.plist file to enable Authorization Requests for Location updates!");
|
||||
//}
|
||||
if (permission == Permission.LocationWhenInUse)
|
||||
{
|
||||
if (info.ContainsKey(new NSString("NSLocationWhenInUseUsageDescription")))
|
||||
|
Loading…
x
Reference in New Issue
Block a user