Skip to content

Commit 25c9651

Browse files
authored
Merge pull request #7 from luke-gs/locationRequestSatisfying
Add ability to filter locations based on satisfaction of provided block
2 parents f73637e + 16af46e commit 25c9651

File tree

2 files changed

+47
-15
lines changed

2 files changed

+47
-15
lines changed

Sources/CLLocationManager+Promise.swift

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,25 +27,33 @@ extension CLLocationManager {
2727
case whenInUse
2828
}
2929

30-
/**
31-
- Returns: A new promise that fulfills with the most recent CLLocation.
32-
- Note: To return all locations call `allResults()`.
33-
- Parameter requestAuthorizationType: We read your Info plist and try to
34-
determine the authorization type we should request automatically. If you
35-
want to force one or the other, change this parameter from its default
36-
value.
37-
*/
38-
public class func requestLocation(authorizationType: RequestAuthorizationType = .automatic) -> Promise<[CLLocation]> {
39-
return promise(yielding: auther(authorizationType))
30+
/// Request a single location using promises
31+
/// - Note: To return all locations call `allResults()`.
32+
///
33+
/// - Parameters:
34+
/// - authorizationType: requestAuthorizationType: We read your Info plist and try to
35+
/// determine the authorization type we should request automatically. If you
36+
/// want to force one or the other, change this parameter from its default
37+
/// value.
38+
/// - block: A block by which to perform any filtering of the locations
39+
/// that are returned. For example:
40+
/// - In order to only retrieve accurate locations, only
41+
/// return true if the locations horizontal accuracy < 50
42+
///
43+
/// - Returns: A new promise that fulfills with the most recent CLLocation
44+
/// that satisfies the provided block if it exists. If the block
45+
/// does not exist, simply return the last location.
46+
public class func requestLocation(authorizationType: RequestAuthorizationType = .automatic, satisfying block: ((CLLocation) -> Bool)? = nil) -> Promise<[CLLocation]> {
47+
return promise(yielding: auther(authorizationType), satisfying: block)
4048
}
4149

4250
@available(*, deprecated: 5.0, renamed: "requestLocation")
43-
public class func promise(_ requestAuthorizationType: RequestAuthorizationType = .automatic) -> Promise<[CLLocation]> {
44-
return requestLocation(authorizationType: requestAuthorizationType)
51+
public class func promise(_ requestAuthorizationType: RequestAuthorizationType = .automatic, satisfying block: ((CLLocation) -> Bool)? = nil) -> Promise<[CLLocation]> {
52+
return requestLocation(authorizationType: requestAuthorizationType, satisfying: block)
4553
}
4654

47-
private class func promise(yielding yield: (CLLocationManager) -> Void = { _ in }) -> Promise<[CLLocation]> {
48-
let manager = LocationManager()
55+
private class func promise(yielding yield: (CLLocationManager) -> Void = { _ in }, satisfying block: ((CLLocation) -> Bool)? = nil) -> Promise<[CLLocation]> {
56+
let manager = LocationManager(satisfying: block)
4957
manager.delegate = manager
5058
yield(manager)
5159
manager.startUpdatingLocation()
@@ -58,9 +66,19 @@ extension CLLocationManager {
5866

5967
private class LocationManager: CLLocationManager, CLLocationManagerDelegate {
6068
let (promise, seal) = Promise<[CLLocation]>.pending()
69+
let satisfyingBlock: ((CLLocation) -> Bool)?
6170

6271
@objc fileprivate func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
63-
seal.fulfill(locations)
72+
if let block = satisfyingBlock {
73+
let satisfiedLocations = locations.filter { block($0) == true }
74+
seal.fulfill(satisfiedLocations)
75+
} else {
76+
seal.fulfill(locations)
77+
}
78+
}
79+
80+
init(satisfying block: ((CLLocation) -> Bool)? = nil) {
81+
self.satisfyingBlock = block
6482
}
6583

6684
@objc func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {

Tests/CLLocationManagerTests.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@ class Test_CLLocationManager_Swift: XCTestCase {
1919
}
2020
}
2121

22+
func test_fufillsWithSatisfyingBlock() {
23+
swizzle(CLLocationManager.self, #selector(CLLocationManager.startUpdatingLocation)) {
24+
let ex = expectation(description: "")
25+
let block: ((CLLocation) -> Bool) = { location in
26+
return location.coordinate.latitude == dummy.last?.coordinate.latitude
27+
}
28+
CLLocationManager.promise(satisfying: block).done({ locations in
29+
locations.forEach { XCTAssert(block($0) == true, "Block should be successful for returned values") }
30+
ex.fulfill()
31+
})
32+
waitForExpectations(timeout: 1, handler: nil)
33+
}
34+
}
35+
2236
#if os(iOS)
2337
func test_requestAuthorization() {
2438
let ex = expectation(description: "")

0 commit comments

Comments
 (0)