Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Capacitor
import IONGeolocationLib
import UIKit

import Combine

Expand All @@ -17,13 +18,38 @@ public class GeolocationPlugin: CAPPlugin, CAPBridgedPlugin {

private var locationService: (any IONGLOCService)?
private var cancellables = Set<AnyCancellable>()
private var locationCancellable: AnyCancellable?
private var callbackManager: GeolocationCallbackManager?
private var statusInitialized = false
private var locationInitialized: Bool = false

override public func load() {
self.locationService = IONGLOCManagerWrapper()
self.callbackManager = .init(capacitorBridge: bridge)

NotificationCenter.default.addObserver(
self,
selector: #selector(appDidBecomeActive),
name: UIApplication.didBecomeActiveNotification,
object: nil
)
}

@objc private func appDidBecomeActive() {
if let watchCallbacksEmpty = callbackManager?.watchCallbacks.isEmpty, !watchCallbacksEmpty {
print("App became active. Restarting location monitoring for watch callbacks.")
locationCancellable?.cancel()
locationCancellable = nil
locationInitialized = false

locationService?.stopMonitoringLocation()
locationService?.startMonitoringLocation()
bindLocationPublisher()
}
}

deinit {
NotificationCenter.default.removeObserver(self)
}

@objc func getCurrentPosition(_ call: CAPPluginCall) {
Expand All @@ -49,6 +75,9 @@ public class GeolocationPlugin: CAPPlugin, CAPBridgedPlugin {

if (callbackManager?.watchCallbacks.isEmpty) ?? false {
locationService?.stopMonitoringLocation()
locationCancellable?.cancel()
locationCancellable = nil
locationInitialized = false
}

callbackManager?.sendSuccess(call)
Expand Down Expand Up @@ -113,18 +142,24 @@ private extension GeolocationPlugin {
func bindLocationPublisher() {
guard !locationInitialized else { return }
locationInitialized = true
locationService?.currentLocationPublisher
.sink(receiveCompletion: { [weak self] completion in
if case .failure(let error) = completion {
// publisher should be re-observed in the next plugin call
self?.locationInitialized = false
print("An error was found while retrieving the location: \(error)")
locationCancellable = locationService?.currentLocationPublisher
.catch { [weak self] error -> AnyPublisher<IONGLOCPositionModel, Never> in
print("An error was found while retrieving the location: \(error)")

if case IONGLOCLocationError.locationUnavailable = error {
print("Location unavailable (likely due to backgrounding). Keeping watch callbacks alive.")
self?.callbackManager?.sendError(.positionUnavailable)
return Empty<IONGLOCPositionModel, Never>()
.eraseToAnyPublisher()
} else {
self?.callbackManager?.sendError(.positionUnavailable)
return Empty<IONGLOCPositionModel, Never>()
.eraseToAnyPublisher()
}
}, receiveValue: { [weak self] position in
}
.sink(receiveValue: { [weak self] position in
self?.callbackManager?.sendSuccess(with: position)
})
.store(in: &cancellables)
}

func requestLocationAuthorisation(type requestType: IONGLOCAuthorisationRequestType) {
Expand Down