From c8763206f0742f41c8d41dc79bd95de5c5447fe5 Mon Sep 17 00:00:00 2001 From: marian Date: Tue, 19 Feb 2019 11:23:57 +0200 Subject: [PATCH 1/7] fix(ios): enforce accuracy, use requestLocation for ios 9+ Regardless of desired accuracy when starting location update ios sends a first location as quick as possible even if not with requested accuracy. For ios version 9+ requestLocation API is used, for lower versions the first location received is ignored unless desired accuracy is Accuracy.any. --- src/geolocation.ios.ts | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/src/geolocation.ios.ts b/src/geolocation.ios.ts index 97d900d..19be2ee 100644 --- a/src/geolocation.ios.ts +++ b/src/geolocation.ios.ts @@ -140,6 +140,10 @@ function errorHandler(errData: UnhandledErrorEventData) { } } +function getVersionMaj () { + return parseInt(Platform.device.osVersion.split(".")[0]); +} + // options - desiredAccuracy, updateDistance, minimumUpdateTime, maximumAge, timeout export function getCurrentLocation(options: Options): Promise { return new Promise(function (resolve, reject) { @@ -164,6 +168,7 @@ export function getCurrentLocation(options: Options): Promise { } else { let timerId; let locListener; + let initLocation; let stopTimerAndMonitor = function (locListenerId) { if (timerId !== undefined) { @@ -174,18 +179,31 @@ export function getCurrentLocation(options: Options): Promise { }; let successCallback = function (location: Location) { - if (typeof options.maximumAge === "number" && location.timestamp.valueOf() + options.maximumAge < new Date().valueOf()) { - // returned location is too old, but we still have some time before the timeout so maybe wait a bit? - return; + if (getVersionMaj() < 9) { + if (typeof options.maximumAge === "number" && location.timestamp.valueOf() + options.maximumAge < new Date().valueOf()) { + // returned location is too old, but we still have some time before the timeout so maybe wait a bit? + return; + } + + if (options.desiredAccuracy !== Accuracy.any && !initLocation) { + // regardless of desired accuracy ios returns first location as quick as possible even if not as accurate as requested + initLocation = location; + return; + + } } stopTimerAndMonitor(locListener.id); resolve(location); }; - - locListener = LocationListenerImpl.initWithLocationError(successCallback); + + locListener = LocationListenerImpl.initWithLocationError(successCallback, reject); try { - LocationMonitor.startLocationMonitoring(options, locListener); + if (getVersionMaj() >= 9) { + LocationMonitor.requestLocation(options, locListener); + } else { + LocationMonitor.startLocationMonitoring(options, locListener); + } } catch (e) { stopTimerAndMonitor(locListener.id); reject(e); @@ -196,7 +214,7 @@ export function getCurrentLocation(options: Options): Promise { LocationMonitor.stopLocationMonitoring(locListener.id); reject(new Error("Timeout while searching for location!")); }, options.timeout || defaultGetLocationTimeout); - } + } } }, reject); }); @@ -321,6 +339,11 @@ export class LocationMonitor { return null; } + static requestLocation(options: Options, locListener: any): void { + let iosLocManager = getIOSLocationManager(locListener, options); + iosLocManager.requestLocation(); + } + static startLocationMonitoring(options: Options, locListener: any): void { let iosLocManager = getIOSLocationManager(locListener, options); iosLocManager.startUpdatingLocation(); @@ -342,7 +365,7 @@ export class LocationMonitor { iosLocManager.distanceFilter = options ? options.updateDistance : minRangeUpdate; locationManagers[locListener.id] = iosLocManager; locationListeners[locListener.id] = locListener; - if (parseInt(Platform.device.osVersion.split(".")[0]) >= 9) { + if (getVersionMaj() >= 9) { iosLocManager.allowsBackgroundLocationUpdates = options && options.iosAllowsBackgroundLocationUpdates != null ? options.iosAllowsBackgroundLocationUpdates : false; From 8c744a4e3cbb9d39d53a99d68d36a6ba497f9264 Mon Sep 17 00:00:00 2001 From: marian Date: Tue, 19 Feb 2019 11:30:52 +0200 Subject: [PATCH 2/7] remove trailing spaces --- src/geolocation.ios.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/geolocation.ios.ts b/src/geolocation.ios.ts index 19be2ee..3812d00 100644 --- a/src/geolocation.ios.ts +++ b/src/geolocation.ios.ts @@ -185,18 +185,17 @@ export function getCurrentLocation(options: Options): Promise { return; } - if (options.desiredAccuracy !== Accuracy.any && !initLocation) { + if (options.desiredAccuracy !== Accuracy.any && !initLocation) { // regardless of desired accuracy ios returns first location as quick as possible even if not as accurate as requested initLocation = location; return; - } } stopTimerAndMonitor(locListener.id); resolve(location); }; - + locListener = LocationListenerImpl.initWithLocationError(successCallback, reject); try { if (getVersionMaj() >= 9) { @@ -214,7 +213,7 @@ export function getCurrentLocation(options: Options): Promise { LocationMonitor.stopLocationMonitoring(locListener.id); reject(new Error("Timeout while searching for location!")); }, options.timeout || defaultGetLocationTimeout); - } + } } }, reject); }); From a83bae87c1412549e1ae9ae0f2e26c291d6bd87e Mon Sep 17 00:00:00 2001 From: Dimitar Todorov Date: Tue, 26 Feb 2019 17:59:51 +0200 Subject: [PATCH 3/7] Update app run --- demo/app/app-root.xml | 2 ++ demo/app/app.ts | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 demo/app/app-root.xml diff --git a/demo/app/app-root.xml b/demo/app/app-root.xml new file mode 100644 index 0000000..8d01995 --- /dev/null +++ b/demo/app/app-root.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/demo/app/app.ts b/demo/app/app.ts index a17b0bd..108a350 100644 --- a/demo/app/app.ts +++ b/demo/app/app.ts @@ -1,2 +1,2 @@ import * as application from 'tns-core-modules/application'; -application.start({ moduleName: "main-page" }); +application.run({ moduleName: "app-root" }); From 6cc3dad12479c16ea1a18d01eeb96a7e413b55a4 Mon Sep 17 00:00:00 2001 From: marian Date: Wed, 27 Feb 2019 11:36:20 +0200 Subject: [PATCH 4/7] add getLocation method to the 'mock' location manager used in tests --- demo/app/tests/mock-ios.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/demo/app/tests/mock-ios.js b/demo/app/tests/mock-ios.js index c1f9df3..11dd776 100644 --- a/demo/app/tests/mock-ios.js +++ b/demo/app/tests/mock-ios.js @@ -19,6 +19,14 @@ var MockLocationManager = (function () { return _this._requestSingleUpdate(_this.delegate, _this); }, 500); }; + MockLocationManager.prototype.requestLocation = function () { + var _this = this; + this.removeUpdates(null); + MockLocationManager.intervalId = setTimeout(function () { + // this.delegate is the location listener + return _this._requestSingleUpdate(_this.delegate, _this); + }, 500); + }; MockLocationManager.prototype._requestSingleUpdate = function (locListener, instance) { var newLocation = { coordinate: { From 2a12c37c9397aea9ae2dcf3272a610207a52c822 Mon Sep 17 00:00:00 2001 From: marian Date: Tue, 19 Feb 2019 11:23:57 +0200 Subject: [PATCH 5/7] fix(ios): enforce accuracy, use requestLocation for ios 9+ Regardless of desired accuracy when starting location update ios sends a first location as quick as possible even if not with requested accuracy. For ios version 9+ requestLocation API is used, for lower versions the first location received is ignored unless desired accuracy is Accuracy.any. --- src/geolocation.ios.ts | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/src/geolocation.ios.ts b/src/geolocation.ios.ts index 97d900d..19be2ee 100644 --- a/src/geolocation.ios.ts +++ b/src/geolocation.ios.ts @@ -140,6 +140,10 @@ function errorHandler(errData: UnhandledErrorEventData) { } } +function getVersionMaj () { + return parseInt(Platform.device.osVersion.split(".")[0]); +} + // options - desiredAccuracy, updateDistance, minimumUpdateTime, maximumAge, timeout export function getCurrentLocation(options: Options): Promise { return new Promise(function (resolve, reject) { @@ -164,6 +168,7 @@ export function getCurrentLocation(options: Options): Promise { } else { let timerId; let locListener; + let initLocation; let stopTimerAndMonitor = function (locListenerId) { if (timerId !== undefined) { @@ -174,18 +179,31 @@ export function getCurrentLocation(options: Options): Promise { }; let successCallback = function (location: Location) { - if (typeof options.maximumAge === "number" && location.timestamp.valueOf() + options.maximumAge < new Date().valueOf()) { - // returned location is too old, but we still have some time before the timeout so maybe wait a bit? - return; + if (getVersionMaj() < 9) { + if (typeof options.maximumAge === "number" && location.timestamp.valueOf() + options.maximumAge < new Date().valueOf()) { + // returned location is too old, but we still have some time before the timeout so maybe wait a bit? + return; + } + + if (options.desiredAccuracy !== Accuracy.any && !initLocation) { + // regardless of desired accuracy ios returns first location as quick as possible even if not as accurate as requested + initLocation = location; + return; + + } } stopTimerAndMonitor(locListener.id); resolve(location); }; - - locListener = LocationListenerImpl.initWithLocationError(successCallback); + + locListener = LocationListenerImpl.initWithLocationError(successCallback, reject); try { - LocationMonitor.startLocationMonitoring(options, locListener); + if (getVersionMaj() >= 9) { + LocationMonitor.requestLocation(options, locListener); + } else { + LocationMonitor.startLocationMonitoring(options, locListener); + } } catch (e) { stopTimerAndMonitor(locListener.id); reject(e); @@ -196,7 +214,7 @@ export function getCurrentLocation(options: Options): Promise { LocationMonitor.stopLocationMonitoring(locListener.id); reject(new Error("Timeout while searching for location!")); }, options.timeout || defaultGetLocationTimeout); - } + } } }, reject); }); @@ -321,6 +339,11 @@ export class LocationMonitor { return null; } + static requestLocation(options: Options, locListener: any): void { + let iosLocManager = getIOSLocationManager(locListener, options); + iosLocManager.requestLocation(); + } + static startLocationMonitoring(options: Options, locListener: any): void { let iosLocManager = getIOSLocationManager(locListener, options); iosLocManager.startUpdatingLocation(); @@ -342,7 +365,7 @@ export class LocationMonitor { iosLocManager.distanceFilter = options ? options.updateDistance : minRangeUpdate; locationManagers[locListener.id] = iosLocManager; locationListeners[locListener.id] = locListener; - if (parseInt(Platform.device.osVersion.split(".")[0]) >= 9) { + if (getVersionMaj() >= 9) { iosLocManager.allowsBackgroundLocationUpdates = options && options.iosAllowsBackgroundLocationUpdates != null ? options.iosAllowsBackgroundLocationUpdates : false; From db7a9815aca081c08edbe2c844f621a6040d37a5 Mon Sep 17 00:00:00 2001 From: marian Date: Tue, 19 Feb 2019 11:30:52 +0200 Subject: [PATCH 6/7] remove trailing spaces --- src/geolocation.ios.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/geolocation.ios.ts b/src/geolocation.ios.ts index 19be2ee..3812d00 100644 --- a/src/geolocation.ios.ts +++ b/src/geolocation.ios.ts @@ -185,18 +185,17 @@ export function getCurrentLocation(options: Options): Promise { return; } - if (options.desiredAccuracy !== Accuracy.any && !initLocation) { + if (options.desiredAccuracy !== Accuracy.any && !initLocation) { // regardless of desired accuracy ios returns first location as quick as possible even if not as accurate as requested initLocation = location; return; - } } stopTimerAndMonitor(locListener.id); resolve(location); }; - + locListener = LocationListenerImpl.initWithLocationError(successCallback, reject); try { if (getVersionMaj() >= 9) { @@ -214,7 +213,7 @@ export function getCurrentLocation(options: Options): Promise { LocationMonitor.stopLocationMonitoring(locListener.id); reject(new Error("Timeout while searching for location!")); }, options.timeout || defaultGetLocationTimeout); - } + } } }, reject); }); From abdc33cecf10755a8ea00473cabb0ace43c6fe33 Mon Sep 17 00:00:00 2001 From: marian Date: Wed, 27 Feb 2019 11:36:20 +0200 Subject: [PATCH 7/7] add getLocation method to the 'mock' location manager used in tests --- demo/app/tests/mock-ios.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/demo/app/tests/mock-ios.js b/demo/app/tests/mock-ios.js index c1f9df3..11dd776 100644 --- a/demo/app/tests/mock-ios.js +++ b/demo/app/tests/mock-ios.js @@ -19,6 +19,14 @@ var MockLocationManager = (function () { return _this._requestSingleUpdate(_this.delegate, _this); }, 500); }; + MockLocationManager.prototype.requestLocation = function () { + var _this = this; + this.removeUpdates(null); + MockLocationManager.intervalId = setTimeout(function () { + // this.delegate is the location listener + return _this._requestSingleUpdate(_this.delegate, _this); + }, 500); + }; MockLocationManager.prototype._requestSingleUpdate = function (locListener, instance) { var newLocation = { coordinate: {