pull/1889/merge
bradleat 2 weeks ago committed by GitHub
commit a89fdc05c3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -93,7 +93,7 @@ export type PositionOptions = {
}
export async function watchPosition(
options: PositionOptions,
options: PositionOptions & {requestUpdatesInBackground?: boolean},
cb: (location: Position | null, error?: string) => void
): Promise<number> {
const channel = new Channel<Position | string>()
@ -106,6 +106,7 @@ export async function watchPosition(
}
await invoke('plugin:geolocation|watch_position', {
options,
requestUpdatesInBackground: options.requestUpdatesInBackground ?? false,
channel
})
return channel.id
@ -130,9 +131,11 @@ export async function checkPermissions(): Promise<PermissionStatus> {
}
export async function requestPermissions(
permissions: PermissionType[] | null
permissions: PermissionType[] | null,
requestUpdatesInBackground: boolean = false
): Promise<PermissionStatus> {
return await invoke('plugin:geolocation|request_permissions', {
permissions
permissions,
requestUpdatesInBackground
})
}

@ -14,6 +14,7 @@ class GetPositionArgs: Decodable {
class WatchPositionArgs: Decodable {
let options: GetPositionArgs
let request_updates_in_background: Bool
let channel: Channel
}
@ -21,9 +22,20 @@ class ClearWatchArgs: Decodable {
let channelId: UInt32
}
enum PermissionType: String, Decodable {
case location
case coarseLocation
}
class RequestPermissionsArgs: Decodable {
let permissions: [PermissionType]
let requestUpdatesInBackground: Bool
}
class GeolocationPlugin: Plugin, CLLocationManagerDelegate {
private let locationManager = CLLocationManager()
private var isUpdatingLocation: Bool = false
private var backgroundUpdatesRequested: Bool = false
private var permissionRequests: [Invoke] = []
private var positionRequests: [Invoke] = []
private var watcherChannels: [Channel] = []
@ -61,6 +73,8 @@ class GeolocationPlugin: Plugin, CLLocationManagerDelegate {
@objc public func watchPosition(_ invoke: Invoke) throws {
let args = try invoke.parseArgs(WatchPositionArgs.self)
self.backgroundUpdatesRequested = args.request_updates_in_background;
self.watcherChannels.append(args.channel)
DispatchQueue.main.async {
@ -70,12 +84,28 @@ class GeolocationPlugin: Plugin, CLLocationManagerDelegate {
self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
}
// TODO: Use the authorizationStatus instance property with locationManagerDidChangeAuthorization(_:) instead.
if CLLocationManager.authorizationStatus() == .notDetermined {
if self.backgroundUpdatesRequested {
self.locationManager.requestAlwaysAuthorization()
} else {
self.locationManager.requestWhenInUseAuthorization()
}
} else {
if CLLocationManager.authorizationStatus() == .authorizedWhenInUse && self.backgroundUpdatesRequested {
self.locationManager.requestAlwaysAuthorization()
} else {
self.locationManager.startUpdatingLocation()
self.isUpdatingLocation = true
// Enable background updates if enabled
if self.backgroundUpdatesRequested {
self.locationManager.allowsBackgroundLocationUpdates = true
self.locationManager.pausesLocationUpdatesAutomatically = false
self.locationManager.showsBackgroundLocationIndicator = true
}
}
}
}
@ -125,9 +155,19 @@ class GeolocationPlugin: Plugin, CLLocationManagerDelegate {
// TODO: Use the authorizationStatus instance property with locationManagerDidChangeAuthorization(_:) instead.
if CLLocationManager.authorizationStatus() == .notDetermined {
self.permissionRequests.append(invoke)
do {
let args = try invoke.parseArgs(RequestPermissionsArgs.self)
DispatchQueue.main.async {
self.locationManager.requestWhenInUseAuthorization()
if args.requestUpdatesInBackground {
// Request background permission if requested
self.locationManager.requestAlwaysAuthorization()
self.backgroundUpdatesRequested = true
}
}
} catch {
invoke.reject(error.localizedDescription)
}
} else {
checkPermissions(invoke)
@ -224,6 +264,11 @@ class GeolocationPlugin: Plugin, CLLocationManagerDelegate {
private func stopUpdating() {
self.locationManager.stopUpdatingLocation()
self.isUpdatingLocation = false
if self.backgroundUpdatesRequested {
self.locationManager.allowsBackgroundLocationUpdates = false
self.locationManager.pausesLocationUpdatesAutomatically = true
self.locationManager.showsBackgroundLocationIndicator = false
}
}
private func convertLocation(_ location: CLLocation) -> JsonObject {

@ -0,0 +1,3 @@
[default]
description = "Default permissions for the plugin"
permissions = ["allow-request-permissions", "allow-check-permissions", "allow-clear-watch", "allow-watch-position", "allow-get-current-position"]

@ -18,9 +18,10 @@ pub(crate) async fn get_current_position<R: Runtime>(
pub(crate) async fn watch_position<R: Runtime>(
app: AppHandle<R>,
options: PositionOptions,
request_updates_in_background: bool,
channel: Channel,
) -> Result<()> {
app.geolocation().watch_position_inner(options, channel)
app.geolocation().watch_position_inner(options, channel, request_updates_in_background)
}
#[command]
@ -37,6 +38,7 @@ pub(crate) async fn check_permissions<R: Runtime>(app: AppHandle<R>) -> Result<P
pub(crate) async fn request_permissions<R: Runtime>(
app: AppHandle<R>,
permissions: Option<Vec<PermissionType>>,
request_updates_in_background: bool,
) -> Result<PermissionStatus> {
app.geolocation().request_permissions(permissions)
app.geolocation().request_permissions(permissions, request_updates_in_background)
}

@ -32,6 +32,7 @@ impl<R: Runtime> Geolocation<R> {
pub fn watch_position<F: Fn(WatchEvent) + Send + Sync + 'static>(
&self,
options: PositionOptions,
request_updates_in_background: bool,
callback: F,
) -> crate::Result<u32> {
let channel = Channel::new(move |event| {
@ -51,7 +52,7 @@ impl<R: Runtime> Geolocation<R> {
});
let id = channel.id();
self.watch_position_inner(options, channel)?;
self.watch_position_inner(options, request_updates_in_background, channel)?;
Ok(id)
}
@ -59,6 +60,7 @@ impl<R: Runtime> Geolocation<R> {
pub(crate) fn watch_position_inner(
&self,
_options: PositionOptions,
_request_updates_in_background: bool,
_callback_channel: Channel,
) -> crate::Result<()> {
Ok(())
@ -75,6 +77,7 @@ impl<R: Runtime> Geolocation<R> {
pub fn request_permissions(
&self,
_permissions: Option<Vec<PermissionType>>,
_request_updates_in_background: bool,
) -> crate::Result<PermissionStatus> {
Ok(PermissionStatus::default())
}

@ -47,6 +47,7 @@ impl<R: Runtime> Geolocation<R> {
pub fn watch_position<F: Fn(WatchEvent) + Send + Sync + 'static>(
&self,
options: PositionOptions,
request_updates_in_background: bool,
callback: F,
) -> crate::Result<u32> {
let channel = Channel::new(move |event| {
@ -66,7 +67,7 @@ impl<R: Runtime> Geolocation<R> {
});
let id = channel.id();
self.watch_position_inner(options, channel)?;
self.watch_position_inner(options, request_updates_in_background, channel)?;
Ok(id)
}
@ -74,10 +75,18 @@ impl<R: Runtime> Geolocation<R> {
pub(crate) fn watch_position_inner(
&self,
options: PositionOptions,
request_updates_in_background: bool,
channel: Channel,
) -> crate::Result<()> {
self.0
.run_mobile_plugin("watchPosition", WatchPayload { options, channel })
.run_mobile_plugin(
"watchPosition",
WatchPayload {
options,
channel,
request_updates_in_background,
},
)
.map_err(Into::into)
}
@ -96,11 +105,15 @@ impl<R: Runtime> Geolocation<R> {
pub fn request_permissions(
&self,
permissions: Option<Vec<PermissionType>>,
request_updates_in_background: bool,
) -> crate::Result<PermissionStatus> {
self.0
.run_mobile_plugin(
"requestPermissions",
serde_json::json!({ "permissions": permissions }),
serde_json::json!({
"permissions": permissions,
"requestUpdatesInBackground": request_updates_in_background,
}),
)
.map_err(Into::into)
}

Loading…
Cancel
Save