Skip to content

Commit

Permalink
Add LocationApplication (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
0xLeif authored Dec 20, 2023
1 parent cfa070d commit 5e7a391
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import AppState
import CoreLocation

public extension Application {
/// An instance of `CLLocationManager` from the CoreLocation framework, which is used for handling the location data in iOS applications.
var locationManager: Dependency<LocationManager> {
dependency(LocationManager())
}
}

/// LocationApplication is a subclass of AppState's Application that conforms to the CLLocationManagerDelegate protocol. This allows it to handle location updates from CLLocationManager. LocationApplication is designed to be subclassed and it primarily functions to register itself as the delegate for the Application dependency locationManager. However, it doesn't carry out any other tasks by default. This means that you will need to start any updating, for example `startUpdatingLocation`.
open class LocationApplication: LifecyleApplication, CLLocationManagerDelegate {
public required init() {
super.init()

Application.dependency(\.locationManager).delegate = self
}

// MARK: - Open CLLocationManagerDelegate Functions

open func locationManager(_ manager: CLLocationManager, didVisit visit: CLVisit) { }
open func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) { }
open func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) { }
open func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) { }
open func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { }
open func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { }
open func locationManager(_ manager: CLLocationManager, didRange beacons: [CLBeacon], satisfying beaconConstraint: CLBeaconIdentityConstraint) { }
open func locationManager(_ manager: CLLocationManager, didUpdateTo newLocation: CLLocation, from oldLocation: CLLocation) { }
open func locationManager(_ manager: CLLocationManager, didStartMonitoringFor region: CLRegion) { }
open func locationManager(_ manager: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion) { }
open func locationManager(_ manager: CLLocationManager, didFailRangingFor beaconConstraint: CLBeaconIdentityConstraint, error: Error) { }
open func locationManager(_ manager: CLLocationManager, didFinishDeferredUpdatesWithError error: Error?) { }
open func locationManager(_ manager: CLLocationManager, monitoringDidFailFor region: CLRegion?, withError error: Error) { }
open func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { }
open func locationManagerDidPauseLocationUpdates(_ manager: CLLocationManager) { }
open func locationManagerDidResumeLocationUpdates(_ manager: CLLocationManager) { }
open func locationManagerShouldDisplayHeadingCalibration(_ manager: CLLocationManager) -> Bool { false }
}
22 changes: 22 additions & 0 deletions Sources/ApplicationKit/LocationApplication/LocationManager.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import AppState
import CoreLocation

fileprivate extension Application {
var coreLocationManager: Dependency<CLLocationManager> {
dependency(CLLocationManager())
}
}

/// A class that wraps around a CLLocationManager instance from AppState's Application singleton.
open class LocationManager {
@AppDependency(\.coreLocationManager) private var manager: CLLocationManager

/// The delegate object to receive update events.
public var delegate: CLLocationManagerDelegate? {
get { manager.delegate }
set { manager.delegate = newValue }
}

/// Default initializer for the LocationManager class.
public init() { }
}
43 changes: 43 additions & 0 deletions Tests/ApplicationKitTests/LocationApplicationTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import AppState
import XCTest
import CoreLocation
@testable import ApplicationKit

class MockLocationManager: LocationManager {
func test() {
delegate?.locationManager?(.init(), didEnterRegion: .init())
}
}

class MyLocationApplication: LocationApplication {
override func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
print("didEnterRegion: \(region)")
}
}

final class LocationApplicationTests: XCTestCase {
var mockLocationManager: MockLocationManager? {
Application.dependency(\.locationManager) as? MockLocationManager
}

func testLocationApplication() throws {
let locationManagerOverride = Application.override(\.locationManager, with: MockLocationManager())

let locationManager = try XCTUnwrap(mockLocationManager)

XCTAssertNil(locationManager.delegate)

Application.promote(to: MyLocationApplication.self)

XCTAssertNotNil(locationManager.delegate)
XCTAssertTrue(locationManager.delegate is MyLocationApplication)

mockLocationManager?.test()

locationManagerOverride.cancel()

XCTAssertNotNil(locationManager.delegate)
XCTAssertTrue(locationManager.delegate is MyLocationApplication)
XCTAssertFalse(Application.dependency(\.locationManager) is MockLocationManager)
}
}

0 comments on commit 5e7a391

Please sign in to comment.