Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Implements #182 #183

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ geolocation.getCurrentLocation({ desiredAccuracy: Accuracy.high, maximumAge: 500
| timeout | 5 minutes | How long to wait for a location in ms. |
| iosAllowsBackgroundLocationUpdates | false | If enabled, UIBackgroundModes key in info.plist is required (check the hint below). Allow the application to receive location updates in background (ignored on Android). Read more in [Apple document](https://developer.apple.com/documentation/corelocation/cllocationmanager/1620568-allowsbackgroundlocationupdates?language=objc) |
| iosPausesLocationUpdatesAutomatically | true | Allow deactivation of the automatic pause of location updates (ignored on Android). Read more in [Apple document](https://developer.apple.com/documentation/corelocation/cllocationmanager/1620553-pauseslocationupdatesautomatical?language=objc)|
| iosOpenSettingsIfLocationIsDisabled | false | If true when the `isEnabled` method is invoked, the settings app will open on iOS so the user can change the location services permission. |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iosOpenSettingsIfLocationIsDisabled -> iosOpenSettingsIfLocationHasBeenDenied



> If iosAllowsBackgroundLocationUpdates is set to true, the following code is required in the info.plist file:
>```
Expand Down
2 changes: 1 addition & 1 deletion src/geolocation.android.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { on as applicationOn, android as androidAppInstance, AndroidApplication, uncaughtErrorEvent, UnhandledErrorEventData } from "application";
import { Accuracy } from "tns-core-modules/ui/enums";
import { setTimeout, clearTimeout } from "timer";
import { setTimeout, clearTimeout } from "tns-core-modules/timer";
import { LocationBase, defaultGetLocationTimeout, fastestTimeUpdate, minTimeUpdate } from "./geolocation.common";
import { Options, successCallbackType, errorCallbackType } from "./location-monitor";
import * as permissions from "nativescript-permissions";
Expand Down
2 changes: 1 addition & 1 deletion src/geolocation.common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ export class LocationBase implements LocationDef {
export const defaultGetLocationTimeout = 5 * 60 * 1000; // 5 minutes
export const minRangeUpdate = 0.1; // 0 meters
export const minTimeUpdate = 1 * 60 * 1000; // 1 minute
export const fastestTimeUpdate = 5 * 1000; // 5 secs
export const fastestTimeUpdate = 5 * 1000; // 5 secs
25 changes: 21 additions & 4 deletions src/geolocation.ios.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Accuracy } from "tns-core-modules/ui/enums";
import { setTimeout, clearTimeout } from "timer";
import { on as applicationOn, uncaughtErrorEvent, UnhandledErrorEventData } from "application";
import { setTimeout, clearTimeout } from "tns-core-modules/timer";
import { on as applicationOn, uncaughtErrorEvent, UnhandledErrorEventData } from "tns-core-modules/application";
import * as utils from "tns-core-modules/utils/utils";

import {
LocationBase,
Expand Down Expand Up @@ -275,12 +276,28 @@ function _isEnabled(options?: Options): boolean {
return false;
}

export function isEnabled(): Promise<boolean> {
export function isEnabled(options: Options): Promise<boolean> {
return new Promise(function (resolve, reject) {
resolve(_isEnabled());
const isEnabledResult = _isEnabled();
const status = CLLocationManager.authorizationStatus();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could reuse the getIOSLocationManagerStatus(), i.e.:

const status = CLLocationManager.authorizationStatus();

// checking if the status for location has been denied previously
// checking if the function has been provided the options and the `iosOpenSettingsIfLocationHasBeenDenied` value as true
if (isEnabledResult === false &&
status === CLAuthorizationStatus.kCLAuthorizationStatusDenied &&
options &&
options.iosOpenSettingsIfLocationHasBeenDenied === true
) {
// now open the Settings so the user can toggle the Location permission
utils.ios.getter(UIApplication, UIApplication.sharedApplication).openURL(NSURL.URLWithString(UIApplicationOpenSettingsURLString));
}
resolve(isEnabledResult);
});
}

export function getIOSLocationManagerStatus(): CLAuthorizationStatus {
return CLLocationManager.authorizationStatus();
}

export function distance(loc1: Location, loc2: Location): number {
if (!loc1.ios) {
loc1.ios = clLocationFromLocation(loc1);
Expand Down
116 changes: 67 additions & 49 deletions src/location-monitor.d.ts
Original file line number Diff line number Diff line change
@@ -1,54 +1,60 @@
import { Location } from "./location";

/**
* Provides options for location monitoring.
*/
* Provides options for location monitoring.
*/
export interface Options {
/**
* Specifies desired accuracy in meters. Defaults to DesiredAccuracy.HIGH
*/
desiredAccuracy?: number;

/**
* Update distance filter in meters. Specifies how often to update. Default is no filter
*/
updateDistance?: number;

/**
* Interval between location updates, in milliseconds (ignored on iOS)
*/
updateTime?: number;

/**
* Minimum time interval between location updates, in milliseconds (ignored on iOS)
*/
minimumUpdateTime?: number;

/**
* How old locations to receive in ms.
*/
maximumAge?: number;

/**
* How long to wait for a location in ms.
*/
timeout?: number;

/**
* A Boolean value which has to be set to true on iOS versions > 9.0 to allow the application to receive location updates in
* background in combination with the UIBackgroundModes key 'location' in the Info.plist. An exception is thrown if the
* property is enabled without the UIBackgroundModes key set to true. The value is ignored on Android.
* @see {@link https://developer.apple.com/reference/corelocation/cllocationmanager/1620568-allowsbackgroundlocationupdates|allowsBackgroundLocationUpdates}
*/
iosAllowsBackgroundLocationUpdates?: boolean;

/**
* A Boolean value which has to be set to false on iOS to deactivate the automatic pause of location updates. The location manager might pause
* location updates for a period of time to improve battery life. This behavior may stop a long-running background task. Set this flag to false
* to prevent this behavior. The value is ignored on Android.
* @see {@link https://developer.apple.com/reference/corelocation/cllocationmanager/1620553-pauseslocationupdatesautomatical|pausesLocationUpdatesAutomatically}
*/
iosPausesLocationUpdatesAutomatically?: boolean;
/**
* Specifies desired accuracy in meters. Defaults to DesiredAccuracy.HIGH
*/
desiredAccuracy?: number;

/**
* Update distance filter in meters. Specifies how often to update. Default is no filter
*/
updateDistance?: number;

/**
* Interval between location updates, in milliseconds (ignored on iOS)
*/
updateTime?: number;

/**
* Minimum time interval between location updates, in milliseconds (ignored on iOS)
*/
minimumUpdateTime?: number;

/**
* How old locations to receive in ms.
*/
maximumAge?: number;

/**
* How long to wait for a location in ms.
*/
timeout?: number;

/**
* A Boolean value which has to be set to true on iOS versions > 9.0 to allow the application to receive location updates in
* background in combination with the UIBackgroundModes key 'location' in the Info.plist. An exception is thrown if the
* property is enabled without the UIBackgroundModes key set to true. The value is ignored on Android.
* @see {@link https://developer.apple.com/reference/corelocation/cllocationmanager/1620568-allowsbackgroundlocationupdates|allowsBackgroundLocationUpdates}
*/
iosAllowsBackgroundLocationUpdates?: boolean;

/**
* A Boolean value which has to be set to false on iOS to deactivate the automatic pause of location updates. The location manager might pause
* location updates for a period of time to improve battery life. This behavior may stop a long-running background task. Set this flag to false
* to prevent this behavior. The value is ignored on Android.
* @see {@link https://developer.apple.com/reference/corelocation/cllocationmanager/1620553-pauseslocationupdatesautomatical|pausesLocationUpdatesAutomatically}
*/
iosPausesLocationUpdatesAutomatically?: boolean;

/**
* A boolean value which if set to true, the application will open the Settings
* app only after the user has previously denied the location permission.
*/
iosOpenSettingsIfLocationHasBeenDenied?: boolean;
}

declare type successCallbackType = (location: Location) => void;
Expand All @@ -64,7 +70,11 @@ export function getCurrentLocation(options: Options): Promise<Location>;
* Monitor for location change.
* @returns {number} The watch id
*/
export function watchLocation(successCallback: successCallbackType, errorCallback: errorCallbackType, options: Options): number;
export function watchLocation(
successCallback: successCallbackType,
errorCallback: errorCallbackType,
options: Options
): number;

/**
* Stop monitoring for location change. Parameter expected is the watchId returned from `watchLocation`.
Expand All @@ -80,7 +90,8 @@ export function enableLocationRequest(always?: boolean): Promise<void>;

/**
* Check if location services are enabled
* @param options android only. Check the availability based on the specified options.
* @param options Check the availability based on the specified options.
* ** iOS Only ** utilizes the iosOpenSettingsIfLocationHasBeenDenied value **
* @returns {boolean} True if location services are enabled
*/
export function isEnabled(options?: Options): Promise<boolean>;
Expand All @@ -92,3 +103,10 @@ export function isEnabled(options?: Options): Promise<boolean>;
* @returns {number} The calculated distance in meters.
*/
export function distance(loc1: Location, loc2: Location): number;

/**
* ** iOS Only **
* Returns the value for the CLLocationManager on iOS.
* @returns {CLAuthorizationStatus} The status of the Location Authorization permission.
*/
export function getIOSLocationManagerStatus(): CLAuthorizationStatus;