Skip to content

Commit

Permalink
Reset LocationProducer when changing provider (#1172)
Browse files Browse the repository at this point in the history
  • Loading branch information
macdrevx committed Mar 4, 2022
1 parent 629a94c commit 7994b03
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 3 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ Mapbox welcomes participation and contributions from everyone.

* Update to MapboxCoreMaps 10.4.0-rc.1 and MapboxCommon 21.2.0-rc.1. ([#1158](https://github.com/mapbox/mapbox-maps-ios/pull/1158))
* Enable explicit drawing behavior for metal view(call `draw()` explicitly instead of `setNeedsDisplay` when view's content need to be redrawn).([#1157](https://github.com/mapbox/mapbox-maps-ios/pull/1157))
* Restore cancellation of animations on single tap. ([#1166](https://github.com/mapbox/mapbox-maps-ios/pull/1166))
* Restore cancellation of animations on single tap. ([#1166](https://github.com/mapbox/mapbox-maps-ios/pull/1166))
* Fix issue where invalid locations could be emitted when setting a custom location provider. ([#1172](https://github.com/mapbox/mapbox-maps-ios/pull/1172))

## 10.4.0-beta.1 - February 23, 2022

Expand Down
7 changes: 7 additions & 0 deletions Sources/MapboxMaps/Location/LocationProducer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ internal final class LocationProducer: LocationProducerProtocol {
locationProvider.setDelegate(EmptyLocationProviderDelegate())
}
didSet {
// reinitialize latest values to mimic setup in init
latestCLLocation = nil
latestHeading = nil
latestAccuracyAuthorization = locationProvider.accuracyAuthorization
locationProvider.setDelegate(self)
syncIsUpdating()
}
Expand Down Expand Up @@ -137,6 +141,9 @@ internal final class LocationProducer: LocationProducerProtocol {
}

private func notifyConsumers() {
guard isUpdating else {
return
}
if let latestLocation = latestLocation {
for consumer in _consumers.allObjects {
consumer.locationUpdate(newLocation: latestLocation)
Expand Down
36 changes: 34 additions & 2 deletions Tests/MapboxMapsTests/Location/LocationProducerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -224,18 +224,50 @@ final class LocationProducerTests: XCTestCase {
}

func testSetLocationProviderWithConsumers() {
let otherProvider = MockLocationProvider()
otherProvider.authorizationStatus = .notDetermined
// populate location, heading, and accuracy authorization from the original location provider
let oldHeading = MockHeading()
locationProducer.locationProvider(locationProvider, didUpdateHeading: oldHeading)
let oldLocation = CLLocation.random()
locationProducer.locationProvider(locationProvider, didUpdateLocations: [oldLocation])
locationProvider.accuracyAuthorization = CLAccuracyAuthorization.reducedAccuracy
locationProducer.locationProviderDidChangeAuthorization(locationProvider)

// add a consumer
locationProducer.add(consumer)

// set up the new provider
let otherProvider = MockLocationProvider()
otherProvider.authorizationStatus = .notDetermined
otherProvider.accuracyAuthorization = .random()
locationProducer.locationProvider = otherProvider

// verify that the producer stops the old provider
XCTAssertEqual(locationProvider.stopUpdatingLocationStub.invocations.count, 1)
XCTAssertEqual(locationProvider.stopUpdatingHeadingStub.invocations.count, 1)

// verify that the producer starts the new provider
XCTAssertEqual(otherProvider.requestWhenInUseAuthorizationStub.invocations.count, 1)
XCTAssertEqual(otherProvider.startUpdatingLocationStub.invocations.count, 1)
XCTAssertEqual(otherProvider.startUpdatingHeadingStub.invocations.count, 1)

// send a heading update from the new provider and verify that observers
// are not notified since the new provider has not yet produced a
// location
let newHeading = MockHeading()
locationProducer.locationProvider(locationProvider, didUpdateHeading: newHeading)

XCTAssertTrue(consumer.locationUpdateStub.invocations.isEmpty)

// send a location update and verify that the observers are notified
// with the correct value
let newLocation = CLLocation.random()
locationProducer.locationProvider(locationProvider, didUpdateLocations: [newLocation])

XCTAssertEqual(consumer.locationUpdateStub.invocations.count, 1)
let location = consumer.locationUpdateStub.invocations.first?.parameters
XCTAssertIdentical(location?.location, newLocation)
XCTAssertIdentical(location?.heading, newHeading)
XCTAssertEqual(location?.accuracyAuthorization, otherProvider.accuracyAuthorization)
}

func testSetLocationProviderWithRecentlyDeinitedConsumers() {
Expand Down

0 comments on commit 7994b03

Please sign in to comment.