Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct the user defaults, SynchronizedArray #377

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion Sources/SwiftLocation/Async Tasks/AnyTask.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,6 @@ public extension AnyTask {

public protocol CancellableTask: AnyObject {

func cancel(task: any AnyTask)
func cancel(task: any AnyTask, completion: (([AnyTask]) -> Void)?)

}
4 changes: 2 additions & 2 deletions Sources/SwiftLocation/Async Tasks/LocatePermission.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ extension Tasks {
switch event {
case .didChangeAuthorization(let authorization):
guard let continuation = continuation else {
cancellable?.cancel(task: self)
cancellable?.cancel(task: self, completion: nil)
return
}

continuation.resume(returning: authorization)
self.continuation = nil
cancellable?.cancel(task: self)
cancellable?.cancel(task: self, completion: nil)
default:
break
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/SwiftLocation/Async Tasks/SingleUpdateLocation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,11 @@ extension Tasks {

continuation?.resume(returning: .didUpdateLocations(filteredLocations))
continuation = nil
cancellable?.cancel(task: self)
cancellable?.cancel(task: self, completion: nil)
case let .didFailWithError(error):
continuation?.resume(returning: .didFailed(error))
continuation = nil
cancellable?.cancel(task: self)
cancellable?.cancel(task: self, completion: nil)
default:
break
}
Expand Down
24 changes: 17 additions & 7 deletions Sources/SwiftLocation/Location Managers/LocationAsyncBridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ final class LocationAsyncBridge: CancellableTask {

// MARK: - Private Properties

private var tasks = [AnyTask]()
private var tasks = SynchronizedArray<AnyTask>()
weak var location: Location?

// MARK: - Internal function
Expand All @@ -49,21 +49,23 @@ final class LocationAsyncBridge: CancellableTask {
/// Cancel the execution of a task.
///
/// - Parameter task: task to cancel.
func cancel(task: AnyTask) {
cancel(taskUUID: task.uuid)
func cancel(task: AnyTask, completion: (([AnyTask]) -> Void)? = nil) {
cancel(taskUUID: task.uuid, completion: completion)
}

/// Cancel the execution of a task with a given unique identifier.
///
/// - Parameter uuid: unique identifier of the task to remove
private func cancel(taskUUID uuid: UUID) {
tasks.removeAll { task in
private func cancel(taskUUID uuid: UUID, completion: (([AnyTask]) -> Void)? = nil) {
tasks.removeAll(where: { task in
if task.uuid == uuid {
task.didCancelled()
return true
} else {
return false
}
}) { removedTasks in
completion?(removedTasks)
removedTasks.forEach { $0.didCancelled() }
}
}

Expand All @@ -90,7 +92,7 @@ final class LocationAsyncBridge: CancellableTask {
///
/// - Parameter event: event to dispatch.
func dispatchEvent(_ event: LocationManagerBridgeEvent) {
for task in tasks {
tasks.forEach { task in
task.receivedLocationManagerEvent(event)
}

Expand All @@ -100,4 +102,12 @@ final class LocationAsyncBridge: CancellableTask {
}
}

/// Count the task of the given class
///
/// - Parameters:
/// - type: type of `AnyTask` conform task to remove.
func count(tasksTypes type: AnyTask.Type) -> Int {
let typeToCount = ObjectIdentifier(type)
return tasks.filter({ $0.taskType == typeToCount }).count
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,25 @@ public protocol LocationManagerProtocol {
var activityType: CLActivityType { get set }
#endif

#if !os(tvOS)
var pausesLocationUpdatesAutomatically: Bool { get set }
#endif

#if !os(tvOS)
var showsBackgroundLocationIndicator: Bool { get set }
#endif

var distanceFilter: CLLocationDistance { get set }
var desiredAccuracy: CLLocationAccuracy { get set }

#if !os(tvOS)
var headingFilter: CLLocationDegrees { get set }
#endif

#if !os(tvOS)
var headingOrientation: CLDeviceOrientation { get set }
#endif

#if !os(tvOS)
var allowsBackgroundLocationUpdates: Bool { get set }
#endif
Expand Down
42 changes: 41 additions & 1 deletion Sources/SwiftLocation/Location.swift
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,24 @@ public final class Location {
}
#endif

#if !os(tvOS)
/// A Boolean value that indicates whether the location-manager object may pause location updates.
/// By defualt is `true`.
public var pausesLocationUpdatesAutomatically: Bool {
get { locationManager.pausesLocationUpdatesAutomatically }
set { locationManager.pausesLocationUpdatesAutomatically = newValue }
}
#endif

#if !os(tvOS)
/// A Boolean value that indicates whether the status bar changes its appearance when an app uses location services in the background.
/// By defualt is `false`.
public var showsBackgroundLocationIndicator: Bool {
get { locationManager.showsBackgroundLocationIndicator }
set { locationManager.showsBackgroundLocationIndicator = newValue }
}
#endif

/// The minimum distance in meters the device must move horizontally before an update event is generated.
/// By defualt is set to `kCLDistanceFilterNone`.
///
Expand All @@ -107,6 +125,24 @@ public final class Location {
set { locationManager.distanceFilter = newValue }
}

#if !os(tvOS)
/// The minimum angular change in degrees required to generate new heading events.
/// By defualt is `1` degree.
public var headingFilter: CLLocationDegrees {
get { locationManager.headingFilter }
set { locationManager.headingFilter = newValue }
}
#endif

#if !os(tvOS)
/// The device orientation to use when computing heading values.
/// By defualt is `CLDeviceOrientation.portrait`.
public var headingOrientation: CLDeviceOrientation {
get { locationManager.headingOrientation }
set { locationManager.headingOrientation = newValue }
}
#endif

/// Indicates whether the app receives location updates when running in the background.
/// By default is `false`.
///
Expand Down Expand Up @@ -272,7 +308,11 @@ public final class Location {

locationManager.startUpdatingLocation()
stream.onTermination = { @Sendable _ in
self.asyncBridge.cancel(task: task)
self.asyncBridge.cancel(task: task) { _ in
if self.asyncBridge.count(tasksTypes: Tasks.ContinuousUpdateLocation.self) <= 0 {
self.stopUpdatingLocation()
}
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftLocation/Support/Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ extension UserDefaults {
}

func location(forKey key: String) -> CLLocation? {
guard let locationData = UserDefaults.standard.data(forKey: key) else {
guard let locationData = data(forKey: key) else {
return nil
}

Expand Down