224 lines
8.1 KiB
Swift
224 lines
8.1 KiB
Swift
import Foundation
|
|
import Capacitor
|
|
import CoreLocation
|
|
import UIKit
|
|
|
|
@objc(DumonGeolocationPlugin)
|
|
public class DumonGeolocationPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
public let identifier = "DumonGeolocationPlugin"
|
|
public let jsName = "DumonGeolocation"
|
|
public let pluginMethods: [CAPPluginMethod] = [
|
|
CAPPluginMethod(name: "startPositioning", returnType: CAPPluginReturnPromise),
|
|
CAPPluginMethod(name: "stopPositioning", returnType: CAPPluginReturnPromise),
|
|
CAPPluginMethod(name: "getLatestPosition", returnType: CAPPluginReturnPromise),
|
|
CAPPluginMethod(name: "checkAndRequestPermissions", returnType: CAPPluginReturnPromise),
|
|
CAPPluginMethod(name: "setOptions", returnType: CAPPluginReturnPromise),
|
|
CAPPluginMethod(name: "getGnssStatus", returnType: CAPPluginReturnPromise),
|
|
CAPPluginMethod(name: "getLocationServicesStatus", returnType: CAPPluginReturnPromise),
|
|
CAPPluginMethod(name: "startBackgroundTracking", returnType: CAPPluginReturnPromise),
|
|
CAPPluginMethod(name: "stopBackgroundTracking", returnType: CAPPluginReturnPromise),
|
|
CAPPluginMethod(name: "isBackgroundTrackingActive", returnType: CAPPluginReturnPromise),
|
|
CAPPluginMethod(name: "getBackgroundLatestPosition", returnType: CAPPluginReturnPromise),
|
|
CAPPluginMethod(name: "openBackgroundPermissionSettings", returnType: CAPPluginReturnPromise),
|
|
CAPPluginMethod(name: "openNotificationPermissionSettings", returnType: CAPPluginReturnPromise),
|
|
CAPPluginMethod(name: "setAuthTokens", returnType: CAPPluginReturnPromise),
|
|
CAPPluginMethod(name: "clearAuthTokens", returnType: CAPPluginReturnPromise),
|
|
CAPPluginMethod(name: "getAuthState", returnType: CAPPluginReturnPromise),
|
|
CAPPluginMethod(name: "setBackgroundPostUrl", returnType: CAPPluginReturnPromise),
|
|
CAPPluginMethod(name: "getBackgroundPostUrl", returnType: CAPPluginReturnPromise),
|
|
CAPPluginMethod(name: "configureEdgeToEdge", returnType: CAPPluginReturnPromise),
|
|
CAPPluginMethod(name: "setGpsMode", returnType: CAPPluginReturnPromise)
|
|
]
|
|
|
|
private let implementation = DumonGeolocation()
|
|
private var pendingPermissionCall: CAPPluginCall?
|
|
private var pendingBackgroundCall: CAPPluginCall?
|
|
|
|
public override func load() {
|
|
implementation.onPositionUpdate = { [weak self] data in
|
|
self?.notifyListeners("onPositionUpdate", data: data)
|
|
}
|
|
implementation.onGnssStatus = { [weak self] data in
|
|
self?.notifyListeners("onGnssStatus", data: data)
|
|
}
|
|
implementation.onAuthorizationChange = { [weak self] status in
|
|
self?.handleAuthorizationChange(status)
|
|
}
|
|
}
|
|
|
|
@objc func startPositioning(_ call: CAPPluginCall) {
|
|
let status = implementation.authorizationStatus()
|
|
if !isLocationAuthorized(status) {
|
|
call.reject("Location permission not granted")
|
|
return
|
|
}
|
|
implementation.startPositioning()
|
|
call.resolve()
|
|
}
|
|
|
|
@objc func stopPositioning(_ call: CAPPluginCall) {
|
|
implementation.stopPositioning()
|
|
call.resolve()
|
|
}
|
|
|
|
@objc func getLatestPosition(_ call: CAPPluginCall) {
|
|
call.resolve(implementation.getLatestPosition())
|
|
}
|
|
|
|
@objc func checkAndRequestPermissions(_ call: CAPPluginCall) {
|
|
let status = implementation.authorizationStatus()
|
|
if status == .notDetermined {
|
|
pendingPermissionCall = call
|
|
implementation.requestWhenInUsePermission()
|
|
return
|
|
}
|
|
call.resolve(permissionStatusDict(status))
|
|
}
|
|
|
|
@objc func setOptions(_ call: CAPPluginCall) {
|
|
var options: [String: Any] = [:]
|
|
for (key, value) in call.options {
|
|
if let key = key as? String {
|
|
options[key] = value
|
|
}
|
|
}
|
|
implementation.setOptions(options)
|
|
call.resolve()
|
|
}
|
|
|
|
@objc func getGnssStatus(_ call: CAPPluginCall) {
|
|
if let data = implementation.getGnssStatus() {
|
|
call.resolve(data)
|
|
} else {
|
|
call.resolve([:])
|
|
}
|
|
}
|
|
|
|
@objc func getLocationServicesStatus(_ call: CAPPluginCall) {
|
|
call.resolve(implementation.getLocationServicesStatus())
|
|
}
|
|
|
|
@objc func startBackgroundTracking(_ call: CAPPluginCall) {
|
|
if let postUrl = call.getString("postUrl") {
|
|
implementation.setBackgroundPostUrl(postUrl)
|
|
}
|
|
let status = implementation.authorizationStatus()
|
|
if status == .authorizedAlways {
|
|
implementation.startBackgroundTracking()
|
|
call.resolve()
|
|
return
|
|
}
|
|
pendingBackgroundCall = call
|
|
implementation.requestAlwaysPermission()
|
|
}
|
|
|
|
@objc func stopBackgroundTracking(_ call: CAPPluginCall) {
|
|
implementation.stopBackgroundTracking()
|
|
call.resolve()
|
|
}
|
|
|
|
@objc func isBackgroundTrackingActive(_ call: CAPPluginCall) {
|
|
call.resolve(["active": implementation.isBackgroundTrackingActive()])
|
|
}
|
|
|
|
@objc func getBackgroundLatestPosition(_ call: CAPPluginCall) {
|
|
if let data = implementation.getBackgroundLatestPosition() {
|
|
call.resolve(data)
|
|
} else {
|
|
call.resolve([:])
|
|
}
|
|
}
|
|
|
|
@objc func openBackgroundPermissionSettings(_ call: CAPPluginCall) {
|
|
openAppSettings(call)
|
|
}
|
|
|
|
@objc func openNotificationPermissionSettings(_ call: CAPPluginCall) {
|
|
openAppSettings(call)
|
|
}
|
|
|
|
@objc func setAuthTokens(_ call: CAPPluginCall) {
|
|
guard let access = call.getString("accessToken"), !access.isEmpty else {
|
|
call.reject("accessToken is required")
|
|
return
|
|
}
|
|
guard let refresh = call.getString("refreshToken"), !refresh.isEmpty else {
|
|
call.reject("refreshToken is required")
|
|
return
|
|
}
|
|
implementation.setAuthTokens(accessToken: access, refreshToken: refresh)
|
|
call.resolve()
|
|
}
|
|
|
|
@objc func clearAuthTokens(_ call: CAPPluginCall) {
|
|
implementation.clearAuthTokens()
|
|
call.resolve()
|
|
}
|
|
|
|
@objc func getAuthState(_ call: CAPPluginCall) {
|
|
call.resolve(["present": implementation.getAuthState()])
|
|
}
|
|
|
|
@objc func setBackgroundPostUrl(_ call: CAPPluginCall) {
|
|
let url = call.getString("url")
|
|
implementation.setBackgroundPostUrl(url)
|
|
call.resolve()
|
|
}
|
|
|
|
@objc func getBackgroundPostUrl(_ call: CAPPluginCall) {
|
|
let url = implementation.getBackgroundPostUrl()
|
|
call.resolve(["url": url ?? NSNull()])
|
|
}
|
|
|
|
@objc func configureEdgeToEdge(_ call: CAPPluginCall) {
|
|
// No-op on iOS; UI handled by app.
|
|
call.resolve()
|
|
}
|
|
|
|
@objc func setGpsMode(_ call: CAPPluginCall) {
|
|
let mode = call.getString("mode") ?? "normal"
|
|
implementation.setGpsMode(mode)
|
|
call.resolve()
|
|
}
|
|
|
|
private func handleAuthorizationChange(_ status: CLAuthorizationStatus) {
|
|
if let call = pendingPermissionCall {
|
|
pendingPermissionCall = nil
|
|
call.resolve(permissionStatusDict(status))
|
|
}
|
|
|
|
if let call = pendingBackgroundCall {
|
|
pendingBackgroundCall = nil
|
|
if status == .authorizedAlways {
|
|
implementation.startBackgroundTracking()
|
|
call.resolve()
|
|
} else {
|
|
call.reject("Background location permission not granted")
|
|
}
|
|
}
|
|
}
|
|
|
|
private func permissionStatusDict(_ status: CLAuthorizationStatus) -> [String: String] {
|
|
let granted = isLocationAuthorized(status)
|
|
return [
|
|
"location": granted ? "granted" : "denied",
|
|
"wifi": "granted"
|
|
]
|
|
}
|
|
|
|
private func isLocationAuthorized(_ status: CLAuthorizationStatus) -> Bool {
|
|
return status == .authorizedAlways || status == .authorizedWhenInUse
|
|
}
|
|
|
|
private func openAppSettings(_ call: CAPPluginCall) {
|
|
guard let url = URL(string: UIApplication.openSettingsURLString) else {
|
|
call.reject("Unable to open settings")
|
|
return
|
|
}
|
|
DispatchQueue.main.async {
|
|
UIApplication.shared.open(url, options: [:], completionHandler: nil)
|
|
call.resolve()
|
|
}
|
|
}
|
|
}
|