Skip to content

Implement FixLocation.provider field based on CLLocationSourceInformation #3728

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

Merged
merged 1 commit into from
Feb 18, 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
17 changes: 15 additions & 2 deletions Sources/MapboxCoreNavigation/FixLocation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,26 @@ import CoreLocation
import Foundation
import MapboxNavigationNative

extension FixLocation {

extension FixLocation {
convenience init(_ location: CLLocation, isMock: Bool = false) {
var bearingAccuracy: NSNumber? = nil
if #available(iOS 13.4, *) {
bearingAccuracy = location.courseAccuracy >= 0 ? location.courseAccuracy as NSNumber : nil
}

var provider: String? = nil
#if compiler(>=5.5)
if #available(iOS 15.0, *) {
if let sourceInformation = location.sourceInformation {
// in some scenarios we store this information to history files, so to save space there, we use "short" names and 1/0 instead of true/false
let isSimulated = sourceInformation.isSimulatedBySoftware ? 1 : 0
let isProducedByAccessory = sourceInformation.isProducedByAccessory ? 1 : 0

provider = "sim:\(isSimulated),acc:\(isProducedByAccessory)"
Comment on lines +17 to +21
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps MapboxNavigationNative could be modified to accept something more structured like a dictionary instead of a freeform, user agent–like string, so that it can format and compress it as appropriate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we should add something iOS-specific - there is no analog of this structure on other platforms. Since this value will be used as kind of debug information I think it is okay to have it in this provider field in a free form. Btw initially I implemented it as a part of FixLocation.extras field, which allows to add any additional information to locations, but then decided that provider is exactly that field that was supposed to use for such use case(i.e. point to the source of location). WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant a JSON-like dictionary of strings, similar to that extras field. But if you’re sure we won’t ever need additional structure beyond this format, then we can go with this more opaque string.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we will need JSON here, I'd prefer to save bytes in history here rather than adding JSON overhead, because we likely need this data for debugging only.

}
}
#endif

self.init(coordinate: location.coordinate,
monotonicTimestampNanoseconds: Int64(location.timestamp.nanosecondsSince1970),
Expand All @@ -17,7 +30,7 @@ extension FixLocation {
bearing: location.course >= 0 ? location.course as NSNumber : nil,
altitude: location.altitude as NSNumber,
accuracyHorizontal: location.horizontalAccuracy >= 0 ? location.horizontalAccuracy as NSNumber : nil,
provider: nil,
provider: provider,
bearingAccuracy: bearingAccuracy,
speedAccuracy: location.speedAccuracy >= 0 ? location.speedAccuracy as NSNumber : nil,
verticalAccuracy: location.verticalAccuracy >= 0 ? location.verticalAccuracy as NSNumber : nil,
Expand Down
25 changes: 24 additions & 1 deletion Tests/MapboxCoreNavigationTests/CLLocationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,25 @@ class CLLocationTests: TestCase {
speedAccuracy: speedAccuracy,
timestamp: timestamp)
}

#if compiler(>=5.5)
if #available(iOS 15.0, *) {
let sourceInfo = CLLocationSourceInformation(
softwareSimulationState: true,
andExternalAccessoryState: false
)
Comment on lines +96 to +100
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Despite this #available macro, iOS 14.5 tests are failing on CI because Xcode 12.5.1 ships with an older iOS development SDK that doesn’t recognize this type yet:

    /Applications/Xcode-12.5.1.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-frontend -frontend -c -primary-file /Users/distiller/project/Tests/MapboxCoreNavigationTests/CLLocationTests.swift /Users/distiller/project/Tests/MapboxCoreNavigationTests/NavigationEventsManagerTests.swift /Users/distiller/project/Tests/MapboxCoreNavigationTests/MapboxCoreNavigationTests.swift /Users/distiller/project/Tests/MapboxCoreNavigationTests/UnimplementedLoggingTests.swift /Users/distiller/project/Tests/MapboxCoreNavigationTests/DateTests.swift /Users/distiller/project/Tests/MapboxCoreNavigationTests/NavigationLocationManagerTests.swift /Users/distiller/project/Tests/MapboxCoreNavigationTests/ReplayLocationManagerTests.swift /Users/distiller/project/Tests/MapboxCoreNavigationTests/TilesetDescriptorFactoryTests.swift /Users/distiller/project/Tests/MapboxCoreNavigationTests/DistanceFormatterTests.swift /Users/distiller/project/Tests/MapboxCoreNavigationTests/RouteProgressTests.swift /Users/distiller/project/Tests/MapboxCoreNavigationTests/PassiveLocationManagerTests.swift /Users/distiller/project/Tests/MapboxCoreNavigationTests/LocationTests.swift /Users/distiller/project/Tests/MapboxCoreNavigationTests/BillingHandlerTests.swift /Users/distiller/project/Tests/MapboxCoreNavigationTests/StringTests.swift /Users/distiller/project/Tests/MapboxCoreNavigationTests/RouteControllerTests.swift /Users/distiller/project/Tests/MapboxCoreNavigationTests/OptionsTests.swift /Users/distiller/project/Tests/MapboxCoreNavigationTests/Extensions/RouteOptionsTests.swift /Users/distiller/project/Tests/MapboxCoreNavigationTests/BundleAdditionsTests.swift /Users/distiller/project/Tests/MapboxCoreNavigationTests/LeakTests.swift /Users/distiller/project/Tests/MapboxCoreNavigationTests/SimulatedLocationManagerTests.swift /Users/distiller/project/Tests/MapboxCoreNavigationTests/TunnelAuthorityTests.swift /Users/distiller/project/Tests/MapboxCoreNavigationTests/Extensions/RouteStateTests.swift /Users/distiller/project/Tests/MapboxCoreNavigationTests/NavigationServiceTests.swift /Users/distiller/project/Tests/MapboxCoreNavigationTests/NativeHandlersFactoryTests.swift -emit-module-path /Users/distiller/Library/Developer/Xcode/DerivedData/MapboxNavigation-gtrukiuwvhbmctfcsthejciepfao/Build/Intermediates.noindex/MapboxNavigation.build/Debug-iphonesimulator/MapboxCoreNavigationTests.build/Objects-normal/x86_64/CLLocationTests\~partial.swiftmodule -emit-module-doc-path /Users/distiller/Library/Developer/Xcode/DerivedData/MapboxNavigation-gtrukiuwvhbmctfcsthejciepfao/Build/Intermediates.noindex/MapboxNavigation.build/Debug-iphonesimulator/MapboxCoreNavigationTests.build/Objects-normal/x86_64/CLLocationTests\~partial.swiftdoc -emit-module-source-info-path /Users/distiller/Library/Developer/Xcode/DerivedData/MapboxNavigation-gtrukiuwvhbmctfcsthejciepfao/Build/Intermediates.noindex/MapboxNavigation.build/Debug-iphonesimulator/MapboxCoreNavigationTests.build/Objects-normal/x86_64/CLLocationTests\~partial.swiftsourceinfo -serialize-diagnostics-path /Users/distiller/Library/Developer/Xcode/DerivedData/MapboxNavigation-gtrukiuwvhbmctfcsthejciepfao/Build/Intermediates.noindex/MapboxNavigation.build/Debug-iphonesimulator/MapboxCoreNavigationTests.build/Objects-normal/x86_64/CLLocationTests.dia -emit-dependencies-path /Users/distiller/Library/Developer/Xcode/DerivedData/MapboxNavigation-gtrukiuwvhbmctfcsthejciepfao/Build/Intermediates.noindex/MapboxNavigation.build/Debug-iphonesimulator/MapboxCoreNavigationTests.build/Objects-normal/x86_64/CLLocationTests.d -emit-reference-dependencies-path /Users/distiller/Library/Developer/Xcode/DerivedData/MapboxNavigation-gtrukiuwvhbmctfcsthejciepfao/Build/Intermediates.noindex/MapboxNavigation.build/Debug-iphonesimulator/MapboxCoreNavigationTests.build/Objects-normal/x86_64/CLLocationTests.swiftdeps -target x86_64-apple-ios11.0-simulator -enable-objc-interop -sdk /Applications/Xcode-12.5.1.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator14.5.sdk -I /Users/distiller/Library/Developer/Xcode/DerivedData/MapboxNavigation-gtrukiuwvhbmctfcsthejciepfao/Build/Products/Debug-iphonesimulator -I /Applications/Xcode-12.5.1.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/lib -F /Users/distiller/Library/Developer/Xcode/DerivedData/MapboxNavigation-gtrukiuwvhbmctfcsthejciepfao/Build/Products/Debug-iphonesimulator -F /Applications/Xcode-12.5.1.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks -F /Applications/Xcode-12.5.1.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator14.5.sdk/Developer/Library/Frameworks -enable-testing -g -module-cache-path /Users/distiller/Library/Developer/Xcode/DerivedData/ModuleCache.noindex -swift-version 5 -enforce-exclusivity\=checked -Onone -D DEBUG -serialize-debugging-options -serialize-debugging-options -Xcc -working-directory -Xcc /Users/distiller/project -enable-anonymous-context-mangled-names -Xcc -I/Users/distiller/Library/Developer/Xcode/DerivedData/MapboxNavigation-gtrukiuwvhbmctfcsthejciepfao/Build/Intermediates.noindex/MapboxNavigation.build/Debug-iphonesimulator/MapboxCoreNavigationTests.build/swift-overrides.hmap -Xcc -iquote -Xcc /Users/distiller/Library/Developer/Xcode/DerivedData/MapboxNavigation-gtrukiuwvhbmctfcsthejciepfao/Build/Intermediates.noindex/MapboxNavigation.build/Debug-iphonesimulator/MapboxCoreNavigationTests.build/MapboxCoreNavigationTests-generated-files.hmap -Xcc -I/Users/distiller/Library/Developer/Xcode/DerivedData/MapboxNavigation-gtrukiuwvhbmctfcsthejciepfao/Build/Intermediates.noindex/MapboxNavigation.build/Debug-iphonesimulator/MapboxCoreNavigationTests.build/MapboxCoreNavigationTests-own-target-headers.hmap -Xcc -I/Users/distiller/Library/Developer/Xcode/DerivedData/MapboxNavigation-gtrukiuwvhbmctfcsthejciepfao/Build/Intermediates.noindex/MapboxNavigation.build/Debug-iphonesimulator/MapboxCoreNavigationTests.build/MapboxCoreNavigationTests-all-non-framework-target-headers.hmap -Xcc -ivfsoverlay -Xcc /Users/distiller/Library/Developer/Xcode/DerivedData/MapboxNavigation-gtrukiuwvhbmctfcsthejciepfao/Build/Intermediates.noindex/MapboxNavigation.build/Debug-iphonesimulator/MapboxCoreNavigationTests.build/all-product-headers.yaml -Xcc -iquote -Xcc /Users/distiller/Library/Developer/Xcode/DerivedData/MapboxNavigation-gtrukiuwvhbmctfcsthejciepfao/Build/Intermediates.noindex/MapboxNavigation.build/Debug-iphonesimulator/MapboxCoreNavigationTests.build/MapboxCoreNavigationTests-project-headers.hmap -Xcc -I/Users/distiller/Library/Developer/Xcode/DerivedData/MapboxNavigation-gtrukiuwvhbmctfcsthejciepfao/Build/Products/Debug-iphonesimulator/include -Xcc -I/Users/distiller/Library/Developer/Xcode/DerivedData/MapboxNavigation-gtrukiuwvhbmctfcsthejciepfao/Build/Intermediates.noindex/MapboxNavigation.build/Debug-iphonesimulator/MapboxCoreNavigationTests.build/DerivedSources-normal/x86_64 -Xcc -I/Users/distiller/Library/Developer/Xcode/DerivedData/MapboxNavigation-gtrukiuwvhbmctfcsthejciepfao/Build/Intermediates.noindex/MapboxNavigation.build/Debug-iphonesimulator/MapboxCoreNavigationTests.build/DerivedSources/x86_64 -Xcc -I/Users/distiller/Library/Developer/Xcode/DerivedData/MapboxNavigation-gtrukiuwvhbmctfcsthejciepfao/Build/Intermediates.noindex/MapboxNavigation.build/Debug-iphonesimulator/MapboxCoreNavigationTests.build/DerivedSources -Xcc -DDEBUG\=1 -target-sdk-version 14.5 -import-objc-header /Users/distiller/project/Tests/MapboxCoreNavigationTests/MapboxCoreNavigationTests-Bridging-Header.h -pch-output-dir /Users/distiller/Library/Developer/Xcode/DerivedData/MapboxNavigation-gtrukiuwvhbmctfcsthejciepfao/Build/Intermediates.noindex/PrecompiledHeaders -pch-disable-validation -module-name MapboxCoreNavigationTests -o /Users/distiller/Library/Developer/Xcode/DerivedData/MapboxNavigation-gtrukiuwvhbmctfcsthejciepfao/Build/Intermediates.noindex/MapboxNavigation.build/Debug-iphonesimulator/MapboxCoreNavigationTests.build/Objects-normal/x86_64/CLLocationTests.o -index-store-path /Users/distiller/Library/Developer/Xcode/DerivedData/MapboxNavigation-gtrukiuwvhbmctfcsthejciepfao/Index/DataStore -index-system-modules
/Users/distiller/project/Tests/MapboxCoreNavigationTests/CLLocationTests.swift:97:30: error: cannot find 'CLLocationSourceInformation' in scope
            let sourceInfo = CLLocationSourceInformation(
                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/distiller/project/Tests/MapboxCoreNavigationTests/CLLocationTests.swift:110:47: error: extra argument 'sourceInfo' in call
                                  sourceInfo: sourceInfo)
                                              ^~~~~~~~~~

#available is evaluated at runtime. Wrap this block in an #if compiler(…) block to prevent older Xcodes from seeing it when compiling.

location = CLLocation(coordinate: coordinate,
altitude: altitude,
horizontalAccuracy: horizontalAccuracy,
verticalAccuracy: verticalAccuracy,
course: bearing,
courseAccuracy: bearingAccuracy,
speed: speed,
speedAccuracy: speedAccuracy,
timestamp: timestamp,
sourceInfo: sourceInfo)
}
#endif

let fixLocation = FixLocation(location)

XCTAssertEqual(fixLocation.coordinate.latitude, coordinate.latitude)
Expand All @@ -108,6 +126,11 @@ class CLLocationTests: TestCase {
XCTAssertEqual(fixLocation.bearingAccuracy?.doubleValue, bearingAccuracy)
XCTAssertEqual(fixLocation.speedAccuracy?.doubleValue, speedAccuracy)
}
#if compiler(>=5.5)
if #available(iOS 15.0, *) {
XCTAssertEqual(fixLocation.provider, "sim:1,acc:0")
}
#endif
}
}