Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

@capacitor-community/background-geolocation

Package Overview
Dependencies
Maintainers
47
Versions
48
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@capacitor-community/background-geolocation - npm Package Compare versions

Comparing version
1.2.25
to
1.2.26
+242
ios/Plugin/Swift/Plugin.swift
import Capacitor
import Foundation
import UIKit
import CoreLocation
// Avoids a bewildering type warning.
let null = Optional<Double>.none as Any
func formatLocation(_ location: CLLocation) -> PluginCallResultData {
var simulated = false;
if #available(iOS 15, *) {
// Prior to iOS 15, it was not possible to detect simulated locations.
// But in general, it is very difficult to simulate locations on iOS in
// production.
if location.sourceInformation != nil {
simulated = location.sourceInformation!.isSimulatedBySoftware;
}
}
return [
"latitude": location.coordinate.latitude,
"longitude": location.coordinate.longitude,
"accuracy": location.horizontalAccuracy,
"altitude": location.altitude,
"altitudeAccuracy": location.verticalAccuracy,
"simulated": simulated,
"speed": location.speed < 0 ? null : location.speed,
"bearing": location.course < 0 ? null : location.course,
"time": NSNumber(
value: Int(
location.timestamp.timeIntervalSince1970 * 1000
)
),
]
}
class Watcher {
let callbackId: String
let locationManager: CLLocationManager = CLLocationManager()
private let created = Date()
private let allowStale: Bool
private var isUpdatingLocation: Bool = false
init(_ id: String, stale: Bool) {
callbackId = id
allowStale = stale
}
func start() {
// Avoid unnecessary calls to startUpdatingLocation, which can
// result in extraneous invocations of didFailWithError.
if !isUpdatingLocation {
locationManager.startUpdatingLocation()
isUpdatingLocation = true
}
}
func stop() {
if isUpdatingLocation {
locationManager.stopUpdatingLocation()
isUpdatingLocation = false
}
}
func isLocationValid(_ location: CLLocation) -> Bool {
return (
allowStale ||
location.timestamp >= created
)
}
}
@objc(BackgroundGeolocation)
public class BackgroundGeolocation: CAPPlugin,
CAPBridgedPlugin,
CLLocationManagerDelegate {
private var watchers = [Watcher]()
public let identifier = "BackgroundGeolocation"
public let jsName = "BackgroundGeolocation"
public let pluginMethods: [CAPPluginMethod] = [
CAPPluginMethod(name: "addWatcher", returnType: CAPPluginReturnCallback),
CAPPluginMethod(name: "removeWatcher", returnType: CAPPluginReturnPromise),
CAPPluginMethod(name: "openSettings", returnType: CAPPluginReturnPromise)
]
@objc public override func load() {
UIDevice.current.isBatteryMonitoringEnabled = true
}
@objc func addWatcher(_ call: CAPPluginCall) {
call.keepAlive = true
// CLLocationManager requires main thread
DispatchQueue.main.async {
let background = call.getString("backgroundMessage") != nil
let watcher = Watcher(
call.callbackId,
stale: call.getBool("stale") ?? false
)
let manager = watcher.locationManager
manager.delegate = self
let externalPower = [
.full,
.charging
].contains(UIDevice.current.batteryState)
manager.desiredAccuracy = (
externalPower
? kCLLocationAccuracyBestForNavigation
: kCLLocationAccuracyBest
)
var distanceFilter = call.getDouble("distanceFilter")
// It appears that setting manager.distanceFilter to 0 can prevent
// subsequent location updates. See issue #88.
if distanceFilter == nil || distanceFilter == 0 {
distanceFilter = kCLDistanceFilterNone
}
manager.distanceFilter = distanceFilter!
manager.allowsBackgroundLocationUpdates = background
manager.showsBackgroundLocationIndicator = background
manager.pausesLocationUpdatesAutomatically = false
self.watchers.append(watcher)
if call.getBool("requestPermissions") != false {
let status = CLLocationManager.authorizationStatus()
if [
.notDetermined,
.denied,
.restricted,
].contains(status) {
return (
background
? manager.requestAlwaysAuthorization()
: manager.requestWhenInUseAuthorization()
)
}
if (
background && status == .authorizedWhenInUse
) {
// Attempt to escalate.
manager.requestAlwaysAuthorization()
}
}
return watcher.start()
}
}
@objc func removeWatcher(_ call: CAPPluginCall) {
// CLLocationManager requires main thread
DispatchQueue.main.async {
if let callbackId = call.getString("id") {
if let index = self.watchers.firstIndex(
where: { $0.callbackId == callbackId }
) {
self.watchers[index].locationManager.stopUpdatingLocation()
self.watchers.remove(at: index)
}
if let savedCall = self.bridge?.savedCall(withID: callbackId) {
self.bridge?.releaseCall(savedCall)
}
return call.resolve()
}
return call.reject("No callback ID")
}
}
@objc func openSettings(_ call: CAPPluginCall) {
DispatchQueue.main.async {
guard let settingsUrl = URL(
string: UIApplication.openSettingsURLString
) else {
return call.reject("No link to settings available")
}
if UIApplication.shared.canOpenURL(settingsUrl) {
UIApplication.shared.open(settingsUrl, completionHandler: {
(success) in
if (success) {
return call.resolve()
} else {
return call.reject("Failed to open settings")
}
})
} else {
return call.reject("Cannot open settings")
}
}
}
public func locationManager(
_ manager: CLLocationManager,
didFailWithError error: Error
) {
if let watcher = self.watchers.first(
where: { $0.locationManager == manager }
) {
if let call = self.bridge?.savedCall(withID: watcher.callbackId) {
if let clErr = error as? CLError {
if clErr.code == .locationUnknown {
// This error is sometimes sent by the manager if
// it cannot get a fix immediately.
return
} else if (clErr.code == .denied) {
watcher.stop()
return call.reject(
"Permission denied.",
"NOT_AUTHORIZED"
)
}
}
return call.reject(error.localizedDescription, nil, error)
}
}
}
public func locationManager(
_ manager: CLLocationManager,
didUpdateLocations locations: [CLLocation]
) {
if let location = locations.last {
if let watcher = self.watchers.first(
where: { $0.locationManager == manager }
) {
if watcher.isLocationValid(location) {
if let call = self.bridge?.savedCall(withID: watcher.callbackId) {
return call.resolve(formatLocation(location))
}
}
}
}
}
public func locationManager(
_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus
) {
// If this method is called before the user decides on a permission, as
// it is on iOS 14 when the permissions dialog is presented, we ignore
// it.
if status != .notDetermined {
if let watcher = self.watchers.first(
where: { $0.locationManager == manager }
) {
return watcher.start()
}
}
}
}
// swift-tools-version: 5.9
import PackageDescription
let package = Package(
name: "CapacitorCommunityBackgroundGeolocation",
platforms: [.iOS(.v12)],
products: [
.library(
name: "CapacitorCommunityBackgroundGeolocation",
targets: ["BackgroundGeolocationPlugin"]
)
],
dependencies: [
.package(
url: "https://github.com/ionic-team/capacitor-swift-pm.git",
from: "7.0.0"
)
],
targets: [
.target(
name: "BackgroundGeolocationPlugin",
dependencies: [
.product(name: "Capacitor", package: "capacitor-swift-pm"),
.product(name: "Cordova", package: "capacitor-swift-pm")
],
path: "ios/Plugin/Swift"
)
]
)
+13
-11
{
"name": "@capacitor-community/background-geolocation",
"version": "1.2.25",
"version": "1.2.26",
"description": "Receive geolocation updates even while the app is in the background.",

@@ -13,18 +13,20 @@ "repository": {

"files": [
"CapacitorCommunityBackgroundGeolocation.podspec",
"Package.swift",
"android/build.gradle",
"android/gradle.properties",
"android/gradle/wrapper/gradle-wrapper.properties",
"android/proguard-rules.pro",
"android/settings.gradle",
"android/proguard-rules.pro",
"android/gradle/wrapper/gradle-wrapper.properties",
"android/gradle.properties",
"ios/Plugin/Plugin.*",
"android/src/main/",
"ios/Podfile*",
"definitions.d.ts",
"ios/Plugin/Info.plist",
"CapacitorCommunityBackgroundGeolocation.podspec",
"definitions.d.ts"
"ios/Plugin/Plugin.*",
"ios/Plugin/Swift/Plugin.swift",
"ios/Podfile*"
],
"devDependencies": {
"@capacitor/android": "6.0.0-rc.0",
"@capacitor/core": "6.0.0-rc.0",
"@capacitor/ios": "6.0.0-rc.0"
"@capacitor/android": "^7.0.0",
"@capacitor/core": "^7.0.0",
"@capacitor/ios": "^7.0.0"
},

@@ -31,0 +33,0 @@ "peerDependencies": {

@@ -217,3 +217,6 @@ # Background Geolocation

### v1.2.17
### v1.2.26
- Add support for Swift Package Manager (SPM).
### v1.2.25
- Add support for Capacitor v7.

@@ -220,0 +223,0 @@

import Capacitor
import Foundation
import UIKit
import CoreLocation
// Avoids a bewildering type warning.
let null = Optional<Double>.none as Any
func formatLocation(_ location: CLLocation) -> PluginCallResultData {
var simulated = false;
if #available(iOS 15, *) {
// Prior to iOS 15, it was not possible to detect simulated locations.
// But in general, it is very difficult to simulate locations on iOS in
// production.
if location.sourceInformation != nil {
simulated = location.sourceInformation!.isSimulatedBySoftware;
}
}
return [
"latitude": location.coordinate.latitude,
"longitude": location.coordinate.longitude,
"accuracy": location.horizontalAccuracy,
"altitude": location.altitude,
"altitudeAccuracy": location.verticalAccuracy,
"simulated": simulated,
"speed": location.speed < 0 ? null : location.speed,
"bearing": location.course < 0 ? null : location.course,
"time": NSNumber(
value: Int(
location.timestamp.timeIntervalSince1970 * 1000
)
),
]
}
class Watcher {
let callbackId: String
let locationManager: CLLocationManager = CLLocationManager()
private let created = Date()
private let allowStale: Bool
private var isUpdatingLocation: Bool = false
init(_ id: String, stale: Bool) {
callbackId = id
allowStale = stale
}
func start() {
// Avoid unnecessary calls to startUpdatingLocation, which can
// result in extraneous invocations of didFailWithError.
if !isUpdatingLocation {
locationManager.startUpdatingLocation()
isUpdatingLocation = true
}
}
func stop() {
if isUpdatingLocation {
locationManager.stopUpdatingLocation()
isUpdatingLocation = false
}
}
func isLocationValid(_ location: CLLocation) -> Bool {
return (
allowStale ||
location.timestamp >= created
)
}
}
@objc(BackgroundGeolocation)
public class BackgroundGeolocation : CAPPlugin, CLLocationManagerDelegate {
private var watchers = [Watcher]()
@objc public override func load() {
UIDevice.current.isBatteryMonitoringEnabled = true
}
@objc func addWatcher(_ call: CAPPluginCall) {
call.keepAlive = true
// CLLocationManager requires main thread
DispatchQueue.main.async {
let background = call.getString("backgroundMessage") != nil
let watcher = Watcher(
call.callbackId,
stale: call.getBool("stale") ?? false
)
let manager = watcher.locationManager
manager.delegate = self
let externalPower = [
.full,
.charging
].contains(UIDevice.current.batteryState)
manager.desiredAccuracy = (
externalPower
? kCLLocationAccuracyBestForNavigation
: kCLLocationAccuracyBest
)
var distanceFilter = call.getDouble("distanceFilter")
// It appears that setting manager.distanceFilter to 0 can prevent
// subsequent location updates. See issue #88.
if distanceFilter == nil || distanceFilter == 0 {
distanceFilter = kCLDistanceFilterNone
}
manager.distanceFilter = distanceFilter!
manager.allowsBackgroundLocationUpdates = background
manager.showsBackgroundLocationIndicator = background
manager.pausesLocationUpdatesAutomatically = false
self.watchers.append(watcher)
if call.getBool("requestPermissions") != false {
let status = CLLocationManager.authorizationStatus()
if [
.notDetermined,
.denied,
.restricted,
].contains(status) {
return (
background
? manager.requestAlwaysAuthorization()
: manager.requestWhenInUseAuthorization()
)
}
if (
background && status == .authorizedWhenInUse
) {
// Attempt to escalate.
manager.requestAlwaysAuthorization()
}
}
return watcher.start()
}
}
@objc func removeWatcher(_ call: CAPPluginCall) {
// CLLocationManager requires main thread
DispatchQueue.main.async {
if let callbackId = call.getString("id") {
if let index = self.watchers.firstIndex(
where: { $0.callbackId == callbackId }
) {
self.watchers[index].locationManager.stopUpdatingLocation()
self.watchers.remove(at: index)
}
if let savedCall = self.bridge?.savedCall(withID: callbackId) {
self.bridge?.releaseCall(savedCall)
}
return call.resolve()
}
return call.reject("No callback ID")
}
}
@objc func openSettings(_ call: CAPPluginCall) {
DispatchQueue.main.async {
guard let settingsUrl = URL(
string: UIApplication.openSettingsURLString
) else {
return call.reject("No link to settings available")
}
if UIApplication.shared.canOpenURL(settingsUrl) {
UIApplication.shared.open(settingsUrl, completionHandler: {
(success) in
if (success) {
return call.resolve()
} else {
return call.reject("Failed to open settings")
}
})
} else {
return call.reject("Cannot open settings")
}
}
}
public func locationManager(
_ manager: CLLocationManager,
didFailWithError error: Error
) {
if let watcher = self.watchers.first(
where: { $0.locationManager == manager }
) {
if let call = self.bridge?.savedCall(withID: watcher.callbackId) {
if let clErr = error as? CLError {
if clErr.code == .locationUnknown {
// This error is sometimes sent by the manager if
// it cannot get a fix immediately.
return
} else if (clErr.code == .denied) {
watcher.stop()
return call.reject(
"Permission denied.",
"NOT_AUTHORIZED"
)
}
}
return call.reject(error.localizedDescription, nil, error)
}
}
}
public func locationManager(
_ manager: CLLocationManager,
didUpdateLocations locations: [CLLocation]
) {
if let location = locations.last {
if let watcher = self.watchers.first(
where: { $0.locationManager == manager }
) {
if watcher.isLocationValid(location) {
if let call = self.bridge?.savedCall(withID: watcher.callbackId) {
return call.resolve(formatLocation(location))
}
}
}
}
}
public func locationManager(
_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus
) {
// If this method is called before the user decides on a permission, as
// it is on iOS 14 when the permissions dialog is presented, we ignore
// it.
if status != .notDetermined {
if let watcher = self.watchers.first(
where: { $0.locationManager == manager }
) {
return watcher.start()
}
}
}
}

Sorry, the diff of this file is not supported yet