Skip to content

Commit 99f73eb

Browse files
authored
Merge pull request #41 from intonarumori/issue40-signification-location-updates
Added monitoring significant location changes
2 parents 3ed4342 + d55d541 commit 99f73eb

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed

Sources/AsyncLocationKit/AsyncLocationManager.swift

+22
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public typealias LocationEnabledStream = AsyncStream<LocationEnabledEvent>
3030
public typealias LocationStream = AsyncStream<LocationUpdateEvent>
3131
public typealias RegionMonitoringStream = AsyncStream<RegionMonitoringEvent>
3232
public typealias VisitMonitoringStream = AsyncStream<VisitMonitoringEvent>
33+
public typealias SignificantLocationChangeMonitoringStream = AsyncStream<SignificantLocationChangeEvent>
3334
public typealias HeadingMonitorStream = AsyncStream<HeadingMonitorEvent>
3435
public typealias AuthorizationStream = AsyncStream<AuthorizationEvent>
3536
public typealias AccuracyAuthorizationStream = AsyncStream<AccuracyAuthorizationEvent>
@@ -280,6 +281,27 @@ public final class AsyncLocationManager {
280281
locationManager.stopMonitoringVisits()
281282
}
282283

284+
@available(watchOS, unavailable)
285+
@available(tvOS, unavailable)
286+
public func startMonitoringSignificantLocationChanges() async -> SignificantLocationChangeMonitoringStream {
287+
let monitoringPerformer = SignificantLocationChangeMonitoringPerformer()
288+
return SignificantLocationChangeMonitoringStream { streamContinuation in
289+
monitoringPerformer.linkContinuation(streamContinuation)
290+
proxyDelegate.addPerformer(monitoringPerformer)
291+
locationManager.startMonitoringSignificantLocationChanges()
292+
streamContinuation.onTermination = { @Sendable _ in
293+
self.proxyDelegate.cancel(for: monitoringPerformer.uniqueIdentifier)
294+
}
295+
}
296+
}
297+
298+
@available(watchOS, unavailable)
299+
@available(tvOS, unavailable)
300+
public func stopMonitoringSignificantLocationChanges() {
301+
locationManager.stopMonitoringSignificantLocationChanges()
302+
proxyDelegate.cancel(for: SignificantLocationChangeMonitoringPerformer.self)
303+
}
304+
283305
#if os(iOS)
284306
@available(iOS 13, *)
285307
public func startUpdatingHeading() async -> HeadingMonitorStream {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// MIT License
2+
//
3+
// Copyright (c) 2023 AsyncSwift
4+
//
5+
// Permission is hereby granted, free of charge, to any person obtaining a copy
6+
// of this software and associated documentation files (the "Software"), to deal
7+
// in the Software without restriction, including without limitation the rights
8+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
// copies of the Software, and to permit persons to whom the Software is
10+
// furnished to do so, subject to the following conditions:
11+
//
12+
// The above copyright notice and this permission notice shall be included in all
13+
// copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
// SOFTWARE.
22+
23+
import Foundation
24+
import CoreLocation
25+
26+
public enum SignificantLocationChangeEvent {
27+
case didPaused
28+
case didResume
29+
case didUpdateLocations(locations: [CLLocation])
30+
case didFailWith(error: Error)
31+
}
32+
33+
class SignificantLocationChangeMonitoringPerformer: AnyLocationPerformer {
34+
var typeIdentifier: ObjectIdentifier {
35+
return ObjectIdentifier(Self.self)
36+
}
37+
38+
var uniqueIdentifier: UUID = UUID()
39+
40+
var eventsSupport: [CoreLocationEventSupport] = [.didUpdateLocations, .locationUpdatesPaused, .locationUpdatesResume, .didFailWithError]
41+
42+
var cancellable: Cancellable?
43+
var stream: SignificantLocationChangeMonitoringStream.Continuation?
44+
45+
func linkContinuation(_ continuation: SignificantLocationChangeMonitoringStream.Continuation) {
46+
stream = continuation
47+
}
48+
49+
func eventSupported(_ event: CoreLocationDelegateEvent) -> Bool {
50+
return eventsSupport.contains(event.rawEvent())
51+
}
52+
53+
func invokedMethod(event: CoreLocationDelegateEvent) {
54+
switch event {
55+
case .didUpdate(let locations):
56+
stream?.yield(.didUpdateLocations(locations: locations))
57+
case .locationUpdatesPaused:
58+
stream?.yield(.didPaused)
59+
case .locationUpdatesResume:
60+
stream?.yield(.didResume)
61+
case .didFailWithError(let error):
62+
stream?.yield(.didFailWith(error: error))
63+
default:
64+
fatalError("Method can't be execute by this performer: \(String(describing: self)) for event: \(type(of: event))")
65+
}
66+
}
67+
68+
func cancelation() {
69+
guard let stream = stream else { return }
70+
stream.finish()
71+
self.stream = nil
72+
}
73+
}

0 commit comments

Comments
 (0)