From 58a20872e27ee6ae1a09200cef45e2bf615b7d1b Mon Sep 17 00:00:00 2001 From: Robbie Murray Date: Wed, 11 Jun 2025 10:38:27 +0100 Subject: [PATCH 1/2] Clean up some compiler warnings * remove the CLLocationCoordinate2D extension that added Equatable Conformance and replace it with a .isNear(to:) method that behaves in exactly the same way but with a name that is more descriptive of its purpose This also avoids undefined behavior in the future if CLLocationCoordinate2D ever gains Equatable conformance. * fix localisation string in VoiceSettings.storyboard That had no affect on the app but was causing a warning * add dummy experiment to git rid of warning about empty enum --- .../ExperimentManager.swift | 1 + .../CoreLocation+Extensions.swift | 18 ++++++---- .../MapKit/MKMapView+Extensions.swift | 2 +- .../Code/App/Helpers/GeometryUtils.swift | 9 ++--- .../AuthoredActivityContent.swift | 2 +- .../Models/Cache Models/Intersection.swift | 12 +++---- .../Database Models/ReferenceEntity.swift | 2 +- .../Code/Data/Models/Protocols/Road.swift | 6 ++-- .../Models/Temp Models/GenericLocation.swift | 2 +- .../Data/Preview/IntersectionFinder.swift | 25 +++++++------ .../Data/Preview/RoadAdjacentDataView.swift | 36 ++++++++++++++++++- .../Data/Spatial Data/SpatialDataCache.swift | 2 +- .../Beacon/BeaconTitleViewController.swift | 2 +- .../Location Detail/LocationDetail.swift | 8 ++--- .../BeaconDetailStore.swift | 2 +- .../EditableMapViewController.swift | 4 +-- .../Visual UI/Views/VoiceSettings.storyboard | 24 ++++++------- 17 files changed, 100 insertions(+), 57 deletions(-) diff --git a/apps/ios/GuideDogs/Code/App/Feature Flags/Experiment Flighting/ExperimentManager.swift b/apps/ios/GuideDogs/Code/App/Feature Flags/Experiment Flighting/ExperimentManager.swift index c3bd06efa..74f0b4cb5 100644 --- a/apps/ios/GuideDogs/Code/App/Feature Flags/Experiment Flighting/ExperimentManager.swift +++ b/apps/ios/GuideDogs/Code/App/Feature Flags/Experiment Flighting/ExperimentManager.swift @@ -14,6 +14,7 @@ enum KnownExperiment: CaseIterable { // Supports client experimentation // For each experiment, add a case to `KnownExperiment` // + case placeholder // TODO: Replace with real experiments var uuid: UUID { /* diff --git a/apps/ios/GuideDogs/Code/App/Framework Extensions/Geo Extensions/CoreLocation+Extensions.swift b/apps/ios/GuideDogs/Code/App/Framework Extensions/Geo Extensions/CoreLocation+Extensions.swift index 06f304800..6d828b2e3 100644 --- a/apps/ios/GuideDogs/Code/App/Framework Extensions/Geo Extensions/CoreLocation+Extensions.swift +++ b/apps/ios/GuideDogs/Code/App/Framework Extensions/Geo Extensions/CoreLocation+Extensions.swift @@ -136,7 +136,7 @@ extension Array where Element == CLLocation { extension CLLocationCoordinate2D { var isValidLocationCoordinate: Bool { - return CLLocationCoordinate2DIsValid(self) && self != CLLocationCoordinate2D(latitude: 0.0, longitude: 0.0) + return CLLocationCoordinate2DIsValid(self) && !self.isNear(to: CLLocationCoordinate2D(latitude: 0.0, longitude: 0.0)) } func distance(from coordinate: CLLocationCoordinate2D) -> CLLocationDistance { @@ -165,7 +165,7 @@ extension CLLocationCoordinate2D { } // Check if the coordinates are the same - guard self != coordinate else { + guard !self .isNear(to: coordinate )else { return 0 } @@ -221,14 +221,18 @@ extension CLLocationCoordinate2D { } -extension CLLocationCoordinate2D: Equatable { - public static func == (lhs: CLLocationCoordinate2D, rhs: CLLocationCoordinate2D) -> Bool { - return lhs.equalTo(coordinate: rhs, threshold: 0.0000009) - } +extension CLLocationCoordinate2D { - private func equalTo(coordinate: CLLocationCoordinate2D, threshold: CLLocationDegrees) -> Bool { + public func isNear(to coordinate: CLLocationCoordinate2D, threshold: CLLocationDegrees = 0.0000009) -> Bool { return fabs(self.latitude - coordinate.latitude) <= threshold && fabs(self.longitude - coordinate.longitude) <= threshold } + + public func isNear(to coordinate: CLLocationCoordinate2D?, threshold: CLLocationDegrees = 0.0000009) -> Bool { + guard let coordinate = coordinate else { + return false + } + return isNear(to: coordinate, threshold: threshold) + } } extension CLLocationCoordinate2D: CustomStringConvertible { diff --git a/apps/ios/GuideDogs/Code/App/Framework Extensions/MapKit/MKMapView+Extensions.swift b/apps/ios/GuideDogs/Code/App/Framework Extensions/MapKit/MKMapView+Extensions.swift index 807124875..a4e868040 100644 --- a/apps/ios/GuideDogs/Code/App/Framework Extensions/MapKit/MKMapView+Extensions.swift +++ b/apps/ios/GuideDogs/Code/App/Framework Extensions/MapKit/MKMapView+Extensions.swift @@ -20,7 +20,7 @@ extension MKMapView { } private func showAnnotationAndCenter(_ annotation: MKAnnotation) { - guard centerCoordinate != annotation.coordinate else { + guard !centerCoordinate.isNear(to: annotation.coordinate )else { // no-op return } diff --git a/apps/ios/GuideDogs/Code/App/Helpers/GeometryUtils.swift b/apps/ios/GuideDogs/Code/App/Helpers/GeometryUtils.swift index c4ed974ab..037d5b4a4 100644 --- a/apps/ios/GuideDogs/Code/App/Helpers/GeometryUtils.swift +++ b/apps/ios/GuideDogs/Code/App/Helpers/GeometryUtils.swift @@ -70,7 +70,7 @@ class GeometryUtils { } // Check if we need to add a coordinate for a closed path - if coordinates.last! != coordinates.first! { + if !coordinates.last!.isNear(to: coordinates.first! ){ (pixelX, pixelY) = VectorTile.getPixelXY(latitude: coordinates.first!.latitude, longitude: coordinates.first!.longitude, zoom: 16) } path.move(to: CGPoint(x: pixelX, y: pixelY)) @@ -125,7 +125,7 @@ class GeometryUtils { static func split(path: [CLLocationCoordinate2D], atCoordinate coordinate: CLLocationCoordinate2D, reversedDirection: Bool = false) -> [CLLocationCoordinate2D] { - guard let coordinateIndex = path.firstIndex(of: coordinate) else { + guard let coordinateIndex = path.firstIndex(where: {coordinate.isNear(to: $0)}) else { return [] } @@ -147,7 +147,8 @@ class GeometryUtils { static func rotate(circularPath path: [CLLocationCoordinate2D], atCoordinate coordinate: CLLocationCoordinate2D, reversedDirection: Bool = false) -> [CLLocationCoordinate2D] { - guard pathIsCircular(path), let coordinateIndex = path.firstIndex(of: coordinate) else { + guard pathIsCircular(path), + let coordinateIndex = path.firstIndex(where: {coordinate.isNear(to: $0)}) else { return [] } @@ -176,7 +177,7 @@ class GeometryUtils { return false } - return first == last + return first.isNear(to: last) } /// Returns the distance of a coordinate path diff --git a/apps/ios/GuideDogs/Code/Data/Authored Activities/AuthoredActivityContent.swift b/apps/ios/GuideDogs/Code/Data/Authored Activities/AuthoredActivityContent.swift index f7a304073..4d8ed171b 100644 --- a/apps/ios/GuideDogs/Code/Data/Authored Activities/AuthoredActivityContent.swift +++ b/apps/ios/GuideDogs/Code/Data/Authored Activities/AuthoredActivityContent.swift @@ -405,7 +405,7 @@ extension ActivityPOI: POI { } func contains(location: CLLocationCoordinate2D) -> Bool { - return coordinate == location + return coordinate.isNear(to: location) } func closestLocation(from location: CLLocation, useEntranceIfAvailable: Bool) -> CLLocation { diff --git a/apps/ios/GuideDogs/Code/Data/Models/Cache Models/Intersection.swift b/apps/ios/GuideDogs/Code/Data/Models/Cache Models/Intersection.swift index c4d3c3d76..ab7267d7b 100644 --- a/apps/ios/GuideDogs/Code/Data/Models/Cache Models/Intersection.swift +++ b/apps/ios/GuideDogs/Code/Data/Models/Cache Models/Intersection.swift @@ -380,7 +380,7 @@ class Intersection: Object, Locatable, Localizable { // Check roads that intersect with their vertices (first or last coordinates). // This represents the vertical section of the T. guard let roadCoordinates = road.coordinates else { return false } - guard intersectionCoordinate == roadCoordinates.first || intersectionCoordinate == roadCoordinates.last else { return false } + guard intersectionCoordinate.isNear(to: roadCoordinates.first) || intersectionCoordinate.isNear(to: roadCoordinates.last) else { return false } // Find a similar road that intersect with it's edge (not the first or last coordinates). // This represents the horizontal section of the T. @@ -388,7 +388,7 @@ class Intersection: Object, Locatable, Localizable { guard otherRoad.key != road.key && otherRoad.name == road.name else { return false } guard let otherRoadCoordinates = otherRoad.coordinates else { return false } - return intersectionCoordinate != otherRoadCoordinates.first && intersectionCoordinate != otherRoadCoordinates.last + return !intersectionCoordinate.isNear(to: otherRoadCoordinates.first) && !intersectionCoordinate.isNear(to: otherRoadCoordinates.last) } } } @@ -520,7 +520,7 @@ extension Intersection { return intersection } - let similarIntersections = intersections.filter { $0.coordinate == intersection.coordinate } + let similarIntersections = intersections.filter { $0.coordinate.isNear(to: intersection.coordinate) } guard similarIntersections.count > 1 else { return intersection } @@ -611,14 +611,14 @@ extension Intersection { let intersectionCoordinate = self.coordinate // 1. Road start - if intersectionCoordinate == roadCoordinates.first! { + if intersectionCoordinate.isNear(to: roadCoordinates.first) { guard let bearing = road.bearing() else { return nil } let direction = Direction(from: heading, to: bearing, type: .leftRight) return [RoadDirection(road, bearing, direction)] } // 2. Road end - else if intersectionCoordinate == roadCoordinates.last! { + else if intersectionCoordinate.isNear(to: roadCoordinates.last) { guard let bearing = road.bearing(reversedDirection: true) else { return nil } let direction = Direction(from: heading, to: bearing, type: .leftRight) @@ -627,7 +627,7 @@ extension Intersection { // 3. Along the road else { // Find the intersection coordinate along the road - guard let intersectionCoordinateIndex = roadCoordinates.firstIndex(of: intersectionCoordinate) else { + guard let intersectionCoordinateIndex = roadCoordinates.firstIndex(where: {$0.isNear(to: intersectionCoordinate) }) else { // We did not find a match for the intersection coordinate // The road does not contain the intersection coordinate DDLogDebug("Could not find an intersection coordinate for road: \(road.name)") diff --git a/apps/ios/GuideDogs/Code/Data/Models/Database Models/ReferenceEntity.swift b/apps/ios/GuideDogs/Code/Data/Models/Database Models/ReferenceEntity.swift index 68c56e33a..a9e46e7eb 100644 --- a/apps/ios/GuideDogs/Code/Data/Models/Database Models/ReferenceEntity.swift +++ b/apps/ios/GuideDogs/Code/Data/Models/Database Models/ReferenceEntity.swift @@ -406,7 +406,7 @@ class ReferenceEntity: Object, ObjectKeyIdentifiable { /// - Throws: If the database/cache cannot be accessed or the new reference entity cannot be added static func update(entity: ReferenceEntity, location: CLLocationCoordinate2D? = nil, nickname: String?, address: String?, annotation: String?, context: String? = nil, isTemp: Bool) throws { var locChanged: Bool = false - if let loc = location, loc != entity.coordinate { + if let loc = location, !loc.isNear(to: entity.coordinate) { locChanged = true } diff --git a/apps/ios/GuideDogs/Code/Data/Models/Protocols/Road.swift b/apps/ios/GuideDogs/Code/Data/Models/Protocols/Road.swift index e52b62abd..3fd445f08 100644 --- a/apps/ios/GuideDogs/Code/Data/Models/Protocols/Road.swift +++ b/apps/ios/GuideDogs/Code/Data/Models/Protocols/Road.swift @@ -165,11 +165,11 @@ extension Road { guard let roadCoordinates = coordinates else { return .none } let intersectionCoordinate = intersection.coordinate - if intersectionCoordinate == roadCoordinates.first { + if intersectionCoordinate.isNear(to: roadCoordinates.first) { return .leading - } else if intersectionCoordinate == roadCoordinates.last { + } else if intersectionCoordinate.isNear(to: roadCoordinates.last) { return .trailing - } else if roadCoordinates.contains(intersectionCoordinate) { + } else if roadCoordinates.contains(where: {$0.isNear(to: intersectionCoordinate) }) { return .leadingAndTrailing } diff --git a/apps/ios/GuideDogs/Code/Data/Models/Temp Models/GenericLocation.swift b/apps/ios/GuideDogs/Code/Data/Models/Temp Models/GenericLocation.swift index ed7a3258c..5fa0a115b 100644 --- a/apps/ios/GuideDogs/Code/Data/Models/Temp Models/GenericLocation.swift +++ b/apps/ios/GuideDogs/Code/Data/Models/Temp Models/GenericLocation.swift @@ -92,7 +92,7 @@ class GenericLocation: SelectablePOI { // MARK: Methods func contains(location: CLLocationCoordinate2D) -> Bool { - return location == self.location.coordinate + return location.isNear(to: self.location.coordinate) } func updateDistanceAndBearing(with location: CLLocation) { diff --git a/apps/ios/GuideDogs/Code/Data/Preview/IntersectionFinder.swift b/apps/ios/GuideDogs/Code/Data/Preview/IntersectionFinder.swift index e8a50a81d..ba72690e0 100644 --- a/apps/ios/GuideDogs/Code/Data/Preview/IntersectionFinder.swift +++ b/apps/ios/GuideDogs/Code/Data/Preview/IntersectionFinder.swift @@ -34,7 +34,7 @@ struct IntersectionFinder { road: Road, preferMainIntersections: Bool = false, secondaryRoadsContext: SecondaryRoadsContext = .standard) { - guard let roadCoordinates = road.coordinates, roadCoordinates.contains(rootCoordinate) else { + guard let roadCoordinates = road.coordinates, roadCoordinates.contains(where: {rootCoordinate.isNear(to: $0)}) else { return nil } @@ -195,10 +195,10 @@ struct IntersectionFinder { coordinatesFromRoot : (trailingCoordinates + coordinatesFromRoot.dropFirst()) - guard let endpointIntersection = intersections.first(where: { $0.coordinate == lastCoordinate }) else { + guard let endpointIntersection = intersections.first(where: { $0.coordinate.isNear(to: lastCoordinate) }) else { // Reached the end of the road - if road.intersections.contains(where: { $0.coordinate == lastCoordinate }) { + if road.intersections.contains(where: { $0.coordinate.isNear(to: lastCoordinate) }) { // Don't synthesize an intersection here since we already filtered this intersection out return nil } @@ -300,7 +300,7 @@ struct IntersectionFinder { // If so, reverse the direction of calculation // note: We want the first adjacent road coordinate to be the same as the last coordinate of the root road guard let lastAdjacentRoadCoordinate = nextRoadSegmentCoordinates.last else { return nil } - let reversedDirection = (rootCoordinate == lastAdjacentRoadCoordinate) + let reversedDirection = rootCoordinate.isNear(to: lastAdjacentRoadCoordinate) if let adjacentRoadClosestIntersection = closestIntersection(fromCoordinate: rootCoordinate, onRoad: nextRoadSegment, @@ -336,7 +336,7 @@ struct IntersectionFinder { } for (i, coordinate) in roadCoordinates.enumerated() { - if let intersection = intersections.first(where: { $0.coordinate == coordinate }) { + if let intersection = intersections.first(where: { $0.coordinate.isNear(to: coordinate) }) { let similarIntersectionWithMaxRoads = Intersection.similarIntersectionWithMaxRoads(intersection: intersection, intersections: intersections) return (similarIntersectionWithMaxRoads, i) } @@ -395,7 +395,7 @@ struct IntersectionFinder { } if IntersectionFinder.roadContainsCycle(road: nextRoadSegment, to: trailingCoordinates) { - if intersection.coordinate == self.rootCoordinate { + if intersection.coordinate.isNear(to: self.rootCoordinate) { // If the road loops back to the root coordinate, no need to return an intersection. return nil } else { @@ -412,7 +412,7 @@ struct IntersectionFinder { // If so, reverse the direction of calculation // note: We want the first adjacent road coordinate to be the same as the last coordinate of the root road guard let lastAdjacentRoadCoordinate = nextRoadSegmentCoordinates.last else { return nil } - let reversedDirection = (lastCoordinate == lastAdjacentRoadCoordinate) + let reversedDirection = lastCoordinate .isNear(to: lastAdjacentRoadCoordinate) return lastIntersection(fromCoordinate: lastCoordinate, onRoad: nextRoadSegment, @@ -429,7 +429,8 @@ struct IntersectionFinder { guard let roadCoordinates = road.coordinates else { return false } guard let lastCoordinate = coordinates.last else { return false } - if roadCoordinates.first == lastCoordinate && roadCoordinates.last == lastCoordinate { + if lastCoordinate.isNear(to: roadCoordinates.first) && + lastCoordinate.isNear(to: roadCoordinates.last) { // The road starts and ends at the same coordinate (loops back) return true } @@ -439,15 +440,17 @@ struct IntersectionFinder { var coordinatesExcludingRoot: [CLLocationCoordinate2D] // Because of road segments direction, we check if the root coordinate is the first or last. - if roadCoordinates.first == lastCoordinate { + if lastCoordinate.isNear(to: roadCoordinates.first) { coordinatesExcludingRoot = Array(roadCoordinates.dropFirst()) - } else if roadCoordinates.last == lastCoordinate { + } else if lastCoordinate.isNear(to: roadCoordinates.last) { coordinatesExcludingRoot = roadCoordinates.dropLast() } else { return false } - if coordinatesExcludingRoot.contains(where: { coordinates.contains($0) }) { + if coordinatesExcludingRoot.contains(where: {coordinate in + coordinates.contains(where: {coordinate.isNear(to: $0)}) + }) { return true } diff --git a/apps/ios/GuideDogs/Code/Data/Preview/RoadAdjacentDataView.swift b/apps/ios/GuideDogs/Code/Data/Preview/RoadAdjacentDataView.swift index ebd87e8f3..61f771692 100644 --- a/apps/ios/GuideDogs/Code/Data/Preview/RoadAdjacentDataView.swift +++ b/apps/ios/GuideDogs/Code/Data/Preview/RoadAdjacentDataView.swift @@ -11,7 +11,7 @@ import CoreLocation import CocoaLumberjackSwift import CoreGPX -struct RoadAdjacentDataView: AdjacentDataView, Equatable { +struct RoadAdjacentDataView: AdjacentDataView /*, fixme Equatable */ { typealias ReferenceEntityID = String @@ -413,3 +413,37 @@ extension RoadAdjacentDataView { } } + +// MARK: Equatable Conformance +// this emulates the old custom Equatable conformance extension on CLLocationCoordinate2D, which was not based on exact equality. +extension RoadAdjacentDataView: Equatable { + static func ==(lhs: RoadAdjacentDataView, rhs: RoadAdjacentDataView) -> Bool { + guard lhs.endpoint == rhs.endpoint, + lhs.direction == rhs.direction, + lhs.style == rhs.style, + lhs.adjacent == rhs.adjacent, + lhs.coordinatesToEndpoint.count + == rhs.coordinatesToEndpoint.count, + lhs.adjacentCalloutLocationsHistory.count + == rhs.adjacentCalloutLocationsHistory.count + else { + return false + } + + // 2) compare the two coordinate arrays element-wise + for (c1, c2) in zip(lhs.coordinatesToEndpoint, rhs.coordinatesToEndpoint) { + if !c1.isNear(to: c2) { return false } + } + + // 3) compare the dictionary of callout locations + for (key, loc1) in lhs.adjacentCalloutLocationsHistory { + guard let loc2 = rhs.adjacentCalloutLocationsHistory[key], + loc1.isNear(to: loc2) + else { + return false + } + } + + return true + } +} diff --git a/apps/ios/GuideDogs/Code/Data/Spatial Data/SpatialDataCache.swift b/apps/ios/GuideDogs/Code/Data/Spatial Data/SpatialDataCache.swift index a51d77e5d..b8bbf9602 100644 --- a/apps/ios/GuideDogs/Code/Data/Spatial Data/SpatialDataCache.swift +++ b/apps/ios/GuideDogs/Code/Data/Spatial Data/SpatialDataCache.swift @@ -346,7 +346,7 @@ class SpatialDataCache: NSObject { /// Returns all the intersections that connect to a given road static func intersection(forRoadKey roadKey: String, atCoordinate coordinate: CLLocationCoordinate2D) -> Intersection? { - return intersections(forRoadKey: roadKey)?.first(where: { $0.coordinate == coordinate }) + return intersections(forRoadKey: roadKey)?.first(where: { $0.coordinate.isNear(to: coordinate) }) } /// Returns all the intersections that connect to a given road, within a region. diff --git a/apps/ios/GuideDogs/Code/Visual UI/Controls/Beacon/BeaconTitleViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/Controls/Beacon/BeaconTitleViewController.swift index ff0899747..2c8101578 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Controls/Beacon/BeaconTitleViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Controls/Beacon/BeaconTitleViewController.swift @@ -97,7 +97,7 @@ class BeaconTitleViewController: UIViewController { // If the selected location on the underlying entity has changed, reconfigure the view // to show the new distance - let beaconCoordinateDidChange = newValue?.locationDetail.location.coordinate != oldValue?.locationDetail.location.coordinate + let beaconCoordinateDidChange = !(newValue?.locationDetail.location.coordinate.isNear(to: oldValue?.locationDetail.location.coordinate) ?? false) // If the underlying entity has changed, reconfigure the view and the view's accessibility // actions diff --git a/apps/ios/GuideDogs/Code/Visual UI/Helpers/Location/Location Detail/LocationDetail.swift b/apps/ios/GuideDogs/Code/Visual UI/Helpers/Location/Location Detail/LocationDetail.swift index 0d073505f..2eac0c155 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Helpers/Location/Location Detail/LocationDetail.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Helpers/Location/Location Detail/LocationDetail.swift @@ -82,21 +82,21 @@ struct LocationDetail { return false } - return lhsAt.coordinate == rhsAt.coordinate - + return lhsAt.coordinate.isNear(to: rhsAt.coordinate +) case let .designData(lhsAt, lhsAddress): guard case let .designData(rhsAt, rhsAddress) = rhs else { return false } - return lhsAt.coordinate == rhsAt.coordinate && lhsAddress == rhsAddress + return lhsAt.coordinate.isNear(to: rhsAt.coordinate) && lhsAddress == rhsAddress case let .screenshots(lhsPoi): guard case let .screenshots(rhsPoi) = rhs else { return false } - return lhsPoi.location.coordinate == rhsPoi.location.coordinate && lhsPoi.name == rhsPoi.name && lhsPoi.addressLine == rhsPoi.addressLine + return lhsPoi.location.coordinate.isNear(to: rhsPoi.location.coordinate) && lhsPoi.name == rhsPoi.name && lhsPoi.addressLine == rhsPoi.addressLine } } diff --git a/apps/ios/GuideDogs/Code/Visual UI/Observable Data Stores/BeaconDetailStore.swift b/apps/ios/GuideDogs/Code/Visual UI/Observable Data Stores/BeaconDetailStore.swift index 308088295..db95ca588 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Observable Data Stores/BeaconDetailStore.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/Observable Data Stores/BeaconDetailStore.swift @@ -176,7 +176,7 @@ class BeaconDetailStore: ObservableObject { let newValue = BeaconDetail.updateLocationDetailIfNeeded(for: oldValue) - guard newValue.locationDetail.source != oldValue.locationDetail.source || newValue.locationDetail.location.coordinate != oldValue.locationDetail.location.coordinate else { + guard newValue.locationDetail.source != oldValue.locationDetail.source || !newValue.locationDetail.location.coordinate.isNear(to: oldValue.locationDetail.location.coordinate) else { return } diff --git a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/Location Detail/EditableMapViewController.swift b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/Location Detail/EditableMapViewController.swift index 7538329e9..babbff2ff 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/Location Detail/EditableMapViewController.swift +++ b/apps/ios/GuideDogs/Code/Visual UI/View Controllers/POI Table/Location Detail/EditableMapViewController.swift @@ -123,7 +123,7 @@ class EditableMapViewController: UIViewController { // Selected location is at the center of the map let newLocation = CLLocation(mapView.centerCoordinate) - if newLocation.coordinate != detail.centerLocation.coordinate { + if !newLocation.coordinate.isNear(to: detail.centerLocation.coordinate) { // Notify the delegate delegate?.viewController(self, didUpdateLocation: LocationDetail(detail, withUpdatedLocation: newLocation)) } @@ -132,7 +132,7 @@ class EditableMapViewController: UIViewController { dismiss(animated: true, completion: nil) } else { // `Edit` selected - if detail.centerLocation.coordinate == mapView.centerCoordinate { + if detail.centerLocation.coordinate.isNear(to: mapView.centerCoordinate) { // Map region is centered at the given location // Immediately configure the view configureForEditLocation() diff --git a/apps/ios/GuideDogs/Code/Visual UI/Views/VoiceSettings.storyboard b/apps/ios/GuideDogs/Code/Visual UI/Views/VoiceSettings.storyboard index 45b451e41..fb0134a40 100644 --- a/apps/ios/GuideDogs/Code/Visual UI/Views/VoiceSettings.storyboard +++ b/apps/ios/GuideDogs/Code/Visual UI/Views/VoiceSettings.storyboard @@ -1,9 +1,9 @@ - + - + @@ -13,7 +13,7 @@ - + @@ -22,7 +22,7 @@ - + @@ -53,7 +53,7 @@ - + @@ -67,7 +67,7 @@ - + @@ -76,21 +76,21 @@ - + - +