From b05c680d62a38ae0020a1293eae36f03112d44b6 Mon Sep 17 00:00:00 2001 From: Joel Carter Date: Fri, 22 Nov 2024 08:50:01 -0600 Subject: [PATCH 01/12] System Location Payload --- .../Location/{ => System}/LocationCoordinatePayloadStruct.swift | 0 .../Location/{ => System}/LocationFloorPayloadStruct.swift | 0 .../XyoClient/Witness/Location/{ => System}/LocationPayload.swift | 0 .../{ => System}/LocationSourceInformationPayloadStruct.swift | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename Sources/XyoClient/Witness/Location/{ => System}/LocationCoordinatePayloadStruct.swift (100%) rename Sources/XyoClient/Witness/Location/{ => System}/LocationFloorPayloadStruct.swift (100%) rename Sources/XyoClient/Witness/Location/{ => System}/LocationPayload.swift (100%) rename Sources/XyoClient/Witness/Location/{ => System}/LocationSourceInformationPayloadStruct.swift (100%) diff --git a/Sources/XyoClient/Witness/Location/LocationCoordinatePayloadStruct.swift b/Sources/XyoClient/Witness/Location/System/LocationCoordinatePayloadStruct.swift similarity index 100% rename from Sources/XyoClient/Witness/Location/LocationCoordinatePayloadStruct.swift rename to Sources/XyoClient/Witness/Location/System/LocationCoordinatePayloadStruct.swift diff --git a/Sources/XyoClient/Witness/Location/LocationFloorPayloadStruct.swift b/Sources/XyoClient/Witness/Location/System/LocationFloorPayloadStruct.swift similarity index 100% rename from Sources/XyoClient/Witness/Location/LocationFloorPayloadStruct.swift rename to Sources/XyoClient/Witness/Location/System/LocationFloorPayloadStruct.swift diff --git a/Sources/XyoClient/Witness/Location/LocationPayload.swift b/Sources/XyoClient/Witness/Location/System/LocationPayload.swift similarity index 100% rename from Sources/XyoClient/Witness/Location/LocationPayload.swift rename to Sources/XyoClient/Witness/Location/System/LocationPayload.swift diff --git a/Sources/XyoClient/Witness/Location/LocationSourceInformationPayloadStruct.swift b/Sources/XyoClient/Witness/Location/System/LocationSourceInformationPayloadStruct.swift similarity index 100% rename from Sources/XyoClient/Witness/Location/LocationSourceInformationPayloadStruct.swift rename to Sources/XyoClient/Witness/Location/System/LocationSourceInformationPayloadStruct.swift From 82024190664a70f66a3a43c6cdeaf932a7260d74 Mon Sep 17 00:00:00 2001 From: Joel Carter Date: Fri, 22 Nov 2024 08:52:23 -0600 Subject: [PATCH 02/12] Namespace iOS Location Payloads --- Sources/XyoClient/Witness/Location/LocationWitness.swift | 2 +- .../IosLocationCoordinatePayloadStruct.swift} | 2 +- .../IosLocationFloorPayloadStruct.swift} | 2 +- .../IosLocationPayload.swift} | 8 ++++---- .../IosLocationSourceInformationPayloadStruct.swift} | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) rename Sources/XyoClient/Witness/Location/{System/LocationCoordinatePayloadStruct.swift => iOS/IosLocationCoordinatePayloadStruct.swift} (90%) rename Sources/XyoClient/Witness/Location/{System/LocationFloorPayloadStruct.swift => iOS/IosLocationFloorPayloadStruct.swift} (88%) rename Sources/XyoClient/Witness/Location/{System/LocationPayload.swift => iOS/IosLocationPayload.swift} (87%) rename Sources/XyoClient/Witness/Location/{System/LocationSourceInformationPayloadStruct.swift => iOS/IosLocationSourceInformationPayloadStruct.swift} (92%) diff --git a/Sources/XyoClient/Witness/Location/LocationWitness.swift b/Sources/XyoClient/Witness/Location/LocationWitness.swift index 6bd4584..8e212e6 100644 --- a/Sources/XyoClient/Witness/Location/LocationWitness.swift +++ b/Sources/XyoClient/Witness/Location/LocationWitness.swift @@ -10,7 +10,7 @@ open class LocationWitness: WitnessModuleAsync { DispatchQueue.main.async { switch result { case .success(let location): - let payload = LocationPayload(location) + let payload = IosLocationPayload(location) completion([payload], nil) case .failure(let error): completion(nil, error) diff --git a/Sources/XyoClient/Witness/Location/System/LocationCoordinatePayloadStruct.swift b/Sources/XyoClient/Witness/Location/iOS/IosLocationCoordinatePayloadStruct.swift similarity index 90% rename from Sources/XyoClient/Witness/Location/System/LocationCoordinatePayloadStruct.swift rename to Sources/XyoClient/Witness/Location/iOS/IosLocationCoordinatePayloadStruct.swift index e1d8e54..c828828 100644 --- a/Sources/XyoClient/Witness/Location/System/LocationCoordinatePayloadStruct.swift +++ b/Sources/XyoClient/Witness/Location/iOS/IosLocationCoordinatePayloadStruct.swift @@ -1,7 +1,7 @@ import CoreLocation import Foundation -struct LocationCoordinatePayloadStruct: Encodable { +struct IosLocationCoordinatePayloadStruct: Encodable { var coordinate: CLLocationCoordinate2D diff --git a/Sources/XyoClient/Witness/Location/System/LocationFloorPayloadStruct.swift b/Sources/XyoClient/Witness/Location/iOS/IosLocationFloorPayloadStruct.swift similarity index 88% rename from Sources/XyoClient/Witness/Location/System/LocationFloorPayloadStruct.swift rename to Sources/XyoClient/Witness/Location/iOS/IosLocationFloorPayloadStruct.swift index 19aee5a..9b21a99 100644 --- a/Sources/XyoClient/Witness/Location/System/LocationFloorPayloadStruct.swift +++ b/Sources/XyoClient/Witness/Location/iOS/IosLocationFloorPayloadStruct.swift @@ -1,7 +1,7 @@ import CoreLocation import Foundation -struct LocationFloorPayloadStruct: Encodable { +struct IosLocationFloorPayloadStruct: Encodable { var floor: CLFloor diff --git a/Sources/XyoClient/Witness/Location/System/LocationPayload.swift b/Sources/XyoClient/Witness/Location/iOS/IosLocationPayload.swift similarity index 87% rename from Sources/XyoClient/Witness/Location/System/LocationPayload.swift rename to Sources/XyoClient/Witness/Location/iOS/IosLocationPayload.swift index 223d281..5b1134c 100644 --- a/Sources/XyoClient/Witness/Location/System/LocationPayload.swift +++ b/Sources/XyoClient/Witness/Location/iOS/IosLocationPayload.swift @@ -1,6 +1,6 @@ import CoreLocation -open class LocationPayload: Payload { +open class IosLocationPayload: Payload { var location: CLLocation @@ -31,7 +31,7 @@ open class LocationPayload: Payload { try container.encode(self.location.altitude, forKey: .altitude) try container.encode( - LocationCoordinatePayloadStruct(self.location.coordinate), forKey: .coordinate) + IosLocationCoordinatePayloadStruct(self.location.coordinate), forKey: .coordinate) try container.encode(self.location.course, forKey: .course) if #available(iOS 13.4, *) { try container.encode(self.location.courseAccuracy, forKey: .courseAccuracy) @@ -41,13 +41,13 @@ open class LocationPayload: Payload { } if let floor = self.location.floor { try container.encode( - LocationFloorPayloadStruct(floor), forKey: .floor) + IosLocationFloorPayloadStruct(floor), forKey: .floor) } try container.encode(self.location.horizontalAccuracy, forKey: .horizontalAccuracy) if #available(iOS 15.0, *) { if let sourceInformation = self.location.sourceInformation { try container.encode( - LocationSourceInformationPayloadStruct(sourceInformation), + IosLocationSourceInformationPayloadStruct(sourceInformation), forKey: .sourceInformation) } } diff --git a/Sources/XyoClient/Witness/Location/System/LocationSourceInformationPayloadStruct.swift b/Sources/XyoClient/Witness/Location/iOS/IosLocationSourceInformationPayloadStruct.swift similarity index 92% rename from Sources/XyoClient/Witness/Location/System/LocationSourceInformationPayloadStruct.swift rename to Sources/XyoClient/Witness/Location/iOS/IosLocationSourceInformationPayloadStruct.swift index 0d4af13..ec4c604 100644 --- a/Sources/XyoClient/Witness/Location/System/LocationSourceInformationPayloadStruct.swift +++ b/Sources/XyoClient/Witness/Location/iOS/IosLocationSourceInformationPayloadStruct.swift @@ -2,7 +2,7 @@ import CoreLocation import Foundation @available(iOS 15.0, *) -struct LocationSourceInformationPayloadStruct: Encodable { +struct IosLocationSourceInformationPayloadStruct: Encodable { var sourceInformation: CLLocationSourceInformation From bf54fbf2fb98dad1e6b26efde2ea7632212ed882 Mon Sep 17 00:00:00 2001 From: Joel Carter Date: Fri, 22 Nov 2024 08:55:33 -0600 Subject: [PATCH 03/12] Generic location payload --- .../LocationCoordinatePayloadStruct.swift | 23 +++++++ .../Generic/LocationFloorPayloadStruct.swift | 21 +++++++ .../Location/Generic/LocationPayload.swift | 61 +++++++++++++++++++ ...cationSourceInformationPayloadStruct.swift | 26 ++++++++ 4 files changed, 131 insertions(+) create mode 100644 Sources/XyoClient/Witness/Location/Generic/LocationCoordinatePayloadStruct.swift create mode 100644 Sources/XyoClient/Witness/Location/Generic/LocationFloorPayloadStruct.swift create mode 100644 Sources/XyoClient/Witness/Location/Generic/LocationPayload.swift create mode 100644 Sources/XyoClient/Witness/Location/Generic/LocationSourceInformationPayloadStruct.swift diff --git a/Sources/XyoClient/Witness/Location/Generic/LocationCoordinatePayloadStruct.swift b/Sources/XyoClient/Witness/Location/Generic/LocationCoordinatePayloadStruct.swift new file mode 100644 index 0000000..e1d8e54 --- /dev/null +++ b/Sources/XyoClient/Witness/Location/Generic/LocationCoordinatePayloadStruct.swift @@ -0,0 +1,23 @@ +import CoreLocation +import Foundation + +struct LocationCoordinatePayloadStruct: Encodable { + + var coordinate: CLLocationCoordinate2D + + init(_ coordinate: CLLocationCoordinate2D) { + self.coordinate = coordinate + } + + enum CodingKeys: String, CodingKey { + case latitude + case longitude + } + + func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + + try container.encode(self.coordinate.latitude, forKey: .latitude) + try container.encode(self.coordinate.longitude, forKey: .longitude) + } +} diff --git a/Sources/XyoClient/Witness/Location/Generic/LocationFloorPayloadStruct.swift b/Sources/XyoClient/Witness/Location/Generic/LocationFloorPayloadStruct.swift new file mode 100644 index 0000000..19aee5a --- /dev/null +++ b/Sources/XyoClient/Witness/Location/Generic/LocationFloorPayloadStruct.swift @@ -0,0 +1,21 @@ +import CoreLocation +import Foundation + +struct LocationFloorPayloadStruct: Encodable { + + var floor: CLFloor + + init(_ floor: CLFloor) { + self.floor = floor + } + + enum CodingKeys: String, CodingKey { + case level + } + + func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + + try container.encode(self.floor.level, forKey: .level) + } +} diff --git a/Sources/XyoClient/Witness/Location/Generic/LocationPayload.swift b/Sources/XyoClient/Witness/Location/Generic/LocationPayload.swift new file mode 100644 index 0000000..345667c --- /dev/null +++ b/Sources/XyoClient/Witness/Location/Generic/LocationPayload.swift @@ -0,0 +1,61 @@ +import CoreLocation + +open class LocationPayload: Payload { + + var location: CLLocation + + public init(_ location: CLLocation) { + self.location = location + super.init("network.xyo.location") + } + + enum CodingKeys: String, CodingKey { + case altitude + case coordinate + case course + case courseAccuracy + case ellipsoidalAltitude + case floor + case horizontalAccuracy + case schema + case sourceInformation + case speed + case speedAccuracy + case timestamp + case verticalAccuracy + } + + override open func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(self.schema, forKey: .schema) + + try container.encode(self.location.altitude, forKey: .altitude) + try container.encode( + IosLocationCoordinatePayloadStruct(self.location.coordinate), forKey: .coordinate) + try container.encode(self.location.course, forKey: .course) + if #available(iOS 13.4, *) { + try container.encode(self.location.courseAccuracy, forKey: .courseAccuracy) + } + if #available(iOS 15, *) { + try container.encode(self.location.ellipsoidalAltitude, forKey: .ellipsoidalAltitude) + } + if let floor = self.location.floor { + try container.encode( + IosLocationFloorPayloadStruct(floor), forKey: .floor) + } + try container.encode(self.location.horizontalAccuracy, forKey: .horizontalAccuracy) + if #available(iOS 15.0, *) { + if let sourceInformation = self.location.sourceInformation { + try container.encode( + IosLocationSourceInformationPayloadStruct(sourceInformation), + forKey: .sourceInformation) + } + } + try container.encode(self.location.speed, forKey: .speed) + try container.encode(self.location.speedAccuracy, forKey: .speedAccuracy) + try container.encode( + Int(self.location.timestamp.timeIntervalSince1970 * 1000), forKey: .timestamp) + try container.encode(self.location.verticalAccuracy, forKey: .verticalAccuracy) + + } +} diff --git a/Sources/XyoClient/Witness/Location/Generic/LocationSourceInformationPayloadStruct.swift b/Sources/XyoClient/Witness/Location/Generic/LocationSourceInformationPayloadStruct.swift new file mode 100644 index 0000000..0d4af13 --- /dev/null +++ b/Sources/XyoClient/Witness/Location/Generic/LocationSourceInformationPayloadStruct.swift @@ -0,0 +1,26 @@ +import CoreLocation +import Foundation + +@available(iOS 15.0, *) +struct LocationSourceInformationPayloadStruct: Encodable { + + var sourceInformation: CLLocationSourceInformation + + init(_ sourceInformation: CLLocationSourceInformation) { + self.sourceInformation = sourceInformation + } + + enum CodingKeys: String, CodingKey { + case isProducedByAccessory + case isSimulatedBySoftware + } + + func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + + try container.encode( + self.sourceInformation.isProducedByAccessory, forKey: .isProducedByAccessory) + try container.encode( + self.sourceInformation.isSimulatedBySoftware, forKey: .isSimulatedBySoftware) + } +} From 76cadbec59bd0df33f868c259dc91cd02ac925ba Mon Sep 17 00:00:00 2001 From: Joel Carter Date: Fri, 22 Nov 2024 09:10:53 -0600 Subject: [PATCH 04/12] Generic location payload --- .../Location/Generic/Coordinates.swift | 53 +++++++++++++++++++ .../Location/Generic/CurrentLocation.swift | 28 ++++++++++ .../LocationCoordinatePayloadStruct.swift | 23 -------- .../Generic/LocationFloorPayloadStruct.swift | 21 -------- ...cationSourceInformationPayloadStruct.swift | 26 --------- 5 files changed, 81 insertions(+), 70 deletions(-) create mode 100644 Sources/XyoClient/Witness/Location/Generic/Coordinates.swift create mode 100644 Sources/XyoClient/Witness/Location/Generic/CurrentLocation.swift delete mode 100644 Sources/XyoClient/Witness/Location/Generic/LocationCoordinatePayloadStruct.swift delete mode 100644 Sources/XyoClient/Witness/Location/Generic/LocationFloorPayloadStruct.swift delete mode 100644 Sources/XyoClient/Witness/Location/Generic/LocationSourceInformationPayloadStruct.swift diff --git a/Sources/XyoClient/Witness/Location/Generic/Coordinates.swift b/Sources/XyoClient/Witness/Location/Generic/Coordinates.swift new file mode 100644 index 0000000..fe2f17e --- /dev/null +++ b/Sources/XyoClient/Witness/Location/Generic/Coordinates.swift @@ -0,0 +1,53 @@ +import CoreLocation +import Foundation + +struct CoordinatesStruct: Encodable { + + var accuracy: Double? + var altitude: Double? + var altitudeAccuracy: Double? + var heading: Double? + var latitude: Double + var longitude: Double + var speed: Double? + + init( + accuracy: Double?, + altitude: Double?, + altitudeAccuracy: Double?, + heading: Double?, + latitude: Double, + longitude: Double, + speed: Double? + ) { + self.accuracy = accuracy + self.altitude = altitude + self.altitudeAccuracy = altitudeAccuracy + self.heading = heading + self.latitude = latitude + self.longitude = longitude + self.speed = speed + } + + enum CodingKeys: String, CodingKey { + case accuracy + case altitude + case altitudeAccuracy + case heading + case latitude + case longitude + case speed + } + + func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + + try container.encode(self.accuracy, forKey: .accuracy) + try container.encode(self.altitude, forKey: .altitude) + try container.encode(self.altitudeAccuracy, forKey: .altitudeAccuracy) + try container.encode(self.heading, forKey: .heading) + try container.encode(self.latitude, forKey: .latitude) + try container.encode(self.longitude, forKey: .longitude) + try container.encode(self.speed, forKey: .speed) + } +} diff --git a/Sources/XyoClient/Witness/Location/Generic/CurrentLocation.swift b/Sources/XyoClient/Witness/Location/Generic/CurrentLocation.swift new file mode 100644 index 0000000..626e9a0 --- /dev/null +++ b/Sources/XyoClient/Witness/Location/Generic/CurrentLocation.swift @@ -0,0 +1,28 @@ +import CoreLocation +import Foundation + +struct CurrentLocationStruct: Encodable { + + var coords: CoordinatesStruct + var timestamp: Date + + init( + coords: CoordinatesStruct, + timestamp: Date + ) { + self.coords = coords + self.timestamp = timestamp + } + + enum CodingKeys: String, CodingKey { + case coords + case timestamp + } + + func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + + try container.encode(self.coords, forKey: .coords) + try container.encode(Int(self.timestamp.timeIntervalSince1970 * 1000), forKey: .timestamp) + } +} diff --git a/Sources/XyoClient/Witness/Location/Generic/LocationCoordinatePayloadStruct.swift b/Sources/XyoClient/Witness/Location/Generic/LocationCoordinatePayloadStruct.swift deleted file mode 100644 index e1d8e54..0000000 --- a/Sources/XyoClient/Witness/Location/Generic/LocationCoordinatePayloadStruct.swift +++ /dev/null @@ -1,23 +0,0 @@ -import CoreLocation -import Foundation - -struct LocationCoordinatePayloadStruct: Encodable { - - var coordinate: CLLocationCoordinate2D - - init(_ coordinate: CLLocationCoordinate2D) { - self.coordinate = coordinate - } - - enum CodingKeys: String, CodingKey { - case latitude - case longitude - } - - func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - - try container.encode(self.coordinate.latitude, forKey: .latitude) - try container.encode(self.coordinate.longitude, forKey: .longitude) - } -} diff --git a/Sources/XyoClient/Witness/Location/Generic/LocationFloorPayloadStruct.swift b/Sources/XyoClient/Witness/Location/Generic/LocationFloorPayloadStruct.swift deleted file mode 100644 index 19aee5a..0000000 --- a/Sources/XyoClient/Witness/Location/Generic/LocationFloorPayloadStruct.swift +++ /dev/null @@ -1,21 +0,0 @@ -import CoreLocation -import Foundation - -struct LocationFloorPayloadStruct: Encodable { - - var floor: CLFloor - - init(_ floor: CLFloor) { - self.floor = floor - } - - enum CodingKeys: String, CodingKey { - case level - } - - func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - - try container.encode(self.floor.level, forKey: .level) - } -} diff --git a/Sources/XyoClient/Witness/Location/Generic/LocationSourceInformationPayloadStruct.swift b/Sources/XyoClient/Witness/Location/Generic/LocationSourceInformationPayloadStruct.swift deleted file mode 100644 index 0d4af13..0000000 --- a/Sources/XyoClient/Witness/Location/Generic/LocationSourceInformationPayloadStruct.swift +++ /dev/null @@ -1,26 +0,0 @@ -import CoreLocation -import Foundation - -@available(iOS 15.0, *) -struct LocationSourceInformationPayloadStruct: Encodable { - - var sourceInformation: CLLocationSourceInformation - - init(_ sourceInformation: CLLocationSourceInformation) { - self.sourceInformation = sourceInformation - } - - enum CodingKeys: String, CodingKey { - case isProducedByAccessory - case isSimulatedBySoftware - } - - func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - - try container.encode( - self.sourceInformation.isProducedByAccessory, forKey: .isProducedByAccessory) - try container.encode( - self.sourceInformation.isSimulatedBySoftware, forKey: .isSimulatedBySoftware) - } -} From 47e0d87b2a8e64d44b93803d568f1d14e7bb3878 Mon Sep 17 00:00:00 2001 From: Joel Carter Date: Fri, 22 Nov 2024 11:35:36 -0600 Subject: [PATCH 05/12] Serializable location payload --- .../Location/Generic/LocationPayload.swift | 55 +++++-------------- 1 file changed, 14 insertions(+), 41 deletions(-) diff --git a/Sources/XyoClient/Witness/Location/Generic/LocationPayload.swift b/Sources/XyoClient/Witness/Location/Generic/LocationPayload.swift index 345667c..03287dc 100644 --- a/Sources/XyoClient/Witness/Location/Generic/LocationPayload.swift +++ b/Sources/XyoClient/Witness/Location/Generic/LocationPayload.swift @@ -10,52 +10,25 @@ open class LocationPayload: Payload { } enum CodingKeys: String, CodingKey { - case altitude - case coordinate - case course - case courseAccuracy - case ellipsoidalAltitude - case floor - case horizontalAccuracy + case currentLocation case schema - case sourceInformation - case speed - case speedAccuracy - case timestamp - case verticalAccuracy } override open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(self.schema, forKey: .schema) - - try container.encode(self.location.altitude, forKey: .altitude) - try container.encode( - IosLocationCoordinatePayloadStruct(self.location.coordinate), forKey: .coordinate) - try container.encode(self.location.course, forKey: .course) - if #available(iOS 13.4, *) { - try container.encode(self.location.courseAccuracy, forKey: .courseAccuracy) - } - if #available(iOS 15, *) { - try container.encode(self.location.ellipsoidalAltitude, forKey: .ellipsoidalAltitude) - } - if let floor = self.location.floor { - try container.encode( - IosLocationFloorPayloadStruct(floor), forKey: .floor) - } - try container.encode(self.location.horizontalAccuracy, forKey: .horizontalAccuracy) - if #available(iOS 15.0, *) { - if let sourceInformation = self.location.sourceInformation { - try container.encode( - IosLocationSourceInformationPayloadStruct(sourceInformation), - forKey: .sourceInformation) - } - } - try container.encode(self.location.speed, forKey: .speed) - try container.encode(self.location.speedAccuracy, forKey: .speedAccuracy) - try container.encode( - Int(self.location.timestamp.timeIntervalSince1970 * 1000), forKey: .timestamp) - try container.encode(self.location.verticalAccuracy, forKey: .verticalAccuracy) - + + let coords: CoordinatesStruct = CoordinatesStruct( + accuracy: self.location.horizontalAccuracy, + altitude: self.location.altitude, + altitudeAccuracy: self.location.altitude, + heading: self.location.course, + latitude: self.location.coordinate.latitude, + longitude: self.location.coordinate.longitude, + speed: self.location.speed + ) + let timestamp = self.location.timestamp + let currentLocation: CurrentLocationStruct = CurrentLocationStruct(coords: coords, timestamp: timestamp) + try container.encode(currentLocation, forKey: .currentLocation) } } From 49aa46a37483c1cb3400d976aa7469ef871663d5 Mon Sep 17 00:00:00 2001 From: Joel Carter Date: Fri, 22 Nov 2024 11:37:02 -0600 Subject: [PATCH 06/12] Generate device-specific and generic location payload --- Sources/XyoClient/Witness/Location/LocationWitness.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Sources/XyoClient/Witness/Location/LocationWitness.swift b/Sources/XyoClient/Witness/Location/LocationWitness.swift index 8e212e6..8702ab9 100644 --- a/Sources/XyoClient/Witness/Location/LocationWitness.swift +++ b/Sources/XyoClient/Witness/Location/LocationWitness.swift @@ -10,8 +10,9 @@ open class LocationWitness: WitnessModuleAsync { DispatchQueue.main.async { switch result { case .success(let location): - let payload = IosLocationPayload(location) - completion([payload], nil) + let iosLocationPayload = IosLocationPayload(location) + let locationPayload = LocationPayload(location) + completion([iosLocationPayload, locationPayload], nil) case .failure(let error): completion(nil, error) } From 7b5420b9bb4c0d514cb66a719b0a6b7cc1daf8b6 Mon Sep 17 00:00:00 2001 From: Joel Carter Date: Fri, 22 Nov 2024 11:38:54 -0600 Subject: [PATCH 07/12] Use address for key in tests --- Tests/XyoClientTests/CoreDataPreviousHashStoreTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/XyoClientTests/CoreDataPreviousHashStoreTests.swift b/Tests/XyoClientTests/CoreDataPreviousHashStoreTests.swift index 05180cf..1b6da6b 100644 --- a/Tests/XyoClientTests/CoreDataPreviousHashStoreTests.swift +++ b/Tests/XyoClientTests/CoreDataPreviousHashStoreTests.swift @@ -65,7 +65,7 @@ final class CoreDataPreviousHashStoreTests: XCTestCase { } func testGetItemNonExistentAddress() { - let address = "0x789abc" + let address = "f8ede235dbc41c06936d46a26d9038a58ba254a1" // Try to get an item that doesn't exist let retrievedHash = store.getItem(address: address) From 9b99b1a030d6242c948e094bb3b0f3d3ba871bc9 Mon Sep 17 00:00:00 2001 From: Joel Carter Date: Fri, 22 Nov 2024 11:46:34 -0600 Subject: [PATCH 08/12] Better test vectors to simulate real data --- Tests/XyoClientTests/AccountServices.swift | 6 +++--- .../CoreDataPreviousHashStoreTests.swift | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Tests/XyoClientTests/AccountServices.swift b/Tests/XyoClientTests/AccountServices.swift index 426e529..0001a3b 100644 --- a/Tests/XyoClientTests/AccountServices.swift +++ b/Tests/XyoClientTests/AccountServices.swift @@ -17,7 +17,7 @@ class AccountServicesTests: XCTestCase { func testGetNamedAccount_CreatesAndReturnsNewAccount_WhenNoExistingAccount() { // Act - let account = AccountServices.getNamedAccount(name: "testAccount") + let account = AccountServices.getNamedAccount(name: "testAccount1") // Assert XCTAssertNotNil(account) @@ -27,9 +27,9 @@ class AccountServicesTests: XCTestCase { func testGetNamedAccount_ReturnsExistingAccount_WhenAccountExists() { // Act // Initial attempt create account - let accountA = AccountServices.getNamedAccount(name: "testAccount") + let accountA = AccountServices.getNamedAccount(name: "testAccount2") // Subsequent ones retrieve account - let accountB = AccountServices.getNamedAccount(name: "testAccount") + let accountB = AccountServices.getNamedAccount(name: "testAccount2") // Asserts let addressA = accountA.address diff --git a/Tests/XyoClientTests/CoreDataPreviousHashStoreTests.swift b/Tests/XyoClientTests/CoreDataPreviousHashStoreTests.swift index 1b6da6b..832235b 100644 --- a/Tests/XyoClientTests/CoreDataPreviousHashStoreTests.swift +++ b/Tests/XyoClientTests/CoreDataPreviousHashStoreTests.swift @@ -22,8 +22,8 @@ final class CoreDataPreviousHashStoreTests: XCTestCase { } func testSetItemAndGetItem() { - let address = "0x123456" - let hash = "0xabcdef" + let address = "2d0fb5708b9d68bfaa96c6e426cbc66a341f117d" + let hash = "fb2b2ed349278d35b2cf32ec719227cf2a0f099f3a3305307bce15362eca32b9" // Set an item store.setItem(address: address, previousHash: hash) @@ -34,8 +34,8 @@ final class CoreDataPreviousHashStoreTests: XCTestCase { } func testRemoveItem() { - let address = "0x123456" - let hash = "0xabcdef" + let address = "f90b9ad30ea94d3df17d51c727c416b46faf18b6" + let hash = "8a76ed3fa2507859e43f24ea0e6c03acb1782281429294bb8123b6d9e73f1710" // Set an item store.setItem(address: address, previousHash: hash) @@ -49,9 +49,9 @@ final class CoreDataPreviousHashStoreTests: XCTestCase { } func testUpdateItem() { - let address = "0x123456" - let initialHash = "0xabcdef" - let updatedHash = "0x123abc" + let address = "85e7a0494c1feb184a80d64aca7bef07d8efd960" + let initialHash = "6c509659288d86d4961906299692239d40e5e3a8834ab89a473d9031e50703e0" + let updatedHash = "c2842590d989afae0bf2970b31d0323f97fe68c71a1c9d13bf275bbed13cf92c" // Set an initial item store.setItem(address: address, previousHash: initialHash) From 07fa599b7afb0b5711ef46f0c3cdc26d9f0dab4f Mon Sep 17 00:00:00 2001 From: Joel Carter Date: Fri, 22 Nov 2024 12:19:43 -0600 Subject: [PATCH 09/12] Location witness convenience init --- .../XyoClient/Witness/Location/LocationWitness.swift | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Sources/XyoClient/Witness/Location/LocationWitness.swift b/Sources/XyoClient/Witness/Location/LocationWitness.swift index 8702ab9..723ad9f 100644 --- a/Sources/XyoClient/Witness/Location/LocationWitness.swift +++ b/Sources/XyoClient/Witness/Location/LocationWitness.swift @@ -2,7 +2,17 @@ import CoreLocation import Foundation open class LocationWitness: WitnessModuleAsync { - private let locationService = LocationService() + private var locationService: LocationService = LocationService() + + override init(account: AccountInstance?) { + self.locationService = LocationService() + super.init(account: account) + } + + convenience init(locationService: LocationService) { + self.init(account: nil) + self.locationService = locationService + } override open func observe(completion: @escaping ([Payload]?, Error?) -> Void) { locationService.requestAuthorization() From a9662e08104abaed41c5f0508dabd182784a59ed Mon Sep 17 00:00:00 2001 From: Joel Carter Date: Fri, 22 Nov 2024 12:33:14 -0600 Subject: [PATCH 10/12] DI Location Service with protocols to allow for unit testing of results --- .../Witness/Location/LocationService.swift | 2 +- .../Location/LocationServiceProtocol.swift | 7 ++++ .../Witness/Location/LocationWitness.swift | 21 +++++++--- .../Witness/LocationWitness.swift | 38 +++++++++++++++++++ 4 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 Sources/XyoClient/Witness/Location/LocationServiceProtocol.swift create mode 100644 Tests/XyoClientTests/Witness/LocationWitness.swift diff --git a/Sources/XyoClient/Witness/Location/LocationService.swift b/Sources/XyoClient/Witness/Location/LocationService.swift index 3308ed3..50a406b 100644 --- a/Sources/XyoClient/Witness/Location/LocationService.swift +++ b/Sources/XyoClient/Witness/Location/LocationService.swift @@ -1,7 +1,7 @@ import CoreLocation import Foundation -public class LocationService: NSObject, CLLocationManagerDelegate { +public class LocationService: NSObject, CLLocationManagerDelegate, LocationServiceProtocol { private let locationManager = CLLocationManager() private var locationCompletion: ((Result) -> Void)? diff --git a/Sources/XyoClient/Witness/Location/LocationServiceProtocol.swift b/Sources/XyoClient/Witness/Location/LocationServiceProtocol.swift new file mode 100644 index 0000000..d346554 --- /dev/null +++ b/Sources/XyoClient/Witness/Location/LocationServiceProtocol.swift @@ -0,0 +1,7 @@ +import CoreLocation +import Foundation + +protocol LocationServiceProtocol { + func requestAuthorization() + func requestLocation(completion: @escaping (Result) -> Void) +} diff --git a/Sources/XyoClient/Witness/Location/LocationWitness.swift b/Sources/XyoClient/Witness/Location/LocationWitness.swift index 723ad9f..f6721e3 100644 --- a/Sources/XyoClient/Witness/Location/LocationWitness.swift +++ b/Sources/XyoClient/Witness/Location/LocationWitness.swift @@ -2,16 +2,27 @@ import CoreLocation import Foundation open class LocationWitness: WitnessModuleAsync { - private var locationService: LocationService = LocationService() + private var _locationService: LocationServiceProtocol? - override init(account: AccountInstance?) { - self.locationService = LocationService() + private var locationService: LocationServiceProtocol { + get { + if let service = _locationService { + return service + } else { + let initialized = LocationService() + self._locationService = initialized + return initialized + } + } + } + + override init(account: AccountInstance? = nil) { super.init(account: account) } - convenience init(locationService: LocationService) { + convenience init(locationService: LocationServiceProtocol) { self.init(account: nil) - self.locationService = locationService + self._locationService = locationService } override open func observe(completion: @escaping ([Payload]?, Error?) -> Void) { diff --git a/Tests/XyoClientTests/Witness/LocationWitness.swift b/Tests/XyoClientTests/Witness/LocationWitness.swift new file mode 100644 index 0000000..ad6a94c --- /dev/null +++ b/Tests/XyoClientTests/Witness/LocationWitness.swift @@ -0,0 +1,38 @@ +import CoreLocation +import XCTest + +@testable import XyoClient + +fileprivate class MockLocationService: LocationServiceProtocol { + var didRequestAuthorization = false + var simulatedResult: Result? + + func requestAuthorization() { + didRequestAuthorization = true + } + + func requestLocation(completion: @escaping (Result) -> Void) { + if let result = simulatedResult { + completion(result) + } + } +} + + +@available(iOS 13.0, *) +final class LocationWitnessTests: XCTestCase { + static var allTests = [ + ( + "observe:returnsMultipleLocationPayloads", testLocationWitness_observe_returnsMultipleLocationPayloads + ) + ] + + @available(iOS 15, *) + func testLocationWitness_observe_returnsMultipleLocationPayloads() async throws { + let locationServiceMock = MockLocationService() + locationServiceMock.simulatedResult = .success(CLLocation(latitude: 1, longitude: 2)) + let sut = LocationWitness(locationService: locationServiceMock) + let result = try await sut.observe() + XCTAssertEqual(result.count, 2) + } +} From 937b820ba65300982e2204829fe426d277fa49ea Mon Sep 17 00:00:00 2001 From: Joel Carter Date: Fri, 22 Nov 2024 12:44:40 -0600 Subject: [PATCH 11/12] Assert location payloads response --- .../Location/Generic/LocationPayload.swift | 5 +++-- .../Witness/Location/LocationWitness.swift | 20 +++++++++---------- .../Witness/LocationWitness.swift | 19 ++++++++++++------ 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/Sources/XyoClient/Witness/Location/Generic/LocationPayload.swift b/Sources/XyoClient/Witness/Location/Generic/LocationPayload.swift index 03287dc..c67a5d1 100644 --- a/Sources/XyoClient/Witness/Location/Generic/LocationPayload.swift +++ b/Sources/XyoClient/Witness/Location/Generic/LocationPayload.swift @@ -17,7 +17,7 @@ open class LocationPayload: Payload { override open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(self.schema, forKey: .schema) - + let coords: CoordinatesStruct = CoordinatesStruct( accuracy: self.location.horizontalAccuracy, altitude: self.location.altitude, @@ -28,7 +28,8 @@ open class LocationPayload: Payload { speed: self.location.speed ) let timestamp = self.location.timestamp - let currentLocation: CurrentLocationStruct = CurrentLocationStruct(coords: coords, timestamp: timestamp) + let currentLocation: CurrentLocationStruct = CurrentLocationStruct( + coords: coords, timestamp: timestamp) try container.encode(currentLocation, forKey: .currentLocation) } } diff --git a/Sources/XyoClient/Witness/Location/LocationWitness.swift b/Sources/XyoClient/Witness/Location/LocationWitness.swift index f6721e3..875879e 100644 --- a/Sources/XyoClient/Witness/Location/LocationWitness.swift +++ b/Sources/XyoClient/Witness/Location/LocationWitness.swift @@ -3,23 +3,21 @@ import Foundation open class LocationWitness: WitnessModuleAsync { private var _locationService: LocationServiceProtocol? - + private var locationService: LocationServiceProtocol { - get { - if let service = _locationService { - return service - } else { - let initialized = LocationService() - self._locationService = initialized - return initialized - } + if let service = _locationService { + return service + } else { + let initialized = LocationService() + self._locationService = initialized + return initialized } } - + override init(account: AccountInstance? = nil) { super.init(account: account) } - + convenience init(locationService: LocationServiceProtocol) { self.init(account: nil) self._locationService = locationService diff --git a/Tests/XyoClientTests/Witness/LocationWitness.swift b/Tests/XyoClientTests/Witness/LocationWitness.swift index ad6a94c..d1a2ab4 100644 --- a/Tests/XyoClientTests/Witness/LocationWitness.swift +++ b/Tests/XyoClientTests/Witness/LocationWitness.swift @@ -3,10 +3,10 @@ import XCTest @testable import XyoClient -fileprivate class MockLocationService: LocationServiceProtocol { +private class MockLocationService: LocationServiceProtocol { var didRequestAuthorization = false var simulatedResult: Result? - + func requestAuthorization() { didRequestAuthorization = true } @@ -18,12 +18,12 @@ fileprivate class MockLocationService: LocationServiceProtocol { } } - @available(iOS 13.0, *) final class LocationWitnessTests: XCTestCase { static var allTests = [ ( - "observe:returnsMultipleLocationPayloads", testLocationWitness_observe_returnsMultipleLocationPayloads + "observe:returnsMultipleLocationPayloads", + testLocationWitness_observe_returnsMultipleLocationPayloads ) ] @@ -32,7 +32,14 @@ final class LocationWitnessTests: XCTestCase { let locationServiceMock = MockLocationService() locationServiceMock.simulatedResult = .success(CLLocation(latitude: 1, longitude: 2)) let sut = LocationWitness(locationService: locationServiceMock) - let result = try await sut.observe() - XCTAssertEqual(result.count, 2) + let results = try await sut.observe() + XCTAssertEqual(results.count, 2) + let locationPayload = try XCTUnwrap( + results.compactMap { $0 as? LocationPayload }.first, "Missing location payload.") + XCTAssertEqual(locationPayload.schema, "network.xyo.location") + let iosLocationPayload = try XCTUnwrap( + results.compactMap { $0 as? IosLocationPayload }.first, "Missing iOS location payload.") + XCTAssertEqual(iosLocationPayload.schema, "network.xyo.location.ios") + } } From 09e3cd9845f760fb60ee1895c18f8e9cdca2933d Mon Sep 17 00:00:00 2001 From: Joel Carter Date: Fri, 22 Nov 2024 12:55:23 -0600 Subject: [PATCH 12/12] Static schema on payloads --- .../Witness/Location/Generic/LocationPayload.swift | 4 +++- .../Witness/Location/iOS/IosLocationPayload.swift | 4 +++- Tests/XyoClientTests/Witness/LocationWitness.swift | 12 +++++++++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Sources/XyoClient/Witness/Location/Generic/LocationPayload.swift b/Sources/XyoClient/Witness/Location/Generic/LocationPayload.swift index c67a5d1..5548e04 100644 --- a/Sources/XyoClient/Witness/Location/Generic/LocationPayload.swift +++ b/Sources/XyoClient/Witness/Location/Generic/LocationPayload.swift @@ -1,12 +1,14 @@ import CoreLocation open class LocationPayload: Payload { + + public static let schema: String = "network.xyo.location" var location: CLLocation public init(_ location: CLLocation) { self.location = location - super.init("network.xyo.location") + super.init(LocationPayload.schema) } enum CodingKeys: String, CodingKey { diff --git a/Sources/XyoClient/Witness/Location/iOS/IosLocationPayload.swift b/Sources/XyoClient/Witness/Location/iOS/IosLocationPayload.swift index 5b1134c..ba044b0 100644 --- a/Sources/XyoClient/Witness/Location/iOS/IosLocationPayload.swift +++ b/Sources/XyoClient/Witness/Location/iOS/IosLocationPayload.swift @@ -1,12 +1,14 @@ import CoreLocation open class IosLocationPayload: Payload { + + public static let schema: String = "network.xyo.location.ios" var location: CLLocation public init(_ location: CLLocation) { self.location = location - super.init("network.xyo.location.ios") + super.init(IosLocationPayload.schema) } enum CodingKeys: String, CodingKey { diff --git a/Tests/XyoClientTests/Witness/LocationWitness.swift b/Tests/XyoClientTests/Witness/LocationWitness.swift index d1a2ab4..27a5fc3 100644 --- a/Tests/XyoClientTests/Witness/LocationWitness.swift +++ b/Tests/XyoClientTests/Witness/LocationWitness.swift @@ -30,16 +30,22 @@ final class LocationWitnessTests: XCTestCase { @available(iOS 15, *) func testLocationWitness_observe_returnsMultipleLocationPayloads() async throws { let locationServiceMock = MockLocationService() - locationServiceMock.simulatedResult = .success(CLLocation(latitude: 1, longitude: 2)) + let lattitiude: Double = 1 + let longitude: Double = 2 + locationServiceMock.simulatedResult = .success(CLLocation(latitude: lattitiude, longitude: longitude)) let sut = LocationWitness(locationService: locationServiceMock) let results = try await sut.observe() XCTAssertEqual(results.count, 2) let locationPayload = try XCTUnwrap( results.compactMap { $0 as? LocationPayload }.first, "Missing location payload.") - XCTAssertEqual(locationPayload.schema, "network.xyo.location") + XCTAssertEqual(locationPayload.schema, LocationPayload.schema) + XCTAssertEqual(locationPayload.location.coordinate.latitude, lattitiude) + XCTAssertEqual(locationPayload.location.coordinate.longitude, longitude) let iosLocationPayload = try XCTUnwrap( results.compactMap { $0 as? IosLocationPayload }.first, "Missing iOS location payload.") - XCTAssertEqual(iosLocationPayload.schema, "network.xyo.location.ios") + XCTAssertEqual(iosLocationPayload.schema, IosLocationPayload.schema) + XCTAssertEqual(iosLocationPayload.location.coordinate.latitude, lattitiude) + XCTAssertEqual(iosLocationPayload.location.coordinate.longitude, longitude) } }