From bec82898c7dc1ba6986d10a168c9fa42e635b112 Mon Sep 17 00:00:00 2001 From: Gary Tokman Date: Tue, 4 May 2021 23:07:00 -0400 Subject: [PATCH] fix: refactor location auth publisher to new file --- .../CoreLocation/AuthorizationPublisher.swift | 96 +++++++++++++++++++ .../CoreLocation/CLLocationManager.swift | 15 ++- 2 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 Sources/ExtensionKit/CoreLocation/AuthorizationPublisher.swift diff --git a/Sources/ExtensionKit/CoreLocation/AuthorizationPublisher.swift b/Sources/ExtensionKit/CoreLocation/AuthorizationPublisher.swift new file mode 100644 index 0000000..3d5a2f4 --- /dev/null +++ b/Sources/ExtensionKit/CoreLocation/AuthorizationPublisher.swift @@ -0,0 +1,96 @@ +import Foundation +import Combine +import CoreLocation + + +protocol PublisherAuthorizationDelegate: class { + func send(status: CLAuthorizationStatus) +} + +protocol SubscriptionAuthorizationDelegate: class { + func requestAuthorization(type: CLLocationManager.AuthorizationType) +} + +final class AuthorizationSubscription : NSObject, + PublisherAuthorizationDelegate, + Subscription where S.Input == CLAuthorizationStatus, + S.Failure == Never { + + typealias Output = CLAuthorizationStatus + typealias Failure = Never + + var subscriber: S? + private weak var delegate: SubscriptionAuthorizationDelegate? + private let authorizationType: CLLocationManager.AuthorizationType + + init( + subscriber: S, + authorizationType: CLLocationManager.AuthorizationType, + delegate: SubscriptionAuthorizationDelegate + ) { + self.subscriber = subscriber + self.delegate = delegate + self.authorizationType = authorizationType + } + + func request(_ demand: Subscribers.Demand) { + delegate?.requestAuthorization(type: authorizationType) + } + + func cancel() { + subscriber = nil + delegate = nil + } + + func send(status: CLAuthorizationStatus) { + _ = subscriber?.receive(status) + } +} + +final class AuthorizationPublisher: NSObject, + Publisher, + CLLocationManagerDelegate, + SubscriptionAuthorizationDelegate { + + typealias Output = CLAuthorizationStatus + typealias Failure = Never + + private let manager: CLLocationManager + private let authorizationType: CLLocationManager.AuthorizationType + private weak var publisherAuthorizationDelegate: PublisherAuthorizationDelegate? + + init(manager: CLLocationManager, authorizationType: CLLocationManager.AuthorizationType) { + self.manager = manager + self.authorizationType = authorizationType + super.init() + self.manager.delegate = self + } + + func receive(subscriber: S) where S: Subscriber, AuthorizationPublisher.Failure == S.Failure, AuthorizationPublisher.Output == S.Input { + let subscription = AuthorizationSubscription( + subscriber: subscriber, + authorizationType: authorizationType, + delegate: self + ) + subscriber.receive(subscription: subscription) + publisherAuthorizationDelegate = subscription + } + + // MARK: - CLLocationManagerDelegate + + func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { + publisherAuthorizationDelegate?.send(status: status) + } + + // MARK: - AuthorizationSubscriptionDelegate + + func requestAuthorization(type: CLLocationManager.AuthorizationType) { + switch type { + case .whenInUse: + manager.requestWhenInUseAuthorization() + case .always: + manager.requestAlwaysAuthorization() + } + } +} + diff --git a/Sources/ExtensionKit/CoreLocation/CLLocationManager.swift b/Sources/ExtensionKit/CoreLocation/CLLocationManager.swift index 59db4bd..5969ae5 100644 --- a/Sources/ExtensionKit/CoreLocation/CLLocationManager.swift +++ b/Sources/ExtensionKit/CoreLocation/CLLocationManager.swift @@ -2,7 +2,20 @@ import Combine import CoreLocation public extension CLLocationManager { - + + /* + /// Upgrade the user authoriztion status + requestLocationAuthorization() + .flatMap { status -> AnyPublisher in + if status == CLAuthorizationStatus.authorizedAlways { + return AuthorizationPublisher(manager: manager, authorizationType: type) + .eraseToAnyPublisher() + } else { + return Just(status) + .eraseToAnyPublisher() + } + } + **/ /// Request locaton authorization and subscribe to `CLAuthorizationStatus` updates /// - Parameters: /// - manager: `CLLocationManager`