Skip to content

Commit 2112449

Browse files
authored
Merge pull request #38 from RomanPodymov/main
Support tvOS
2 parents e70b5dc + 554a775 commit 2112449

File tree

10 files changed

+49
-14
lines changed

10 files changed

+49
-14
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[![Swift Package Manager](https://img.shields.io/badge/Swift_Package_Manager-compatible-orange?style=flat)](https://img.shields.io/badge/Swift_Package_Manager-compatible-orange?style=flat)
44
[![Swift](https://img.shields.io/badge/Swift-5.5-orange?style=flat)](https://img.shields.io/badge/Swift-5.5-Orange?style=flat)
5-
[![Platforms](https://img.shields.io/badge/platforms-iOS--13%20|%20macOS(beta)%20|%20watchOS--6(beta)-orange?style=flat)](https://img.shields.io/badge/platforms-iOS--13%20|%20macOS(beta)-orange?style=flat)
5+
[![Platforms](https://img.shields.io/badge/platforms-iOS--13%20|%20macOS(beta)%20|%20watchOS--6(beta)%20|%20tvOS(beta)-orange?style=flat)](https://img.shields.io/badge/platforms-iOS--13%20|%20macOS(beta)%20|%20watchOS--6(beta)%20|%20tvOS(beta)-orange?style=flat)
66

77
Wrapper for Apple `CoreLocation` framework with new Concurency Model. No more `delegate` pattern or `completion blocks`.
88

Sources/AsyncLocationKit/AsyncLocationManager.swift

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public typealias HeadingMonitorStream = AsyncStream<HeadingMonitorEvent>
3434
public typealias AuthorizationStream = AsyncStream<AuthorizationEvent>
3535
public typealias AccuracyAuthorizationStream = AsyncStream<AccuracyAuthorizationEvent>
3636
@available(watchOS, unavailable)
37+
@available(tvOS, unavailable)
3738
public typealias BeaconsRangingStream = AsyncStream<BeaconRangeEvent>
3839

3940
public final class AsyncLocationManager {
@@ -51,7 +52,9 @@ public final class AsyncLocationManager {
5152
locationDelegate = LocationDelegate(delegateProxy: proxyDelegate)
5253
self.locationManager.delegate = locationDelegate
5354
self.locationManager.desiredAccuracy = desiredAccuracy.convertingAccuracy
55+
#if !os(tvOS)
5456
self.locationManager.allowsBackgroundLocationUpdates = allowsBackgroundLocationUpdates
57+
#endif
5558
}
5659

5760

@@ -64,7 +67,7 @@ public final class AsyncLocationManager {
6467

6568
@available(watchOS 6.0, *)
6669
public func getAuthorizationStatus() -> CLAuthorizationStatus {
67-
if #available(iOS 14, watchOS 7, *) {
70+
if #available(iOS 14, tvOS 14, watchOS 7, *) {
6871
return locationManager.authorizationStatus
6972
} else {
7073
return CLLocationManager.authorizationStatus()
@@ -116,7 +119,7 @@ public final class AsyncLocationManager {
116119
proxyDelegate.cancel(for: AccuracyAuthorizationMonitoringPerformer.self)
117120
}
118121

119-
@available(iOS 14, watchOS 7, *)
122+
@available(iOS 14, tvOS 14, watchOS 7, *)
120123
public func getAccuracyAuthorization() -> CLAccuracyAuthorization {
121124
locationManager.accuracyAuthorization
122125
}
@@ -125,6 +128,7 @@ public final class AsyncLocationManager {
125128
locationManager.desiredAccuracy = newAccuracy.convertingAccuracy
126129
}
127130

131+
@available(tvOS, unavailable)
128132
public func updateAllowsBackgroundLocationUpdates(with newAllows: Bool) {
129133
locationManager.allowsBackgroundLocationUpdates = newAllows
130134
}
@@ -149,7 +153,7 @@ public final class AsyncLocationManager {
149153
})
150154
}
151155

152-
#if !APPCLIP
156+
#if !APPCLIP && !os(tvOS)
153157
@available(*, deprecated, message: "Use new function requestPermission(with:)")
154158
@available(watchOS 7.0, *)
155159
@available(iOS 14, *)
@@ -195,11 +199,12 @@ public final class AsyncLocationManager {
195199
}
196200
}
197201

198-
@available(iOS 14, watchOS 7, *)
202+
@available(iOS 14, tvOS 14, watchOS 7, *)
199203
public func requestTemporaryFullAccuracyAuthorization(purposeKey: String) async throws -> CLAccuracyAuthorization? {
200204
try await locationPermissionTemporaryFullAccuracy(purposeKey: purposeKey)
201205
}
202206

207+
@available(tvOS, unavailable)
203208
public func startUpdatingLocation() async -> LocationStream {
204209
let monitoringPerformer = MonitoringUpdateLocationPerformer()
205210
return LocationStream { streamContinuation in
@@ -231,6 +236,7 @@ public final class AsyncLocationManager {
231236
}
232237

233238
@available(watchOS, unavailable)
239+
@available(tvOS, unavailable)
234240
public func startMonitoring(for region: CLRegion) async -> RegionMonitoringStream {
235241
let performer = RegionMonitoringPerformer(region: region)
236242
return RegionMonitoringStream { streamContinuation in
@@ -244,6 +250,7 @@ public final class AsyncLocationManager {
244250
}
245251

246252
@available(watchOS, unavailable)
253+
@available(tvOS, unavailable)
247254
public func stopMonitoring(for region: CLRegion) {
248255
proxyDelegate.cancel(for: RegionMonitoringPerformer.self) { regionMonitoring in
249256
guard let regionPerformer = regionMonitoring as? RegionMonitoringPerformer else { return false }
@@ -253,6 +260,7 @@ public final class AsyncLocationManager {
253260
}
254261

255262
@available(watchOS, unavailable)
263+
@available(tvOS, unavailable)
256264
public func startMonitoringVisit() async -> VisitMonitoringStream {
257265
let performer = VisitMonitoringPerformer()
258266
return VisitMonitoringStream { stream in
@@ -266,6 +274,7 @@ public final class AsyncLocationManager {
266274
}
267275

268276
@available(watchOS, unavailable)
277+
@available(tvOS, unavailable)
269278
public func stopMonitoringVisit() {
270279
proxyDelegate.cancel(for: VisitMonitoringPerformer.self)
271280
locationManager.stopMonitoringVisits()
@@ -292,6 +301,7 @@ public final class AsyncLocationManager {
292301
#endif
293302

294303
@available(watchOS, unavailable)
304+
@available(tvOS, unavailable)
295305
public func startRangingBeacons(satisfying: CLBeaconIdentityConstraint) async -> BeaconsRangingStream {
296306
let performer = BeaconsRangePerformer(satisfying: satisfying)
297307
return BeaconsRangingStream { stream in
@@ -305,6 +315,7 @@ public final class AsyncLocationManager {
305315
}
306316

307317
@available(watchOS, unavailable)
318+
@available(tvOS, unavailable)
308319
public func stopRangingBeacons(satisfying: CLBeaconIdentityConstraint) {
309320
proxyDelegate.cancel(for: BeaconsRangePerformer.self) { beaconsMonitoring in
310321
guard let beaconsPerformer = beaconsMonitoring as? BeaconsRangePerformer else { return false }
@@ -346,12 +357,14 @@ extension AsyncLocationManager {
346357
locationManager.requestAlwaysAuthorization()
347358
}
348359
#else
349-
if #available(iOS 14, watchOS 7, *), locationManager.authorizationStatus != .notDetermined && locationManager.authorizationStatus != .authorizedWhenInUse {
360+
if #available(iOS 14, tvOS 14, watchOS 7, *), locationManager.authorizationStatus != .notDetermined && locationManager.authorizationStatus != .authorizedWhenInUse {
350361
continuation.resume(with: .success(locationManager.authorizationStatus))
351362
} else {
363+
#if !os(tvOS)
352364
authorizationPerformer.linkContinuation(continuation)
353365
proxyDelegate.addPerformer(authorizationPerformer)
354366
locationManager.requestAlwaysAuthorization()
367+
#endif
355368
}
356369
#endif
357370
}
@@ -360,7 +373,7 @@ extension AsyncLocationManager {
360373
})
361374
}
362375

363-
@available(iOS 14, watchOS 7, *)
376+
@available(iOS 14, tvOS 14, watchOS 7, *)
364377
private func locationPermissionTemporaryFullAccuracy(purposeKey: String) async throws -> CLAccuracyAuthorization? {
365378
let authorizationPerformer = RequestAccuracyAuthorizationPerformer()
366379
return try await withTaskCancellationHandler(operation: {

Sources/AsyncLocationKit/CoreLocationEvents.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,19 @@ enum CoreLocationDelegateEvent {
3131
case didChangeAccuracyAuthorization(authorization: CLAccuracyAuthorization)
3232
// MARK: - Location events
3333
case didUpdate(locations: [CLLocation])
34+
@available(tvOS, unavailable)
3435
case didUpdateHeading(heading: CLHeading)
3536

3637
@available(watchOS, unavailable)
38+
@available(tvOS, unavailable)
3739
case didDetermine(state: CLRegionState, forRegion: CLRegion)
3840

3941
// MARK: - Beacons events
4042
@available(watchOS, unavailable)
43+
@available(tvOS, unavailable)
4144
case didRange(beacons: [CLBeacon], beaconConstraint: CLBeaconIdentityConstraint)
4245
@available(watchOS, unavailable)
46+
@available(tvOS, unavailable)
4347
case didFailRanginFor(beaconConstraint: CLBeaconIdentityConstraint, error: Error)
4448
// MARK: - Region events
4549
case didEnterRegion(region: CLRegion)
@@ -50,6 +54,7 @@ enum CoreLocationDelegateEvent {
5054
case monitoringDidFailFor(region: CLRegion?, error: Error)
5155
// MARK: - Visit event
5256
@available(watchOS, unavailable)
57+
@available(tvOS, unavailable)
5358
case didVisit(visit: CLVisit)
5459
// MARK: - Pause and resume events
5560
case locationUpdatesPaused

Sources/AsyncLocationKit/Helpers/NotificationNames.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
// SOFTWARE.
2222

2323
import Foundation
24-
#if os(iOS)
24+
#if os(iOS) || os(tvOS)
2525
import UIKit
2626
#elseif os(macOS)
2727
import AppKit
@@ -31,15 +31,15 @@ import WatchKit
3131

3232
@available(macOS 12, iOS 13, tvOS 13, watchOS 8, *)
3333
struct NotificationNamesConstants {
34-
#if os(iOS)
34+
#if os(iOS) || os(tvOS)
3535
static let willResignActiveName = UIApplication.willResignActiveNotification
3636
#elseif os(macOS)
3737
static let willResignActiveName = NSApplication.willResignActiveNotification
3838
#elseif os(watchOS)
3939
static let willResignActiveName = WKExtension.applicationWillResignActiveNotification
4040
#endif
4141

42-
#if os(iOS)
42+
#if os(iOS) || os(tvOS)
4343
static let didBecomeActiveName = UIApplication.didBecomeActiveNotification
4444
#elseif os(macOS)
4545
static let didBecomeActiveName = NSApplication.didBecomeActiveNotification

Sources/AsyncLocationKit/LocationDelegate.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ internal class LocationDelegate: NSObject, CLLocationManagerDelegate {
3333

3434
// MARK: - Authorize
3535
@available(watchOS 7.0, *)
36-
@available(iOS 14, *)
36+
@available(iOS 14, tvOS 14, *)
3737
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
3838
proxy?.eventForMethodInvoked(.didChangeAuthorization(status: manager.authorizationStatus))
3939
proxy?.eventForMethodInvoked(.didChangeAccuracyAuthorization(authorization: manager.accuracyAuthorization))
@@ -59,11 +59,13 @@ internal class LocationDelegate: NSObject, CLLocationManagerDelegate {
5959
proxy?.eventForMethodInvoked(.didUpdate(locations: locations))
6060
}
6161

62+
#if !os(tvOS)
6263
func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
6364
proxy?.eventForMethodInvoked(.didUpdateHeading(heading: newHeading))
6465
}
66+
#endif
6567

66-
#if os(iOS) || os(tvOS)
68+
#if os(iOS)
6769
func locationManager(_ manager: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion) {
6870
proxy?.eventForMethodInvoked(.didDetermine(state: state, forRegion: region))
6971
}
@@ -96,7 +98,7 @@ internal class LocationDelegate: NSObject, CLLocationManagerDelegate {
9698
proxy?.eventForMethodInvoked(.didFailWithError(error: error))
9799
}
98100

99-
#if os(iOS) || os(tvOS)
101+
#if os(iOS)
100102
func locationManager(_ manager: CLLocationManager, monitoringDidFailFor region: CLRegion?, withError error: Error) {
101103
proxy?.eventForMethodInvoked(.monitoringDidFailFor(region: region, error: error))
102104
}

Sources/AsyncLocationKit/Performers/BeaconsRangePerformer.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import Foundation
2424
import CoreLocation
2525

2626
@available(watchOS, unavailable)
27+
@available(tvOS, unavailable)
2728
public enum BeaconRangeEvent {
2829
case didRange(beacons: [CLBeacon], beaconConstraint: CLBeaconIdentityConstraint)
2930
case didFailRanginFor(beaconConstraint: CLBeaconIdentityConstraint, error: Error)
@@ -42,17 +43,21 @@ class BeaconsRangePerformer: AnyLocationPerformer {
4243
var eventssupported: [CoreLocationEventSupport] = [.didRangeBeacons, .didFailRanginForBeaconConstraint]
4344

4445
@available(watchOS, unavailable)
46+
@available(tvOS, unavailable)
4547
var satisfying: CLBeaconIdentityConstraint
4648

4749
@available(watchOS, unavailable)
50+
@available(tvOS, unavailable)
4851
var stream: BeaconsRangingStream.Continuation?
4952

5053
@available(watchOS, unavailable)
54+
@available(tvOS, unavailable)
5155
init(satisfying: CLBeaconIdentityConstraint) {
5256
self.satisfying = satisfying
5357
}
5458

5559
@available(watchOS, unavailable)
60+
@available(tvOS, unavailable)
5661
func linkContinuation(_ continuation: BeaconsRangingStream.Continuation) {
5762
self.stream = continuation
5863
}
@@ -63,10 +68,12 @@ class BeaconsRangePerformer: AnyLocationPerformer {
6368

6469
func invokedMethod(event: CoreLocationDelegateEvent) {
6570
switch event {
71+
#if !os(tvOS)
6672
case .didRange(let beacons, let beaconConstraint):
6773
stream?.yield(.didRange(beacons: beacons, beaconConstraint: beaconConstraint))
6874
case .didFailRanginFor(let beaconConstraint, let error):
6975
stream?.yield(.didFailRanginFor(beaconConstraint: beaconConstraint, error: error))
76+
#endif
7077
default:
7178
fatalError("Method can't be execute by this performer: \(String(describing: self)) for event: \(type(of: event))")
7279
}

Sources/AsyncLocationKit/Performers/HeadingMonitorPerformer.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import Foundation
2424
import CoreLocation.CLHeading
2525

2626
public enum HeadingMonitorEvent {
27+
@available(tvOS, unavailable)
2728
case didUpdate(heading: CLHeading)
2829
case didFailWith(error: Error)
2930
}
@@ -49,8 +50,10 @@ class HeadingMonitorPerformer: AnyLocationPerformer {
4950

5051
func invokedMethod(event: CoreLocationDelegateEvent) {
5152
switch event {
53+
#if !os(tvOS)
5254
case .didUpdateHeading(let heading):
5355
stream?.yield(.didUpdate(heading: heading))
56+
#endif
5457
case .didFailWithError(let error):
5558
stream?.yield(.didFailWith(error: error))
5659
default:

Sources/AsyncLocationKit/Performers/VisitMonitoringPerformer.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import CoreLocation.CLVisit
2525

2626
public enum VisitMonitoringEvent {
2727
@available(watchOS, unavailable)
28+
@available(tvOS, unavailable)
2829
case didVisit(visit: CLVisit)
2930
case didFailWithError(error: Error)
3031
}
@@ -53,7 +54,7 @@ class VisitMonitoringPerformer: AnyLocationPerformer {
5354
case .didFailWithError(let error):
5455
stream?.yield(.didFailWithError(error: error))
5556
case .didVisit(let visit):
56-
#if os(iOS) || os(tvOS)
57+
#if os(iOS)
5758
stream?.yield(.didVisit(visit: visit))
5859
#endif
5960
default:

Tests/AsyncLocationKitTests/AsyncLocationKitTests.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@ final class AsyncLocationKitTests: XCTestCase {
1616
}
1717

1818
func testAllowsBackgroundLocationUpdates() {
19+
#if !os(tvOS)
1920
let firstAllows = true
2021
let locationManager = AsyncLocationManager(locationManager: AsyncLocationKitTests.mockLocationManager, allowsBackgroundLocationUpdates: firstAllows)
2122
XCTAssertTrue(AsyncLocationKitTests.mockLocationManager.allowsBackgroundLocationUpdates == firstAllows)
2223

2324
let secondAllows = false
2425
locationManager.updateAllowsBackgroundLocationUpdates(with: secondAllows)
2526
XCTAssertTrue(AsyncLocationKitTests.mockLocationManager.allowsBackgroundLocationUpdates == secondAllows)
27+
#endif
2628
}
2729

2830
func testRequestLocation() async {

Tests/AsyncLocationKitTests/LocationManager.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import CoreLocation
1111
class MockLocationManager: CLLocationManager {
1212
private var mockAllowsBackgroundLocationUpdates: Bool = false
1313

14+
#if !os(tvOS)
1415
override var allowsBackgroundLocationUpdates: Bool {
1516
get {
1617
return mockAllowsBackgroundLocationUpdates
@@ -19,6 +20,7 @@ class MockLocationManager: CLLocationManager {
1920
mockAllowsBackgroundLocationUpdates = newValue
2021
}
2122
}
23+
#endif
2224

2325
override var location: CLLocation? {
2426
return CLLocation(latitude: 100, longitude: 200)

0 commit comments

Comments
 (0)