Skip to content

Commit 9b437a7

Browse files
committed
update
1 parent dffddfe commit 9b437a7

File tree

3 files changed

+104
-98
lines changed

3 files changed

+104
-98
lines changed

Sources/d3-async-location/Delegate.swift renamed to Sources/d3-async-location/LocationManagerAsync+/Delegate.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ extension LocationManagerAsync{
1111

1212
/// The methods that you use to receive events from an associated location-manager object
1313
/// The location manager calls its delegate’s methods to report location-related events to your app.
14+
@available(iOS 15.0, watchOS 7.0, *)
1415
final class Delegate: NSObject, CLLocationManagerDelegate{
1516

1617
/// Continuation asynchronously passing location data
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
//
2+
// Permission.swift
3+
//
4+
//
5+
// Created by Igor on 06.02.2023.
6+
//
7+
8+
import CoreLocation
9+
import Combine
10+
import SwiftUI
11+
12+
extension LocationManagerAsync{
13+
14+
/// Helper class to determine permission to get access for streaming ``CLLocation``
15+
@available(iOS 15.0, watchOS 7.0, *)
16+
final class Permission{
17+
18+
/// Name of notification for event location manager changed authorization status
19+
static let authorizationStatus = Notification.Name("authorizationStatus")
20+
21+
// MARK: - Private properties
22+
23+
/// The current authorization status for the app
24+
private var status : CLAuthorizationStatus
25+
26+
/// Continuation to get permission if status is not defined
27+
private var flow : CheckedContinuation<CLAuthorizationStatus, Never>?
28+
29+
/// Check if status is determined
30+
private var isDetermined : Bool{
31+
status != .notDetermined
32+
}
33+
34+
/// Subscription to authorization status changes
35+
private var cancelable : AnyCancellable?
36+
37+
// MARK: - Life circle
38+
39+
/// Init defining is access to location service is granted
40+
/// - Parameter status: Constant indicating the app's authorization to use location services
41+
init(with status: CLAuthorizationStatus){
42+
self.status = status
43+
initSubscription()
44+
}
45+
46+
// MARK: - API
47+
48+
/// Get status asynchronously and check is it authorized to start getting the stream of locations
49+
public func isGranted(for manager: CLLocationManager) async -> Bool{
50+
let status = await requestPermission(manager)
51+
return isAuthorized(status)
52+
}
53+
54+
// MARK: - Private methods
55+
56+
57+
/// Subscribe for event when location manager change authorization status to go on access permission flow
58+
private func initSubscription(){
59+
let name = Permission.authorizationStatus
60+
cancelable = NotificationCenter.default.publisher(for: name)
61+
.sink { [weak self] value in
62+
self?.statusChanged(value)
63+
}
64+
}
65+
66+
/// Determine status after the request permission
67+
/// - Parameter manager: Location manager
68+
private func statusChanged(_ value: Output) {
69+
if let s = value.object as? CLAuthorizationStatus{
70+
status = s
71+
flow?.resume(returning: status)
72+
}
73+
}
74+
75+
/// Check permission status
76+
/// - Parameter status: Constant indicating the app's authorization to use location services
77+
/// - Returns: Return `True` if is allowed
78+
private func isAuthorized(_ status : CLAuthorizationStatus) -> Bool{
79+
[CLAuthorizationStatus.authorizedWhenInUse, .authorizedAlways].contains(status)
80+
}
81+
82+
/// Requests the user’s permission to use location services while the app is in use
83+
/// Don't forget to add in Info "Privacy - Location When In Use Usage Description" something like "Show list of locations"
84+
/// - Returns: Permission status
85+
private func requestPermission(_ manager : CLLocationManager) async -> CLAuthorizationStatus{
86+
manager.requestWhenInUseAuthorization()
87+
88+
if isDetermined{
89+
return status
90+
}
91+
92+
return await withCheckedContinuation{ continuation in
93+
flow = continuation
94+
}
95+
}
96+
}
97+
98+
// MARK: - Alias types -
99+
100+
fileprivate typealias Output = NotificationCenter.Publisher.Output
101+
102+
}
103+

Sources/d3-async-location/Permission.swift

Lines changed: 0 additions & 98 deletions
This file was deleted.

0 commit comments

Comments
 (0)