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

Reset LocationProducer when changing provider #1172

Merged
merged 2 commits into from
Mar 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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