11import Capacitor
22import IONGeolocationLib
3+ import UIKit
34
45import Combine
56
@@ -17,13 +18,38 @@ public class GeolocationPlugin: CAPPlugin, CAPBridgedPlugin {
1718
1819 private var locationService : ( any IONGLOCService ) ?
1920 private var cancellables = Set < AnyCancellable > ( )
21+ private var locationCancellable : AnyCancellable ?
2022 private var callbackManager : GeolocationCallbackManager ?
2123 private var statusInitialized = false
2224 private var locationInitialized : Bool = false
2325
2426 override public func load( ) {
2527 self . locationService = IONGLOCManagerWrapper ( )
2628 self . callbackManager = . init( capacitorBridge: bridge)
29+
30+ NotificationCenter . default. addObserver (
31+ self ,
32+ selector: #selector( appDidBecomeActive) ,
33+ name: UIApplication . didBecomeActiveNotification,
34+ object: nil
35+ )
36+ }
37+
38+ @objc private func appDidBecomeActive( ) {
39+ if let watchCallbacksEmpty = callbackManager? . watchCallbacks. isEmpty, !watchCallbacksEmpty {
40+ print ( " App became active. Restarting location monitoring for watch callbacks. " )
41+ locationCancellable? . cancel ( )
42+ locationCancellable = nil
43+ locationInitialized = false
44+
45+ locationService? . stopMonitoringLocation ( )
46+ locationService? . startMonitoringLocation ( )
47+ bindLocationPublisher ( )
48+ }
49+ }
50+
51+ deinit {
52+ NotificationCenter . default. removeObserver ( self )
2753 }
2854
2955 @objc func getCurrentPosition( _ call: CAPPluginCall ) {
@@ -49,6 +75,9 @@ public class GeolocationPlugin: CAPPlugin, CAPBridgedPlugin {
4975
5076 if ( callbackManager? . watchCallbacks. isEmpty) ?? false {
5177 locationService? . stopMonitoringLocation ( )
78+ locationCancellable? . cancel ( )
79+ locationCancellable = nil
80+ locationInitialized = false
5281 }
5382
5483 callbackManager? . sendSuccess ( call)
@@ -113,18 +142,24 @@ private extension GeolocationPlugin {
113142 func bindLocationPublisher( ) {
114143 guard !locationInitialized else { return }
115144 locationInitialized = true
116- locationService? . currentLocationPublisher
117- . sink ( receiveCompletion : { [ weak self] completion in
118- if case . failure ( let error) = completion {
119- // publisher should be re-observed in the next plugin call
120- self ? . locationInitialized = false
121- print ( " An error was found while retrieving the location: \( error ) " )
145+ locationCancellable = locationService? . currentLocationPublisher
146+ . catch { [ weak self] error -> AnyPublisher < IONGLOCPositionModel , Never > in
147+ print ( " An error was found while retrieving the location: \( error ) " )
148+
149+ if case IONGLOCLocationError . locationUnavailable = error {
150+ print ( " Location unavailable (likely due to backgrounding). Keeping watch callbacks alive. " )
122151 self ? . callbackManager? . sendError ( . positionUnavailable)
152+ return Empty < IONGLOCPositionModel , Never > ( )
153+ . eraseToAnyPublisher ( )
154+ } else {
155+ self ? . callbackManager? . sendError ( . positionUnavailable)
156+ return Empty < IONGLOCPositionModel , Never > ( )
157+ . eraseToAnyPublisher ( )
123158 }
124- } , receiveValue: { [ weak self] position in
159+ }
160+ . sink ( receiveValue: { [ weak self] position in
125161 self ? . callbackManager? . sendSuccess ( with: position)
126162 } )
127- . store ( in: & cancellables)
128163 }
129164
130165 func requestLocationAuthorisation( type requestType: IONGLOCAuthorisationRequestType ) {
0 commit comments