From 2ed62636e17fd131d29e6f008333461371f01f7c Mon Sep 17 00:00:00 2001 From: Jack Alto <384288+aokj4ck@users.noreply.github.com> Date: Tue, 9 Apr 2024 17:07:13 -0400 Subject: [PATCH 1/6] [SSDK-622] Add language parameter to offline tileset descriptor creation (#202) ### Description Fixes [SSDK-622](https://mapbox.atlassian.net/browse/SSDK-622) Add optional `language` parameter that has two modes: 1. Absent language parameter / `nil` value will use existing behavior of _just_ the dataset name. 2. A given language parameter will be appended to the dataset name. ### Checklist - [x] Update `CHANGELOG` - [x] Add a non-English language test after #199 is merged --- CHANGELOG.md | 3 + .../InternalAPI/CoreSearchEngineStatics.swift | 57 ++++++++++++++++-- .../Offline/SearchOfflineManager.swift | 37 ++++++++++-- .../OfflineIntegrationTests.swift | 59 ++++++++++++++++++- 4 files changed, 144 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ae47e89d..2471ab400 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ Guide: https://keepachangelog.com/en/1.0.0/ +- [Offline] Add optional `language` parameter to SearchOfflineManager.createTilesetDescriptor and SearchOfflineManager.createPlacesTilesetDescriptor functions. +- [Tests] Add Spanish language offline search test. + - [Offline] Added OfflineIndexObserver which accepts two blocks for indexChanged or error events. This can be assigned to the offline search engine to receive state updates. - [Offline] Change default tileset name to `mbx-main` diff --git a/Sources/MapboxSearch/InternalAPI/CoreSearchEngineStatics.swift b/Sources/MapboxSearch/InternalAPI/CoreSearchEngineStatics.swift index 71e4c3ffd..b7b53b270 100644 --- a/Sources/MapboxSearch/InternalAPI/CoreSearchEngineStatics.swift +++ b/Sources/MapboxSearch/InternalAPI/CoreSearchEngineStatics.swift @@ -1,11 +1,60 @@ import Foundation enum CoreSearchEngineStatics { - static func createTilesetDescriptor(dataset: String, version: String) -> MapboxCommon.TilesetDescriptor { - CoreSearchEngine.createTilesetDescriptor(forDataset: dataset, version: version) + enum Constants { + static let delimiter = "_" } - static func createPlacesTilesetDescriptor(dataset: String, version: String) -> MapboxCommon.TilesetDescriptor { - CoreSearchEngine.createPlacesTilesetDescriptor(forDataset: dataset, version: version) + static func createTilesetDescriptor(dataset: String, version: String, language: String? = nil) -> MapboxCommon + .TilesetDescriptor { + let identifier: String + if let language { + if ISOLanguages.contains(language: language) { + identifier = dataset + Constants.delimiter + language + } else { + _Logger.searchSDK + .warning( + "Provided language code '\(language)' for tileset is non-ISO. Dataset '\(dataset)' without language will be used." + ) + identifier = dataset + } + } else { + identifier = dataset + } + return CoreSearchEngine.createTilesetDescriptor(forDataset: identifier, version: version) + } + + static func createPlacesTilesetDescriptor(dataset: String, version: String, language: String? = nil) -> MapboxCommon + .TilesetDescriptor { + let identifier: String + if let language { + if ISOLanguages.contains(language: language) { + identifier = dataset + Constants.delimiter + language + } else { + _Logger.searchSDK + .warning( + "Provided language code '\(language)' for places tileset is non-ISO. Dataset '\(dataset)' without language will be used." + ) + identifier = dataset + } + } else { + identifier = dataset + } + return CoreSearchEngine.createPlacesTilesetDescriptor(forDataset: identifier, version: version) + } +} + +enum ISOLanguages { + static func contains(language: String) -> Bool { + var validLanguage: Bool + if #available(iOS 16, *) { + validLanguage = Locale.LanguageCode.isoLanguageCodes + .map(\.identifier) + .contains(language) + } else { + validLanguage = Locale.isoLanguageCodes + .contains(language) + } + return validLanguage } } diff --git a/Sources/MapboxSearch/PublicAPI/Offline/SearchOfflineManager.swift b/Sources/MapboxSearch/PublicAPI/Offline/SearchOfflineManager.swift index cf8a898cc..52fad5780 100644 --- a/Sources/MapboxSearch/PublicAPI/Offline/SearchOfflineManager.swift +++ b/Sources/MapboxSearch/PublicAPI/Offline/SearchOfflineManager.swift @@ -41,26 +41,53 @@ public class SearchOfflineManager { engine.setTileStore(searchTileStore.commonTileStore, completion: completion) } - /// Creates TilesetDescriptor for offline search index data with provided dataset name and version. + // MARK: - Tileset with name, version, and language parameters + + /// Creates TilesetDescriptor for offline search index data with provided dataset name, version, and language. + /// Providing nil or excluding the language parameter will use the dataset name as-is. + /// Providing a language will append it to the name. /// - Parameters: /// - dataset: dataset name /// - version: dataset version + /// - language: Provide a ISO 639-1 Code language from NSLocale. Values will be appended to the place dataset + /// name. /// - Returns: TilesetDescriptor for TileStore - public static func createTilesetDescriptor(dataset: String, version: String? = nil) -> MapboxCommon + public static func createTilesetDescriptor( + dataset: String, + version: String? = nil, + language: String? = nil + ) -> MapboxCommon .TilesetDescriptor { - CoreSearchEngineStatics.createTilesetDescriptor(dataset: dataset, version: version ?? "") + CoreSearchEngineStatics.createTilesetDescriptor( + dataset: dataset, + version: version ?? "", + language: language + ) } /// Creates TilesetDescriptor for offline search boundaries with provided dataset name and version. + /// Providing nil or excluding the language parameter will use the places dataset name as-is. + /// Providing a language will append it to the name. /// - Parameters: /// - dataset: dataset name /// - version: dataset version + /// - language: Provide a ISO 639-1 Code language from NSLocale. Values will be appended to the dataset name. /// - Returns: TilesetDescriptor for TileStore - public static func createPlacesTilesetDescriptor(dataset: String, version: String? = nil) -> MapboxCommon + public static func createPlacesTilesetDescriptor( + dataset: String, + version: String? = nil, + language: String? = nil + ) -> MapboxCommon .TilesetDescriptor { - CoreSearchEngineStatics.createPlacesTilesetDescriptor(dataset: dataset, version: version ?? "") + CoreSearchEngineStatics.createPlacesTilesetDescriptor( + dataset: dataset, + version: version ?? "", + language: language + ) } + // MARK: - Default tileset + /// Creates TilesetDescriptor for offline search index data using default dataset name. /// - Returns: TilesetDescriptor for TileStore public static func createDefaultTilesetDescriptor() -> MapboxCommon.TilesetDescriptor { diff --git a/Tests/MapboxSearchIntegrationTests/OfflineIntegrationTests.swift b/Tests/MapboxSearchIntegrationTests/OfflineIntegrationTests.swift index 200916951..b705f2262 100644 --- a/Tests/MapboxSearchIntegrationTests/OfflineIntegrationTests.swift +++ b/Tests/MapboxSearchIntegrationTests/OfflineIntegrationTests.swift @@ -36,10 +36,15 @@ class OfflineIntegrationTests: MockServerIntegrationTestCase { wait(for: [setTileStoreExpectation], timeout: 10) } - func loadData(completion: @escaping (Result) -> Void) + func loadData( + tilesetDescriptor: TilesetDescriptor? = nil, + completion: @escaping (Result) -> Void + ) -> SearchCancelable { - /// This will use the default dataset defined at ``SearchOfflineManager.defaultDatasetName`` - let descriptor = SearchOfflineManager.createDefaultTilesetDescriptor() + /// A nil tilesetDescriptor parameter will fallback to the default dataset defined at + /// ``SearchOfflineManager.defaultDatasetName`` + let descriptor = tilesetDescriptor ?? SearchOfflineManager.createDefaultTilesetDescriptor() + let dcLocationValue = NSValue(mkCoordinate: dcLocation) let options = MapboxCommon.TileRegionLoadOptions.build( geometry: Geometry(point: dcLocationValue), @@ -104,6 +109,54 @@ class OfflineIntegrationTests: MockServerIntegrationTestCase { XCTAssertFalse(searchEngine.suggestions.isEmpty) } + func testSpanishLanguageSupport() throws { + clearData() + + // Set up index observer before the fetch starts to validate changes after it completes + let indexChangedExpectation = expectation(description: "Received offline index changed event") + let offlineIndexObserver = OfflineIndexObserver(onIndexChangedBlock: { changeEvent in + _Logger.searchSDK.info("Index changed: \(changeEvent)") + indexChangedExpectation.fulfill() + }, onErrorBlock: { error in + _Logger.searchSDK.error("Encountered error in OfflineIndexObserver \(error)") + XCTFail(error.debugDescription) + }) + searchEngine.offlineManager.engine.addOfflineIndexObserver(for: offlineIndexObserver) + + // Perform the offline fetch + let spanishTileset = SearchOfflineManager.createTilesetDescriptor( + dataset: "mbx-main", + language: "es" + ) + let loadDataExpectation = expectation(description: "Load Data") + _ = loadData(tilesetDescriptor: spanishTileset) { result in + switch result { + case .success(let region): + XCTAssert(region.id == self.regionId) + XCTAssert(region.completedResourceCount > 0) + XCTAssertEqual(region.requiredResourceCount, region.completedResourceCount) + case .failure(let error): + XCTFail("Unable to load Region, \(error.localizedDescription)") + } + loadDataExpectation.fulfill() + } + wait( + for: [loadDataExpectation, indexChangedExpectation], + timeout: 200, + enforceOrder: true + ) + + let offlineUpdateExpectation = delegate.offlineUpdateExpectation + searchEngine.search(query: "café") + wait(for: [offlineUpdateExpectation], timeout: 10) + + XCTAssertNil(delegate.error) + XCTAssertNil(delegate.error?.localizedDescription) + XCTAssertNotNil(searchEngine.responseInfo) + XCTAssertFalse(delegate.resolvedResults.isEmpty) + XCTAssertFalse(searchEngine.suggestions.isEmpty) + } + func testNoData() { clearData() From 284487ba5f5dc2c1b8bb694114742613e475e57f Mon Sep 17 00:00:00 2001 From: Jack Alto <384288+aokj4ck@users.noreply.github.com> Date: Tue, 9 Apr 2024 17:22:12 -0400 Subject: [PATCH 2/6] Fix missing image reference from xib (#203) ### Description Before this fix the following console message was logged ``` 2024-04-03 15:19:52.728231-0400 Demo[79878:948336] Could not load the "maki/home" image referenced from a nib in the bundle with identifier "com.mapbox.MapboxSearchUIResources" 2024-04-03 15:19:52.731094-0400 Demo[79878:948336] Could not load the "maki/home" image referenced from a nib in the bundle with identifier "com.mapbox.MapboxSearchUIResources" ``` ### Checklist - [NA] Update `CHANGELOG` #### Screenshots | Before | After | | -- | -- | | Screenshot 2024-04-03 at 15 22 43 | Screenshot 2024-04-03 at 15 22 49 | --- Sources/MapboxSearchUI/UserFavoriteCell.xib | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/MapboxSearchUI/UserFavoriteCell.xib b/Sources/MapboxSearchUI/UserFavoriteCell.xib index e844272fb..b44a94f1c 100644 --- a/Sources/MapboxSearchUI/UserFavoriteCell.xib +++ b/Sources/MapboxSearchUI/UserFavoriteCell.xib @@ -1,9 +1,9 @@ - + - + @@ -17,7 +17,7 @@ - + @@ -76,7 +76,7 @@ - + From d50bb24d94573d9b27e313a87f753ab33d1626ba Mon Sep 17 00:00:00 2001 From: Jack Alto <384288+aokj4ck@users.noreply.github.com> Date: Mon, 15 Apr 2024 15:55:39 -0400 Subject: [PATCH 3/6] Move DiscoverViewController from MapboxSearch target to Demo target (#211) ### Description - Validate with a git grep for 'customModule' and confirm each interface builder file is in the appropriate module and path - MapboxSearch should not contain views ### Checklist - [NA] Update `CHANGELOG` --- MapboxSearch.xcodeproj/project.pbxproj | 4 ++-- Sources/Demo/Base.lproj/Main.storyboard | 2 +- Sources/Demo/DiscoverViewController.swift | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/MapboxSearch.xcodeproj/project.pbxproj b/MapboxSearch.xcodeproj/project.pbxproj index b65450aaf..5bd2f145d 100644 --- a/MapboxSearch.xcodeproj/project.pbxproj +++ b/MapboxSearch.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 0405809D2BA8E67D00A54CB9 /* OwningObjectDeallocatedErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0405809C2BA8E67D00A54CB9 /* OwningObjectDeallocatedErrorTests.swift */; }; + 041DAFD92BCDA45B0071F9EB /* DiscoverViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14B92D5D298BFD19006003C1 /* DiscoverViewController.swift */; }; 042477C32B7290F900D870D5 /* SearchEngineGeocodingIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 042477C12B7290E700D870D5 /* SearchEngineGeocodingIntegrationTests.swift */; }; 042477C52B72CCB000D870D5 /* geocoding-reverse-geocoding.json in Resources */ = {isa = PBXBuildFile; fileRef = 042477C42B72CCB000D870D5 /* geocoding-reverse-geocoding.json */; }; 042477C62B72CCB000D870D5 /* geocoding-reverse-geocoding.json in Resources */ = {isa = PBXBuildFile; fileRef = 042477C42B72CCB000D870D5 /* geocoding-reverse-geocoding.json */; }; @@ -104,7 +105,6 @@ 149948EF290A8DD500E7E619 /* Swifter in Frameworks */ = {isa = PBXBuildFile; productRef = 149948EE290A8DD500E7E619 /* Swifter */; }; 149948F1290A8DF900E7E619 /* Swifter in Frameworks */ = {isa = PBXBuildFile; productRef = 149948F0290A8DF900E7E619 /* Swifter */; settings = {ATTRIBUTES = (Required, ); }; }; 14A0B83D2A5FF20B00D281F1 /* PlaceAutocomplet.Result+Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14A0B83B2A5FF1B300D281F1 /* PlaceAutocomplet.Result+Tests.swift */; }; - 14B92D5E298BFD19006003C1 /* DiscoverViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14B92D5D298BFD19006003C1 /* DiscoverViewController.swift */; }; 14F71865299FD4BD00D5BC2E /* PlaceAutocomplete+PlaceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14F71864299FD4BD00D5BC2E /* PlaceAutocomplete+PlaceType.swift */; }; 14F7186B29A1361700D5BC2E /* PlaceAutocompleteMainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14F7186929A1341A00D5BC2E /* PlaceAutocompleteMainViewController.swift */; }; 14F7186D29A139BF00D5BC2E /* PlaceAutocompleteDetailsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14F7186C29A139BF00D5BC2E /* PlaceAutocompleteDetailsViewController.swift */; }; @@ -2597,7 +2597,6 @@ 14173C302878437D00B20E1C /* Country+ISO3166-1.swift in Sources */, FEEDD3162508DFE400DC0A98 /* SearchCategorySuggestion.swift in Sources */, FEEDD31D2508DFE400DC0A98 /* HighlightsCalculator.swift in Sources */, - 14B92D5E298BFD19006003C1 /* DiscoverViewController.swift in Sources */, 14FA657C2953497600056E5B /* PlaceAutocomplete+Options.swift in Sources */, F9A0B8402562B10E00CAD907 /* SearchResultMetadata.swift in Sources */, FE097B7D264EAA1A001EAC2F /* CustomNSError.swift in Sources */, @@ -2869,6 +2868,7 @@ files = ( 1440BF4F290019AD009B3679 /* AddressAutofillResultViewController.swift in Sources */, 1440BF4D28FD75A9009B3679 /* AddressAutofillMainViewController.swift in Sources */, + 041DAFD92BCDA45B0071F9EB /* DiscoverViewController.swift in Sources */, FEEDD3C32508E3CD00DC0A98 /* AppDelegate.swift in Sources */, 14F7186D29A139BF00D5BC2E /* PlaceAutocompleteDetailsViewController.swift in Sources */, FEEDD3BF2508E3CD00DC0A98 /* MapRootController.swift in Sources */, diff --git a/Sources/Demo/Base.lproj/Main.storyboard b/Sources/Demo/Base.lproj/Main.storyboard index 806f40fba..bebe11cce 100644 --- a/Sources/Demo/Base.lproj/Main.storyboard +++ b/Sources/Demo/Base.lproj/Main.storyboard @@ -248,7 +248,7 @@ - + diff --git a/Sources/Demo/DiscoverViewController.swift b/Sources/Demo/DiscoverViewController.swift index c4d86c665..76b16f9b4 100644 --- a/Sources/Demo/DiscoverViewController.swift +++ b/Sources/Demo/DiscoverViewController.swift @@ -1,3 +1,4 @@ +import MapboxSearch import MapKit import UIKit From 993f04ff7a43f51568932c7ed08b63540da9b915 Mon Sep 17 00:00:00 2001 From: Jack Alto <384288+aokj4ck@users.noreply.github.com> Date: Thu, 18 Apr 2024 16:43:48 -0400 Subject: [PATCH 4/6] Update SearchCore to alpha.16 (#212) ### Description - Regular SDK updates ### Checklist - [x] Update `CHANGELOG` --- CHANGELOG.md | 1 + Cartfile | 4 ++-- Cartfile.resolved | 2 +- Package.swift | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2471ab400..46711d9a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ Guide: https://keepachangelog.com/en/1.0.0/ - [Tests] Demonstrate providing a `Geometry(point: NSValue(mkCoordinate: CLLocationCoordinate2D))` with `TileRegionLoadOptions.build` function. - [Core] Increment minimum MapboxCommon version from 24.0.0 to 24.2.0. +**MapboxCoreSearch**: v2.0.0-alpha.16 **MapboxCommon**: v24.2.0 ## 2.0.0-rc.3 diff --git a/Cartfile b/Cartfile index 530d47dbc..57f52ab34 100644 --- a/Cartfile +++ b/Cartfile @@ -1,2 +1,2 @@ -binary "https://api.mapbox.com/downloads/v2/carthage/search-core-sdk/MapboxCoreSearch.xcframework.json" == 2.0.0-alpha.14 -binary "https://api.mapbox.com/downloads/v2/carthage/mapbox-common/MapboxCommon.json" == 24.2.0 \ No newline at end of file +binary "https://api.mapbox.com/downloads/v2/carthage/search-core-sdk/MapboxCoreSearch.xcframework.json" == 2.0.0-alpha.16 +binary "https://api.mapbox.com/downloads/v2/carthage/mapbox-common/MapboxCommon.json" == 24.2.0 diff --git a/Cartfile.resolved b/Cartfile.resolved index 0cf38f59e..fc1d20d1c 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,2 +1,2 @@ binary "https://api.mapbox.com/downloads/v2/carthage/mapbox-common/MapboxCommon.json" "24.2.0" -binary "https://api.mapbox.com/downloads/v2/carthage/search-core-sdk/MapboxCoreSearch.xcframework.json" "2.0.0-alpha.14" +binary "https://api.mapbox.com/downloads/v2/carthage/search-core-sdk/MapboxCoreSearch.xcframework.json" "2.0.0-alpha.16" diff --git a/Package.swift b/Package.swift index e36ab2f8c..c376e6a42 100644 --- a/Package.swift +++ b/Package.swift @@ -4,7 +4,7 @@ import PackageDescription import Foundation -let (coreSearchVersion, coreSearchVersionHash) = ("2.0.0-alpha.14", "c3e61341f2beb1b8043f3c71caccdd9bea12a23f221cb90eb452e2abe299c3e0") +let (coreSearchVersion, coreSearchVersionHash) = ("2.0.0-alpha.16", "315d5f6ed1446f5ca5d62cc6e4124ae01fa271ad9d675268e886c38149db8532") let commonMinVersion = Version("24.2.0") let commonMaxVersion = Version("25.0.0") From fa0a370ed3314863e190e2b6c7b6a5a86034f74b Mon Sep 17 00:00:00 2001 From: Jack Alto <384288+aokj4ck@users.noreply.github.com> Date: Fri, 19 Apr 2024 10:07:05 -0400 Subject: [PATCH 5/6] [SSDK-736] fix SDK import through SPM (#213) ### Description Fixes SSDK-736 - This fixes a "SILFunction type mistmatch" when using SPM and Xcode 15.3. - More on SILFunction type mismatch: https://github.com/apple/swift/issues/65849 > I'm asking because @_implementationOnly is only compatible with resilient modules. You can build resilient modules using a classic Xcode project and by enabling the build setting Build Library for Distribution. I believe packages don't yet have a way to enable this feature without using unsafe flags. > > Using @_implementationOnly without resilience may lead to runtime crashes and memory corruption. Very recent compilers warn about this configuration. > > Considering @_implementationOnly is an unofficial feature you may still hit compiler crashes even in supported configurations. While there's not much we can do for crashes without resilience, if you still see a crash after enabling resilience I may be able to help on that front. ### Checklist - [x] Update `CHANGELOG` --- CHANGELOG.md | 3 +++ MapboxSearch.xcodeproj/project.pbxproj | 12 ------------ .../MapboxSearch/InternalAPI/CoreAliases.swift | 10 ++++------ .../CoreOfflineIndexChangeEventType.swift | 18 ------------------ .../CoreUserRecordsLayerStub.swift | 2 +- Tests/MapboxSearchTests/CoreAliases.swift | 1 - Tests/MockWebServer/MockResponse.swift | 1 - 7 files changed, 8 insertions(+), 39 deletions(-) delete mode 100644 Sources/MapboxSearch/InternalAPI/Offline/CoreOfflineIndexChangeEventType.swift delete mode 120000 Tests/MapboxSearchTests/CoreAliases.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 46711d9a0..e84c29d83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ Guide: https://keepachangelog.com/en/1.0.0/ +- [Offline] Remove `CoreOfflineIndexChangeEventType` extension previously used for development. +- [Core] Remove usages of `@_implementationOnly import` due to compilation issue. + - [Offline] Add optional `language` parameter to SearchOfflineManager.createTilesetDescriptor and SearchOfflineManager.createPlacesTilesetDescriptor functions. - [Tests] Add Spanish language offline search test. diff --git a/MapboxSearch.xcodeproj/project.pbxproj b/MapboxSearch.xcodeproj/project.pbxproj index 5bd2f145d..1f3f568b7 100644 --- a/MapboxSearch.xcodeproj/project.pbxproj +++ b/MapboxSearch.xcodeproj/project.pbxproj @@ -33,7 +33,6 @@ 0477904E2B890F4E00A99528 /* search-box-retrieve-minsk.json in Resources */ = {isa = PBXBuildFile; fileRef = 0477904C2B890F4E00A99528 /* search-box-retrieve-minsk.json */; }; 0477904F2B890F4E00A99528 /* search-box-retrieve-minsk.json in Resources */ = {isa = PBXBuildFile; fileRef = 0477904C2B890F4E00A99528 /* search-box-retrieve-minsk.json */; }; 0484BCDF2BC4865C003CF408 /* OfflineIndexObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0484BCDE2BC4865C003CF408 /* OfflineIndexObserver.swift */; }; - 0484BCE22BC49A23003CF408 /* CoreOfflineIndexChangeEventType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0484BCE12BC49A23003CF408 /* CoreOfflineIndexChangeEventType.swift */; }; 048823482B6B0A9D00C770AA /* category-hotel-search-along-route-jp.json in Resources */ = {isa = PBXBuildFile; fileRef = 04AB0B7C2B6B043C00FDE7D5 /* category-hotel-search-along-route-jp.json */; }; 048823492B6B0A9D00C770AA /* category-hotel-search-along-route-jp.json in Resources */ = {isa = PBXBuildFile; fileRef = 04AB0B7C2B6B043C00FDE7D5 /* category-hotel-search-along-route-jp.json */; }; 0488234A2B6B0A9E00C770AA /* category-hotel-search-along-route-jp.json in Resources */ = {isa = PBXBuildFile; fileRef = 04AB0B7C2B6B043C00FDE7D5 /* category-hotel-search-along-route-jp.json */; }; @@ -543,7 +542,6 @@ 047790482B890A8500A99528 /* search-box-recursion.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "search-box-recursion.json"; sourceTree = ""; }; 0477904C2B890F4E00A99528 /* search-box-retrieve-minsk.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "search-box-retrieve-minsk.json"; sourceTree = ""; }; 0484BCDE2BC4865C003CF408 /* OfflineIndexObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfflineIndexObserver.swift; sourceTree = ""; }; - 0484BCE12BC49A23003CF408 /* CoreOfflineIndexChangeEventType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreOfflineIndexChangeEventType.swift; sourceTree = ""; }; 04970F8C2B7A97C900213763 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; 04AB0B4A2B6AADB700FDE7D5 /* mapbox.places.san.francisco.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = mapbox.places.san.francisco.json; sourceTree = ""; }; 04AB0B792B6AF37800FDE7D5 /* DiscoverIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiscoverIntegrationTests.swift; sourceTree = ""; }; @@ -1056,14 +1054,6 @@ path = sbs; sourceTree = ""; }; - 0484BCE02BC49A18003CF408 /* Offline */ = { - isa = PBXGroup; - children = ( - 0484BCE12BC49A23003CF408 /* CoreOfflineIndexChangeEventType.swift */, - ); - path = Offline; - sourceTree = ""; - }; 04970F8B2B7A97C900213763 /* Resources */ = { isa = PBXGroup; children = ( @@ -1744,7 +1734,6 @@ FEEDD2C12508DFE400DC0A98 /* InternalAPI */ = { isa = PBXGroup; children = ( - 0484BCE02BC49A18003CF408 /* Offline */, 04C127562B62FFD000884325 /* Engine */, 148DE66E285777050085684D /* Common */, F98BECBB2577B9150081D3BC /* Telemetry */, @@ -2677,7 +2666,6 @@ F9E8146225418E7D00F6378E /* EventsManager.swift in Sources */, FEEDD3002508DFE400DC0A98 /* CLLocationCoordinate2DCodable.swift in Sources */, FEEDD3042508DFE400DC0A98 /* SearchResultType.swift in Sources */, - 0484BCE22BC49A23003CF408 /* CoreOfflineIndexChangeEventType.swift in Sources */, F91FD66C258CCB41008CB8E1 /* CoreResultType+Extensions.swift in Sources */, FEEDD3152508DFE400DC0A98 /* ServerSearchResult.swift in Sources */, 140E47A2298BC90E00677E30 /* Discover.swift in Sources */, diff --git a/Sources/MapboxSearch/InternalAPI/CoreAliases.swift b/Sources/MapboxSearch/InternalAPI/CoreAliases.swift index 1c69bb309..c718e5480 100644 --- a/Sources/MapboxSearch/InternalAPI/CoreAliases.swift +++ b/Sources/MapboxSearch/InternalAPI/CoreAliases.swift @@ -1,10 +1,8 @@ -@_implementationOnly import MapboxCommon_Private +import MapboxCommon_Private +import MapboxCoreSearch +import MapboxCoreSearch_Private -/// https://forums.swift.org/t/update-on-implementation-only-imports/26996 -@_implementationOnly import MapboxCoreSearch -@_implementationOnly import MapboxCoreSearch_Private - -// Note: This file included in MapboxSearch and MapboxSearchTests targets +// Note: This file is included in MapboxSearch and MapboxSearchTests targets typealias CoreSearchEngine = MapboxCoreSearch.SearchEngine typealias CoreSearchResponse = MapboxCoreSearch_Private.SearchResponse diff --git a/Sources/MapboxSearch/InternalAPI/Offline/CoreOfflineIndexChangeEventType.swift b/Sources/MapboxSearch/InternalAPI/Offline/CoreOfflineIndexChangeEventType.swift deleted file mode 100644 index 0be3ffce2..000000000 --- a/Sources/MapboxSearch/InternalAPI/Offline/CoreOfflineIndexChangeEventType.swift +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright © 2024 Mapbox. All rights reserved. - -import Foundation - -extension CoreOfflineIndexChangeEventType: CustomDebugStringConvertible { - public var debugDescription: String { - switch self { - case .added: - return "Added" - case .removed: - return "Removed" - case .updated: - return "Updated" - @unknown default: - return "Unknown" - } - } -} diff --git a/Tests/MapboxSearchTests/Common/Stubs&Models/CoreUserRecordsLayerStub.swift b/Tests/MapboxSearchTests/Common/Stubs&Models/CoreUserRecordsLayerStub.swift index 7b7a2d85e..4a82b8c1f 100644 --- a/Tests/MapboxSearchTests/Common/Stubs&Models/CoreUserRecordsLayerStub.swift +++ b/Tests/MapboxSearchTests/Common/Stubs&Models/CoreUserRecordsLayerStub.swift @@ -1,4 +1,4 @@ -@_implementationOnly import MapboxCoreSearch +@testable import MapboxCoreSearch @testable import MapboxSearch class CoreUserRecordsLayerStub: CoreUserRecordsLayerProtocol { diff --git a/Tests/MapboxSearchTests/CoreAliases.swift b/Tests/MapboxSearchTests/CoreAliases.swift deleted file mode 120000 index 94c9daba1..000000000 --- a/Tests/MapboxSearchTests/CoreAliases.swift +++ /dev/null @@ -1 +0,0 @@ -../../Sources/MapboxSearch/InternalAPI/CoreAliases.swift \ No newline at end of file diff --git a/Tests/MockWebServer/MockResponse.swift b/Tests/MockWebServer/MockResponse.swift index cea7235d3..d37d5170e 100644 --- a/Tests/MockWebServer/MockResponse.swift +++ b/Tests/MockWebServer/MockResponse.swift @@ -1,5 +1,4 @@ import Foundation -@_implementationOnly import MapboxCoreSearch @testable import MapboxSearch import Swifter import XCTest From b30ea744e872d8f74e5766d6c28d9c7067baaaf3 Mon Sep 17 00:00:00 2001 From: Jack Alto <384288+aokj4ck@users.noreply.github.com> Date: Fri, 19 Apr 2024 10:40:16 -0400 Subject: [PATCH 6/6] Add mapboxId to SearchResult and derived types (#216) ### Description - Add `mapboxId: String?` to SearchResult - Available in responses when engine's apiType == .searchBox - Follow-up to https://github.com/mapbox/mapbox-search-ios/pull/150 ### Checklist - [X] Update `CHANGELOG` --- CHANGELOG.md | 8 ++++++++ Sources/Demo/PlaceAutocompleteDetailsViewController.swift | 6 ++++++ Sources/MapboxSearch/PublicAPI/FavoriteRecord.swift | 6 ++++++ Sources/MapboxSearch/PublicAPI/HistoryRecord.swift | 5 +++++ .../Search Results/ExternalRecordPlaceholder.swift | 4 ++-- .../Search Results/SearchCategorySuggestionImpl.swift | 4 ++-- .../PublicAPI/Search Results/SearchResult.swift | 3 +++ .../Search Results/SearchResultSuggestionImpl.swift | 4 ++-- .../PublicAPI/Search Results/SearchSuggestion.swift | 1 + .../PublicAPI/Search Results/ServerSearchResult.swift | 4 ++-- .../Use Cases/Address Autofill/AddressAutofill.swift | 3 +++ .../Address Autofill/Models/AddressAutofill+Result.swift | 5 +++++ .../Models/Suggestion/AddressAutofill+Suggestion.swift | 5 +++++ .../AddressAutofill.Suggestion+SearchResult.swift | 1 + .../Use Cases/Discover/Models/Discover+Result.swift | 4 ++++ .../Models/PlaceAutocomplete+Result.swift | 3 +++ .../Models/PlaceAutocomplete+Suggestion.swift | 8 ++++++++ .../Use Cases/Place Autocomplete/PlaceAutocomplete.swift | 1 + .../AddressAutofillIntegrationTests.swift | 3 ++- .../DiscoverIntegrationTests.swift | 2 ++ .../PlaceAutocompleteIntegrationTests.swift | 1 + .../Common/Data Samples/SearchResultStub+Samples.swift | 1 + .../Common/Models/Search Result/SearchResultTests.swift | 1 + .../Common/Stubs&Models/IndexableRecordStub.swift | 1 + .../Stubs&Models/PlaceAutocompleteSuggestionStub.swift | 1 + .../Common/Stubs&Models/SearchResultStub.swift | 4 ++++ .../Common/Stubs&Models/TestDataProviderRecord.swift | 2 +- .../Legacy/CodablePersistentServiceTests.swift | 1 + Tests/MapboxSearchTests/Legacy/FavoriteRecordTests.swift | 1 + Tests/MapboxSearchTests/Legacy/HistoryRecordTests.swift | 3 +++ 30 files changed, 86 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e84c29d83..fc4679a82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,14 @@ Guide: https://keepachangelog.com/en/1.0.0/ +- [SearchResult] Add support for `mapboxId` field when availalbe. +- [FavoriteRecord] Add support for `mapboxId` field when availalbe. +- [HistoryRecord] Add support for `mapboxId` field when availalbe. +- [Discover] Add more complete support for `mapboxId` field in Result subtype when availalbe. +- [Address Autofill] Add more complete support for `mapboxId` field in Result and Suggestion subtypes when availalbe. +- [Place Autocomplete] Add more complete support for `mapboxId` field in Result and Suggestion subtypes when availalbe. +- [Demo] Add `mapboxId` table view cell to PlaceAutocomplete detail view controller when available. + - [Offline] Remove `CoreOfflineIndexChangeEventType` extension previously used for development. - [Core] Remove usages of `@_implementationOnly import` due to compilation issue. diff --git a/Sources/Demo/PlaceAutocompleteDetailsViewController.swift b/Sources/Demo/PlaceAutocompleteDetailsViewController.swift index 4633deec7..2cec68a52 100644 --- a/Sources/Demo/PlaceAutocompleteDetailsViewController.swift +++ b/Sources/Demo/PlaceAutocompleteDetailsViewController.swift @@ -168,6 +168,12 @@ extension PlaceAutocomplete.Result { ) } + if let mapboxId { + components.append( + (name: "Mapbox ID", value: mapboxId) + ) + } + return components } } diff --git a/Sources/MapboxSearch/PublicAPI/FavoriteRecord.swift b/Sources/MapboxSearch/PublicAPI/FavoriteRecord.swift index 24b962b07..9904f2db6 100644 --- a/Sources/MapboxSearch/PublicAPI/FavoriteRecord.swift +++ b/Sources/MapboxSearch/PublicAPI/FavoriteRecord.swift @@ -8,6 +8,9 @@ public struct FavoriteRecord: IndexableRecord, SearchResult, Codable, Equatable /// Displayable name of the record. public var name: String + /// A unique identifier for the geographic feature + public var mapboxId: String? + /** The feature name, as matched by the search algorithm. @@ -79,6 +82,7 @@ public struct FavoriteRecord: IndexableRecord, SearchResult, Codable, Equatable /// - resultType: Favorite result type public init( id: String? = nil, + mapboxId: String? = nil, name: String, matchingName: String?, coordinate: CLLocationCoordinate2D, @@ -93,6 +97,7 @@ public struct FavoriteRecord: IndexableRecord, SearchResult, Codable, Equatable metadata: SearchResultMetadata? = nil ) { self.id = id ?? UUID().uuidString + self.mapboxId = mapboxId self.name = name self.matchingName = matchingName self.coordinateCodable = .init(coordinate) @@ -118,6 +123,7 @@ public struct FavoriteRecord: IndexableRecord, SearchResult, Codable, Equatable ) { self.init( id: id, + mapboxId: searchResult.mapboxId, name: name, matchingName: searchResult.matchingName, coordinate: searchResult.coordinate, diff --git a/Sources/MapboxSearch/PublicAPI/HistoryRecord.swift b/Sources/MapboxSearch/PublicAPI/HistoryRecord.swift index 4fbed4019..3acb136b6 100644 --- a/Sources/MapboxSearch/PublicAPI/HistoryRecord.swift +++ b/Sources/MapboxSearch/PublicAPI/HistoryRecord.swift @@ -20,6 +20,8 @@ public struct HistoryRecord: IndexableRecord, SearchResult, Codable, Hashable { /// Unique identifier public private(set) var id: String + public private(set) var mapboxId: String? + /// Record's name public private(set) var name: String @@ -97,6 +99,7 @@ public struct HistoryRecord: IndexableRecord, SearchResult, Codable, Hashable { /// - routablePoints: Coordinates of building entries public init( id: String = UUID().uuidString, + mapboxId: String?, name: String, matchingName: String?, serverIndex: Int?, @@ -112,6 +115,7 @@ public struct HistoryRecord: IndexableRecord, SearchResult, Codable, Hashable { routablePoints: [RoutablePoint]? = nil ) { self.id = id + self.mapboxId = mapboxId self.name = name self.matchingName = matchingName self.serverIndex = serverIndex @@ -138,6 +142,7 @@ public struct HistoryRecord: IndexableRecord, SearchResult, Codable, Hashable { timestamp: Date = Date() ) { self.id = searchResult.id + self.mapboxId = searchResult.mapboxId self.name = searchResult.name self.matchingName = searchResult.matchingName self.serverIndex = searchResult.serverIndex diff --git a/Sources/MapboxSearch/PublicAPI/Search Results/ExternalRecordPlaceholder.swift b/Sources/MapboxSearch/PublicAPI/Search Results/ExternalRecordPlaceholder.swift index 3ac5ee654..f567f91ff 100644 --- a/Sources/MapboxSearch/PublicAPI/Search Results/ExternalRecordPlaceholder.swift +++ b/Sources/MapboxSearch/PublicAPI/Search Results/ExternalRecordPlaceholder.swift @@ -2,14 +2,14 @@ import CoreLocation import Foundation class ExternalRecordPlaceholder: SearchResultSuggestion, CoreResponseProvider { - var mapboxId: String? - var originalResponse: CoreSearchResultResponse var dataLayerIdentifier: String var id: String + var mapboxId: String? + var name: String var address: Address? diff --git a/Sources/MapboxSearch/PublicAPI/Search Results/SearchCategorySuggestionImpl.swift b/Sources/MapboxSearch/PublicAPI/Search Results/SearchCategorySuggestionImpl.swift index eef83e73b..da12c829c 100644 --- a/Sources/MapboxSearch/PublicAPI/Search Results/SearchCategorySuggestionImpl.swift +++ b/Sources/MapboxSearch/PublicAPI/Search Results/SearchCategorySuggestionImpl.swift @@ -2,12 +2,12 @@ import CoreLocation import Foundation class SearchCategorySuggestionImpl: SearchCategorySuggestion, CoreResponseProvider { - var mapboxId: String? - var originalResponse: CoreSearchResultResponse var id: String + var mapboxId: String? + var name: String var address: Address? diff --git a/Sources/MapboxSearch/PublicAPI/Search Results/SearchResult.swift b/Sources/MapboxSearch/PublicAPI/Search Results/SearchResult.swift index 37c6381ac..55cd92a51 100644 --- a/Sources/MapboxSearch/PublicAPI/Search Results/SearchResult.swift +++ b/Sources/MapboxSearch/PublicAPI/Search Results/SearchResult.swift @@ -9,6 +9,9 @@ public protocol SearchResult { /// Result name. var name: String { get } + /// A unique identifier for the geographic feature + var mapboxId: String? { get } + /// Icon name according to [Mapbox Maki icon set](https://github.com/mapbox/maki/) var iconName: String? { get } diff --git a/Sources/MapboxSearch/PublicAPI/Search Results/SearchResultSuggestionImpl.swift b/Sources/MapboxSearch/PublicAPI/Search Results/SearchResultSuggestionImpl.swift index c4322650c..4808b2627 100644 --- a/Sources/MapboxSearch/PublicAPI/Search Results/SearchResultSuggestionImpl.swift +++ b/Sources/MapboxSearch/PublicAPI/Search Results/SearchResultSuggestionImpl.swift @@ -2,14 +2,14 @@ import CoreLocation import Foundation class SearchResultSuggestionImpl: SearchResultSuggestion, CoreResponseProvider { - var mapboxId: String? - var originalResponse: CoreSearchResultResponse let dataLayerIdentifier = SearchEngine.providerIdentifier var id: String + var mapboxId: String? + var name: String var address: Address? diff --git a/Sources/MapboxSearch/PublicAPI/Search Results/SearchSuggestion.swift b/Sources/MapboxSearch/PublicAPI/Search Results/SearchSuggestion.swift index 5a39ee621..907592213 100644 --- a/Sources/MapboxSearch/PublicAPI/Search Results/SearchSuggestion.swift +++ b/Sources/MapboxSearch/PublicAPI/Search Results/SearchSuggestion.swift @@ -11,6 +11,7 @@ public protocol SearchSuggestion { /// - Attention: Mapbox backend may change the identifier of the object in the future. var id: String { get } + /// A unique identifier for the geographic feature var mapboxId: String? { get } /// Suggestion name. diff --git a/Sources/MapboxSearch/PublicAPI/Search Results/ServerSearchResult.swift b/Sources/MapboxSearch/PublicAPI/Search Results/ServerSearchResult.swift index 0b3854288..cb90ac222 100644 --- a/Sources/MapboxSearch/PublicAPI/Search Results/ServerSearchResult.swift +++ b/Sources/MapboxSearch/PublicAPI/Search Results/ServerSearchResult.swift @@ -2,8 +2,6 @@ import CoreLocation import Foundation class ServerSearchResult: SearchResult, SearchResultSuggestion, CoreResponseProvider { - var mapboxId: String? - var distance: CLLocationDistance? var originalResponse: CoreSearchResultResponse @@ -37,6 +35,8 @@ class ServerSearchResult: SearchResult, SearchResultSuggestion, CoreResponseProv var id: String + var mapboxId: String? + var name: String var matchingName: String? diff --git a/Sources/MapboxSearch/PublicAPI/Use Cases/Address Autofill/AddressAutofill.swift b/Sources/MapboxSearch/PublicAPI/Use Cases/Address Autofill/AddressAutofill.swift index c3473fd1a..1a950f7b2 100644 --- a/Sources/MapboxSearch/PublicAPI/Use Cases/Address Autofill/AddressAutofill.swift +++ b/Sources/MapboxSearch/PublicAPI/Use Cases/Address Autofill/AddressAutofill.swift @@ -132,6 +132,7 @@ extension AddressAutofill { } let result = AddressAutofill.Result( name: suggestion.name, + mapboxId: suggestion.mapboxId, formattedAddress: suggestion.formattedAddress, coordinate: coordinate, addressComponents: suggestion.addressComponents @@ -248,6 +249,7 @@ extension AddressAutofill { return Suggestion( name: name, + mapboxId: result.mapboxId, formattedAddress: fullAddress, coordinate: result.center?.value, addressComponents: resultAddress, @@ -287,6 +289,7 @@ extension AddressAutofill { let autofillResult = AddressAutofill.Result( name: result.name, + mapboxId: result.mapboxId, formattedAddress: formattedAddress, coordinate: result.coordinate, addressComponents: addressComponents diff --git a/Sources/MapboxSearch/PublicAPI/Use Cases/Address Autofill/Models/AddressAutofill+Result.swift b/Sources/MapboxSearch/PublicAPI/Use Cases/Address Autofill/Models/AddressAutofill+Result.swift index 8d82bc0c1..df4a283d2 100644 --- a/Sources/MapboxSearch/PublicAPI/Use Cases/Address Autofill/Models/AddressAutofill+Result.swift +++ b/Sources/MapboxSearch/PublicAPI/Use Cases/Address Autofill/Models/AddressAutofill+Result.swift @@ -5,6 +5,9 @@ extension AddressAutofill { /// Result name. public let name: String + /// A unique identifier for the geographic feature + public let mapboxId: String? + /// Textual representation of the address. public let formattedAddress: String @@ -16,11 +19,13 @@ extension AddressAutofill { init( name: String, + mapboxId: String?, formattedAddress: String, coordinate: CLLocationCoordinate2D, addressComponents: NonEmptyArray ) { self.name = name + self.mapboxId = mapboxId self.formattedAddress = formattedAddress self.coordinate = coordinate self.addressComponents = addressComponents diff --git a/Sources/MapboxSearch/PublicAPI/Use Cases/Address Autofill/Models/Suggestion/AddressAutofill+Suggestion.swift b/Sources/MapboxSearch/PublicAPI/Use Cases/Address Autofill/Models/Suggestion/AddressAutofill+Suggestion.swift index 05d554348..278e5259f 100644 --- a/Sources/MapboxSearch/PublicAPI/Use Cases/Address Autofill/Models/Suggestion/AddressAutofill+Suggestion.swift +++ b/Sources/MapboxSearch/PublicAPI/Use Cases/Address Autofill/Models/Suggestion/AddressAutofill+Suggestion.swift @@ -6,6 +6,9 @@ extension AddressAutofill { /// Suggestion name. public let name: String + /// A unique identifier for the geographic feature + public let mapboxId: String? + /// Textual representation of the address. public let formattedAddress: String @@ -21,12 +24,14 @@ extension AddressAutofill { init( name: String, + mapboxId: String?, formattedAddress: String, coordinate: CLLocationCoordinate2D?, addressComponents: NonEmptyArray, underlying: Underlying ) { self.name = name + self.mapboxId = mapboxId self.formattedAddress = formattedAddress self.coordinate = coordinate self.addressComponents = addressComponents diff --git a/Sources/MapboxSearch/PublicAPI/Use Cases/Address Autofill/Models/Suggestion/AddressAutofill.Suggestion+SearchResult.swift b/Sources/MapboxSearch/PublicAPI/Use Cases/Address Autofill/Models/Suggestion/AddressAutofill.Suggestion+SearchResult.swift index 0d9bd80bb..b725e4a55 100644 --- a/Sources/MapboxSearch/PublicAPI/Use Cases/Address Autofill/Models/Suggestion/AddressAutofill.Suggestion+SearchResult.swift +++ b/Sources/MapboxSearch/PublicAPI/Use Cases/Address Autofill/Models/Suggestion/AddressAutofill.Suggestion+SearchResult.swift @@ -23,6 +23,7 @@ extension AddressAutofill.Suggestion { return try .init( name: searchResult.name, + mapboxId: searchResult.mapboxId, formattedAddress: formattedAddress, coordinate: searchResult.coordinate, addressComponents: address.toAutofillComponents(), diff --git a/Sources/MapboxSearch/PublicAPI/Use Cases/Discover/Models/Discover+Result.swift b/Sources/MapboxSearch/PublicAPI/Use Cases/Discover/Models/Discover+Result.swift index ef2c09638..d2fd9283e 100644 --- a/Sources/MapboxSearch/PublicAPI/Use Cases/Discover/Models/Discover+Result.swift +++ b/Sources/MapboxSearch/PublicAPI/Use Cases/Discover/Models/Discover+Result.swift @@ -6,6 +6,9 @@ extension Discover { /// Result's name public let name: String + /// A unique identifier for the geographic feature + public let mapboxId: String? + /// Result's address public let address: AddressComponents @@ -34,6 +37,7 @@ extension Discover.Result { return .init( name: searchResult.name, + mapboxId: searchResult.mapboxId, address: .init(searchResult: searchResult), coordinate: searchResult.coordinate, routablePoints: routablePointsArray, diff --git a/Sources/MapboxSearch/PublicAPI/Use Cases/Place Autocomplete/Models/PlaceAutocomplete+Result.swift b/Sources/MapboxSearch/PublicAPI/Use Cases/Place Autocomplete/Models/PlaceAutocomplete+Result.swift index b97ba0b89..afcafb3fa 100644 --- a/Sources/MapboxSearch/PublicAPI/Use Cases/Place Autocomplete/Models/PlaceAutocomplete+Result.swift +++ b/Sources/MapboxSearch/PublicAPI/Use Cases/Place Autocomplete/Models/PlaceAutocomplete+Result.swift @@ -5,6 +5,9 @@ extension PlaceAutocomplete { /// Result name. public let name: String + /// A unique identifier for the geographic feature + public let mapboxId: String? + /// Contains formatted address. public let description: String? diff --git a/Sources/MapboxSearch/PublicAPI/Use Cases/Place Autocomplete/Models/PlaceAutocomplete+Suggestion.swift b/Sources/MapboxSearch/PublicAPI/Use Cases/Place Autocomplete/Models/PlaceAutocomplete+Suggestion.swift index 193018f92..0bf179b3d 100644 --- a/Sources/MapboxSearch/PublicAPI/Use Cases/Place Autocomplete/Models/PlaceAutocomplete+Suggestion.swift +++ b/Sources/MapboxSearch/PublicAPI/Use Cases/Place Autocomplete/Models/PlaceAutocomplete+Suggestion.swift @@ -6,6 +6,9 @@ extension PlaceAutocomplete { /// Place's name. public let name: String + /// A unique identifier for the geographic feature + public let mapboxId: String? + /// Contains formatted address. public let description: String? @@ -36,6 +39,7 @@ extension PlaceAutocomplete { init( name: String, + mapboxId: String?, description: String?, coordinate: CLLocationCoordinate2D?, iconName: String?, @@ -47,6 +51,7 @@ extension PlaceAutocomplete { underlying: Underlying ) { self.name = name + self.mapboxId = mapboxId self.description = description self.coordinate = coordinate self.iconName = iconName @@ -69,6 +74,7 @@ extension PlaceAutocomplete.Suggestion { func result(for underlyingResult: SearchResult) -> PlaceAutocomplete.Result { .init( name: name, + mapboxId: underlyingResult.mapboxId, description: description, type: placeType, coordinate: coordinate, @@ -108,6 +114,7 @@ extension PlaceAutocomplete.Suggestion { return .init( name: searchResult.name, + mapboxId: searchResult.mapboxId, description: searchResult.descriptionText, coordinate: searchResult.coordinate, iconName: searchResult.iconName, @@ -136,6 +143,7 @@ extension PlaceAutocomplete.Suggestion { return .init( name: searchSuggestion.names.first ?? "", + mapboxId: searchSuggestion.mapboxId, description: searchSuggestion.addressDescription, coordinate: coordinate, iconName: searchSuggestion.icon, diff --git a/Sources/MapboxSearch/PublicAPI/Use Cases/Place Autocomplete/PlaceAutocomplete.swift b/Sources/MapboxSearch/PublicAPI/Use Cases/Place Autocomplete/PlaceAutocomplete.swift index 58b1b6141..5cae61dd2 100644 --- a/Sources/MapboxSearch/PublicAPI/Use Cases/Place Autocomplete/PlaceAutocomplete.swift +++ b/Sources/MapboxSearch/PublicAPI/Use Cases/Place Autocomplete/PlaceAutocomplete.swift @@ -317,6 +317,7 @@ extension PlaceAutocomplete { return Suggestion( name: name, + mapboxId: result.mapboxId, description: result.addressDescription, coordinate: result.center?.value, iconName: result.icon, diff --git a/Tests/MapboxSearchIntegrationTests/AddressAutofillIntegrationTests.swift b/Tests/MapboxSearchIntegrationTests/AddressAutofillIntegrationTests.swift index 89dead51c..7bb35d2d0 100644 --- a/Tests/MapboxSearchIntegrationTests/AddressAutofillIntegrationTests.swift +++ b/Tests/MapboxSearchIntegrationTests/AddressAutofillIntegrationTests.swift @@ -41,7 +41,7 @@ final class AddressAutofillIntegrationTests: MockServerIntegrationTestCase { switch result { case .success(let searchResults): XCTAssertFalse(searchResults.isEmpty) + let firstResult = searchResults.first + XCTAssertNotNil(firstResult?.mapboxId) expectation.fulfill() case .failure: XCTFail("Error not expected") diff --git a/Tests/MapboxSearchIntegrationTests/PlaceAutocompleteIntegrationTests.swift b/Tests/MapboxSearchIntegrationTests/PlaceAutocompleteIntegrationTests.swift index 895402f3c..e13e4fb18 100644 --- a/Tests/MapboxSearchIntegrationTests/PlaceAutocompleteIntegrationTests.swift +++ b/Tests/MapboxSearchIntegrationTests/PlaceAutocompleteIntegrationTests.swift @@ -62,6 +62,7 @@ final class PlaceAutocompleteIntegrationTests: MockServerIntegrationTestCase Self { .init( name: "name", + mapboxId: nil, description: "description", coordinate: CLLocationCoordinate2D(latitude: 10, longitude: 10), iconName: "iconName", diff --git a/Tests/MapboxSearchTests/Common/Stubs&Models/SearchResultStub.swift b/Tests/MapboxSearchTests/Common/Stubs&Models/SearchResultStub.swift index 47e7ef7bf..7f0500d07 100644 --- a/Tests/MapboxSearchTests/Common/Stubs&Models/SearchResultStub.swift +++ b/Tests/MapboxSearchTests/Common/Stubs&Models/SearchResultStub.swift @@ -4,6 +4,7 @@ import CoreLocation class SearchResultStub: SearchResult { init( id: String, + mapboxId: String?, accuracy: SearchResultAccuracy? = nil, categories: [String]? = nil, name: String, @@ -19,6 +20,7 @@ class SearchResultStub: SearchResult { dataLayerIdentifier: String = "unit-test-stub" ) { self.id = id + self.mapboxId = mapboxId self.accuracy = accuracy self.categories = categories self.name = name @@ -37,6 +39,7 @@ class SearchResultStub: SearchResult { var dataLayerIdentifier: String var id: String + var mapboxId: String? var accuracy: SearchResultAccuracy? var categories: [String]? var name: String @@ -68,6 +71,7 @@ extension SearchResultStub { static var `default`: SearchResultStub { SearchResultStub( id: "AddressAutofillAddressComponentTests", + mapboxId: nil, name: "AddressAutofillAddressComponentTests", matchingName: nil, serverIndex: nil, diff --git a/Tests/MapboxSearchTests/Common/Stubs&Models/TestDataProviderRecord.swift b/Tests/MapboxSearchTests/Common/Stubs&Models/TestDataProviderRecord.swift index 4e6d67a18..7b5bde27e 100644 --- a/Tests/MapboxSearchTests/Common/Stubs&Models/TestDataProviderRecord.swift +++ b/Tests/MapboxSearchTests/Common/Stubs&Models/TestDataProviderRecord.swift @@ -4,7 +4,7 @@ import CoreLocation struct TestDataProviderRecord: IndexableRecord, SearchResult { var type: SearchResultType var id: String = UUID().uuidString - var mapboxId: String = UUID().uuidString // TODO: Revisit + var mapboxId: String? var accuracy: SearchResultAccuracy? var name: String var matchingName: String? diff --git a/Tests/MapboxSearchTests/Legacy/CodablePersistentServiceTests.swift b/Tests/MapboxSearchTests/Legacy/CodablePersistentServiceTests.swift index 6b9788cc6..ae47955ae 100644 --- a/Tests/MapboxSearchTests/Legacy/CodablePersistentServiceTests.swift +++ b/Tests/MapboxSearchTests/Legacy/CodablePersistentServiceTests.swift @@ -59,6 +59,7 @@ class CodablePersistentServiceTests: XCTestCase { let coordinate = CLLocationCoordinate2D(latitude: 10.0, longitude: 10.0) let record = HistoryRecord( id: UUID().uuidString, + mapboxId: nil, name: "DaName", matchingName: nil, serverIndex: nil, diff --git a/Tests/MapboxSearchTests/Legacy/FavoriteRecordTests.swift b/Tests/MapboxSearchTests/Legacy/FavoriteRecordTests.swift index 83363642b..97b731ff0 100644 --- a/Tests/MapboxSearchTests/Legacy/FavoriteRecordTests.swift +++ b/Tests/MapboxSearchTests/Legacy/FavoriteRecordTests.swift @@ -7,6 +7,7 @@ class FavoriteRecordTests: XCTestCase { let record = FavoriteRecord(id: "unique-id", name: "Custom Name", searchResult: resultStub) XCTAssertEqual(record.id, "unique-id") + XCTAssertNotNil(record.mapboxId) XCTAssertEqual(record.name, "Custom Name") XCTAssertEqual(record.address, resultStub.address) XCTAssertEqual(record.categories, resultStub.categories) diff --git a/Tests/MapboxSearchTests/Legacy/HistoryRecordTests.swift b/Tests/MapboxSearchTests/Legacy/HistoryRecordTests.swift index 9a86ad439..b614793a0 100644 --- a/Tests/MapboxSearchTests/Legacy/HistoryRecordTests.swift +++ b/Tests/MapboxSearchTests/Legacy/HistoryRecordTests.swift @@ -5,6 +5,7 @@ class HistoryRecordTests: XCTestCase { func testHistoryRecordCategories() throws { let record = HistoryRecord( id: UUID().uuidString, + mapboxId: nil, name: "DaName", matchingName: nil, serverIndex: nil, @@ -22,6 +23,7 @@ class HistoryRecordTests: XCTestCase { func testHistoryRecordCoordinates() { var record = HistoryRecord( id: UUID().uuidString, + mapboxId: nil, name: "DaName", matchingName: nil, serverIndex: nil, @@ -43,6 +45,7 @@ class HistoryRecordTests: XCTestCase { func testHistoryRecordDescriptionText() { let record = HistoryRecord( id: UUID().uuidString, + mapboxId: nil, name: "DaName", matchingName: nil, serverIndex: nil,