From 0a5b625420ac28b7769e318bdadd0d7fa7bcca65 Mon Sep 17 00:00:00 2001 From: Roman Laitarenko Date: Tue, 1 Oct 2024 22:52:55 +0300 Subject: [PATCH] `2.3.0` release cherry-picks (#714) * Improve style image error reporting (#700) * Report error when image cannot be added to the style * Use dedicated method to check for style image * Typed `RendredQueryGeometry` (#707) * Typed `RenderedQueryGeometry` * lint * Pass job name and commit hash to firebase matrix labels * bump gcloud version * Remove unnecessary android apk build in CI * lint * Bump Maps SDK to 11.7.0 (#709) * Fix AGP 7 compatibility (#712) * Downgrade androidx.lifecycle to 2.6.2 for AGP 7 * Downgrade androidx.annotation to 1.5.0 * Downgrade AGP to 7.3.0, Gradle to 7.4.2 * Use minimum supported AGP and gradle in examples project * Downgrade CI android image to one that has Java 17 for Gradle 7.5 compatibility * Updage lockfile * Prepare 2.3.0 (#713) * Update changelog * Bump SDK version --- .circleci/config.yml | 11 ++++--- CHANGELOG.md | 26 +++++++++++---- README.md | 6 ++-- android/build.gradle | 8 ++--- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../com/mapbox/maps/mapbox_maps/Extentions.kt | 3 +- .../mapbox_maps/MapInterfaceController.kt | 4 +-- .../maps/mapbox_maps/pigeons/MapInterfaces.kt | 14 ++++---- .../gradle/wrapper/gradle-wrapper.properties | 2 +- example/android/settings.gradle | 2 +- .../integration_test/map_interface_test.dart | 18 ++++------- example/ios/Podfile.lock | 24 +++++++------- example/lib/cluster.dart | 6 ++-- example/lib/map_interface.dart | 6 ++-- example/pubspec.lock | 14 ++++---- ios/Classes/Generated/MapInterfaces.swift | 14 ++++---- ios/Classes/MapInterfaceController.swift | 17 +++++++--- ios/Classes/StyleController.swift | 14 +++++--- ios/mapbox_maps_flutter.podspec | 4 +-- lib/src/map_widget.dart | 2 +- lib/src/mapbox_map.dart | 32 ++++++++++++++++++- lib/src/pigeons/map_interfaces.dart | 14 ++++---- pubspec.yaml | 2 +- 23 files changed, 148 insertions(+), 97 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9fa0117c..27aa05fd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,7 +18,7 @@ commands: setup-gcloud: steps: - gcp-cli/setup: - version: 489.0.0 + version: 494.0.0 gcloud_service_key: GCLOUD_SERVICE_ACCOUNT_JSON add-mapbox-submodules-key: @@ -35,7 +35,7 @@ jobs: type: string default: example/build/app/outputs/apk docker: - - image: cimg/android:2024.09.1 + - image: cimg/android:2024.01.1 resource_class: 2xlarge steps: - checkout @@ -53,7 +53,6 @@ jobs: name: "Build Android integration tests" working_directory: example/android command: | - flutter build apk ./gradlew app:assembleAndroidTest --stacktrace ./gradlew app:assembleDebug -Ptarget=integration_test/all_test.dart -Pdart-defines="$(echo -n "ACCESS_TOKEN=$MAPBOX_ACCESS_TOKEN" | base64 -w 0)" --stacktrace - persist_to_workspace: @@ -85,7 +84,8 @@ jobs: --use-orchestrator \ --num-flaky-test-attempts 3 \ --no-record-video \ - --no-performance-metrics + --no-performance-metrics \ + --client-details matrixLabel="${CIRCLE_JOB}-${CIRCLE_SHA1:0:6}" build-ios: parameters: @@ -146,7 +146,8 @@ jobs: --test << parameters.workspace-path >>/build_products.zip \ --device model=iphone13pro,version=15.7 \ --timeout 5m \ - --num-flaky-test-attempts 3 2>&1 | tee firebase_test_lab_run.log + --num-flaky-test-attempts 3 \ + --client-details matrixLabel="${CIRCLE_JOB}-${CIRCLE_SHA1:0:6}" 2>&1 | tee firebase_test_lab_run.log - run: name: Download XCResults command: | diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bb99e4f..16be39de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ -### 2.3.0-rc.1 +# 2.3.0 +* Deprecate untyped default constructor of `RenderedQueryGeometry` with typed constructors: `RenderedQueryGeometry.fromList()/fromScreenBox()/fromScreenCoordinate()`. + +This change improves type safety and clarity in the code. By using specific constructors, you can ensure that the `RenderedQueryGeometry` is created with the correct type of data, reducing the risk of runtime errors and making the code easier to understand and maintain. + +**Example:** + +*Before:* +```dart +// Using the untyped default constructor +final geometry = RenderedQueryGeometry(type: Type.SCREEN_COORDINATE, value jsonEncode(screenCoordinate.encode())); +``` + +*After:* +```dart +// Using a typed constructor +final geometry = RenderedQueryGeometry.fromScreenCoordinate(screenCoordinate); +``` * Expose API to clear map data, and to set options to `TileStore`. You can now clear temporary map data from the data path defined in the given resource options, which is useful when you want reduce the disk usage or in case the disk cache contains invalid data. @@ -13,7 +30,6 @@ And you can now set additional options to a `TileStore`, for example, a maximum // This removes the tiles from the predictive cache. tileStore.setDiskQuota(0); ``` - * Add support for partial GeoJSON updates. Instead of setting a whole new GeoJSON object anew every time a single feature has changed, now you can apply more granular, partial GeoJSON updates. @@ -51,13 +67,9 @@ circleAnnotationManager.setCircleColor(Colors.blue.value); * Expose experimental `lineTrimColor` and `lineTrimFadeRange` on `LineLayer` which allow to set custom color for trimmed line and fade effect for trim. * Add experimental `FillExtrusionLayer.fillExtrusionLineWidth` that can switch fill extrusion rendering into wall rendering mode. Use this property to render the feature with the given width over the outlines of the geometry. * Add experimental `MapboxMap.setSnapshotLegacyMode()` to help avoiding `MapboxMap.snapshot()` native crash on some Samsung devices running Android 14. `MapboxMap.setSnapshotLegacyMode()` has no effect on iOS. -* Bump Maps SDK to 11.7.0-rc.1 - -### 2.3.0-beta.1 - * Fix build errors when using Flutter SDK 3.24. * Add `GestureState` to `MapContentGestureContext` to indicate whether gesture has been started, its touches have changed or it has ended. -* Bump Maps SDK to 11.7.0-beta.1 +* Bump Maps SDK to 11.7.0. ### 2.2.0 diff --git a/README.md b/README.md index ba1e841a..31b9d0dc 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Mapbox Maps SDK Flutter SDK -The Mapbox Maps SDK Flutter SDK is an officially developed solution from Mapbox that enables use of our latest Maps SDK product (v11.7.0-rc.1). The SDK allows developers to embed highly-customized maps using a Flutter widget on Android and iOS. +The Mapbox Maps SDK Flutter SDK is an officially developed solution from Mapbox that enables use of our latest Maps SDK product (v11.7.0). The SDK allows developers to embed highly-customized maps using a Flutter widget on Android and iOS. Web and desktop are not supported. @@ -113,7 +113,7 @@ To use the Maps Flutter SDK add the git dependency to the pubspec.yaml: ``` dependencies: - mapbox_maps_flutter: ^2.3.0-rc.1 + mapbox_maps_flutter: ^2.3.0 ``` ### Configure permissions @@ -160,7 +160,7 @@ The `MapboxMap` controller instance is provided with `MapWidget.onMapCreated` ca `MapboxMap` exposes an entry point to the most of the APIs Maps Flutter SDK provides. It allows to control the map, camera, styles, observe map events, query rendered features, etc. -It's organized similarly to the [Android](https://docs.mapbox.com/android/maps/api/11.5.0/mapbox-maps-android/com.mapbox.maps/-mapbox-map/) and [iOS](https://docs.mapbox.com/ios/maps/api/11.5.0/documentation/mapboxmaps/mapboxmap) counterparts. +It's organized similarly to the [Android](https://docs.mapbox.com/android/maps/api/11.7.0/mapbox-maps-android/com.mapbox.maps/-mapbox-map/) and [iOS](https://docs.mapbox.com/ios/maps/api/11.7.0/documentation/mapboxmaps/mapboxmap) counterparts. To interact with the map after it's created store the MapboxMap object somewhere : ``` diff --git a/android/build.gradle b/android/build.gradle index 3895ec16..990e8afb 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -9,7 +9,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath 'com.android.tools.build:gradle:7.3.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } @@ -78,8 +78,8 @@ if (file("$rootDir/gradle/ktlint.gradle").exists() && file("$rootDir/gradle/lint } dependencies { - implementation "com.mapbox.maps:android:11.7.0-rc.1" + implementation "com.mapbox.maps:android:11.7.0" - implementation "androidx.annotation:annotation:1.8.2" - implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.8.4" + implementation "androidx.annotation:annotation:1.5.0" + implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.6.2" } diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 567ad65a..111c25e7 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip diff --git a/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/Extentions.kt b/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/Extentions.kt index 32b428ec..d7f7d1fa 100644 --- a/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/Extentions.kt +++ b/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/Extentions.kt @@ -12,7 +12,6 @@ import com.mapbox.maps.EdgeInsets import com.mapbox.maps.StylePackError import com.mapbox.maps.applyDefaultParams import com.mapbox.maps.debugoptions.MapViewDebugOptions -import com.mapbox.maps.extension.style.expressions.dsl.generated.min import com.mapbox.maps.extension.style.layers.properties.generated.ProjectionName import com.mapbox.maps.extension.style.light.LightPosition import com.mapbox.maps.extension.style.light.generated.ambientLight @@ -235,7 +234,7 @@ fun SourceQueryOptions.toSourceQueryOptions(): com.mapbox.maps.SourceQueryOption return com.mapbox.maps.SourceQueryOptions(sourceLayerIds, filter.toValue()) } -fun RenderedQueryGeometry.toRenderedQueryGeometry(context: Context): com.mapbox.maps.RenderedQueryGeometry { +fun _RenderedQueryGeometry.toRenderedQueryGeometry(context: Context): com.mapbox.maps.RenderedQueryGeometry { return when (type) { Type.SCREEN_BOX -> com.mapbox.maps.RenderedQueryGeometry.valueOf( Gson().fromJson( diff --git a/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/MapInterfaceController.kt b/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/MapInterfaceController.kt index 2b1ed93d..e2c3b36e 100644 --- a/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/MapInterfaceController.kt +++ b/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/MapInterfaceController.kt @@ -16,7 +16,6 @@ import com.mapbox.maps.mapbox_maps.pigeons.MapOptions import com.mapbox.maps.mapbox_maps.pigeons.NorthOrientation import com.mapbox.maps.mapbox_maps.pigeons.QueriedRenderedFeature import com.mapbox.maps.mapbox_maps.pigeons.QueriedSourceFeature -import com.mapbox.maps.mapbox_maps.pigeons.RenderedQueryGeometry import com.mapbox.maps.mapbox_maps.pigeons.RenderedQueryOptions import com.mapbox.maps.mapbox_maps.pigeons.Size import com.mapbox.maps.mapbox_maps.pigeons.SourceQueryOptions @@ -26,6 +25,7 @@ import com.mapbox.maps.mapbox_maps.pigeons.TileCoverOptions import com.mapbox.maps.mapbox_maps.pigeons.ViewportMode import com.mapbox.maps.mapbox_maps.pigeons._MapInterface import com.mapbox.maps.mapbox_maps.pigeons._MapWidgetDebugOptionsBox +import com.mapbox.maps.mapbox_maps.pigeons._RenderedQueryGeometry import com.mapbox.maps.plugin.delegates.listeners.OnMapLoadErrorListener class MapInterfaceController( @@ -142,7 +142,7 @@ class MapInterfaceController( } override fun queryRenderedFeatures( - geometry: RenderedQueryGeometry, + geometry: _RenderedQueryGeometry, options: RenderedQueryOptions, callback: (Result>) -> Unit ) { diff --git a/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/pigeons/MapInterfaces.kt b/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/pigeons/MapInterfaces.kt index b56edebf..09839412 100644 --- a/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/pigeons/MapInterfaces.kt +++ b/android/src/main/kotlin/com/mapbox/maps/mapbox_maps/pigeons/MapInterfaces.kt @@ -1378,7 +1378,7 @@ data class QueriedFeature( * * Generated class from Pigeon that represents data sent in messages. */ -data class RenderedQueryGeometry( +data class _RenderedQueryGeometry( /** ScreenCoordinate/List/ScreenBox in Json mode. */ val value: String, val type: Type @@ -1386,10 +1386,10 @@ data class RenderedQueryGeometry( ) { companion object { @Suppress("LocalVariableName") - fun fromList(__pigeon_list: List): RenderedQueryGeometry { + fun fromList(__pigeon_list: List): _RenderedQueryGeometry { val value = __pigeon_list[0] as String val type = __pigeon_list[1] as Type - return RenderedQueryGeometry(value, type) + return _RenderedQueryGeometry(value, type) } } fun toList(): List { @@ -2005,7 +2005,7 @@ private object MapInterfacesPigeonCodec : StandardMessageCodec() { } 156.toByte() -> { return (readValue(buffer) as? List)?.let { - RenderedQueryGeometry.fromList(it) + _RenderedQueryGeometry.fromList(it) } } 157.toByte() -> { @@ -2296,7 +2296,7 @@ private object MapInterfacesPigeonCodec : StandardMessageCodec() { stream.write(155) writeValue(stream, value.toList()) } - is RenderedQueryGeometry -> { + is _RenderedQueryGeometry -> { stream.write(156) writeValue(stream, value.toList()) } @@ -3211,7 +3211,7 @@ interface _MapInterface { * @param completion The `query features completion` called when the query completes. * @return A `cancelable` object that could be used to cancel the pending query. */ - fun queryRenderedFeatures(geometry: RenderedQueryGeometry, options: RenderedQueryOptions, callback: (Result>) -> Unit) + fun queryRenderedFeatures(geometry: _RenderedQueryGeometry, options: RenderedQueryOptions, callback: (Result>) -> Unit) /** * Queries the map for source features. * @@ -3678,7 +3678,7 @@ interface _MapInterface { if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List - val geometryArg = args[0] as RenderedQueryGeometry + val geometryArg = args[0] as _RenderedQueryGeometry val optionsArg = args[1] as RenderedQueryOptions api.queryRenderedFeatures(geometryArg, optionsArg) { result: Result> -> val error = result.exceptionOrNull() diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index 815eca31..f58dbd5d 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Tue Apr 30 20:27:36 EEST 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/example/android/settings.gradle b/example/android/settings.gradle index 59b3a0b3..f3dd9b24 100644 --- a/example/android/settings.gradle +++ b/example/android/settings.gradle @@ -18,7 +18,7 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "8.3.2" apply false + id "com.android.application" version "7.3.0" apply false id "org.jetbrains.kotlin.android" version "1.8.22" apply false } diff --git a/example/integration_test/map_interface_test.dart b/example/integration_test/map_interface_test.dart index 96a44396..03fc3951 100644 --- a/example/integration_test/map_interface_test.dart +++ b/example/integration_test/map_interface_test.dart @@ -326,8 +326,7 @@ void main() { var screenBox = ScreenBox( min: ScreenCoordinate(x: 0.0, y: 0.0), max: ScreenCoordinate(x: 500.0, y: 1000.0)); - var renderedQueryGeometry = RenderedQueryGeometry( - value: json.encode(screenBox.toJson()), type: Type.SCREEN_BOX); + var renderedQueryGeometry = RenderedQueryGeometry.fromScreenBox(screenBox); var query = await mapboxMap.queryRenderedFeatures(renderedQueryGeometry, RenderedQueryOptions(layerIds: ['points'], filter: null)); expect(query.length, greaterThan(0)); @@ -335,18 +334,15 @@ void main() { expect(query[0]!.queriedFeature.feature['id'], 'point'); query = await mapboxMap.queryRenderedFeatures( - RenderedQueryGeometry( - value: json.encode(ScreenCoordinate(x: 0.0, y: 0.0).toJson()), - type: Type.SCREEN_COORDINATE), + RenderedQueryGeometry.fromScreenCoordinate( + ScreenCoordinate(x: 0.0, y: 0.0)), RenderedQueryOptions(layerIds: ['points'], filter: null)); expect(query.length, 0); query = await mapboxMap.queryRenderedFeatures( - RenderedQueryGeometry( - value: json.encode([ - ScreenCoordinate(x: 0.0, y: 0.0).toJson(), - ScreenCoordinate(x: 1.0, y: 1.0).toJson() - ]), - type: Type.LIST), + RenderedQueryGeometry.fromList([ + ScreenCoordinate(x: 0.0, y: 0.0), + ScreenCoordinate(x: 1.0, y: 1.0), + ]), RenderedQueryOptions(layerIds: ['points'], filter: null)); expect(query.length, 0); }); diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index ea68f37f..05373fdb 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -2,16 +2,16 @@ PODS: - Flutter (1.0.0) - integration_test (0.0.1): - Flutter - - mapbox_maps_flutter (2.3.0-beta.1): + - mapbox_maps_flutter (2.3.0): - Flutter - - MapboxMaps (~> 11.7.0-rc.1) + - MapboxMaps (~> 11.7.0) - Turf (= 3.0.0) - - MapboxCommon (24.7.0-rc.2) - - MapboxCoreMaps (11.7.0-rc.2): - - MapboxCommon (~> 24.7.0-rc) - - MapboxMaps (11.7.0-rc.1): - - MapboxCommon (= 24.7.0-rc.2) - - MapboxCoreMaps (= 11.7.0-rc.2) + - MapboxCommon (24.7.0) + - MapboxCoreMaps (11.7.0): + - MapboxCommon (~> 24.7) + - MapboxMaps (11.7.0): + - MapboxCommon (= 24.7.0) + - MapboxCoreMaps (= 11.7.0) - Turf (= 3.0.0) - path_provider_foundation (0.0.1): - Flutter @@ -49,10 +49,10 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573 - mapbox_maps_flutter: 0c0afaaa72413cb02b70126646d79bfff9094ca0 - MapboxCommon: 85c133c17aa073d6d57a14ee5676a2236d3df35a - MapboxCoreMaps: 35061f7cacdfc22accd89b2218bc66af1939f380 - MapboxMaps: 1ab65689c868ac0c1065342ba840818087f1486b + mapbox_maps_flutter: fb6e57802405af69ecd96a9a2c7cdf9c756c4985 + MapboxCommon: fbc1138a831f4c1b728167c3f49701fe3a9aeed1 + MapboxCoreMaps: 8946c9fa51e588d594ee6ebf192d9942368abb6a + MapboxMaps: bf9f775d921ed357ae642c379ebad90550cdb9de path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6 Turf: a1604e74adce15c58462c9ae2acdbf049d5be35e diff --git a/example/lib/cluster.dart b/example/lib/cluster.dart index a2929d82..e15333f6 100644 --- a/example/lib/cluster.dart +++ b/example/lib/cluster.dart @@ -87,11 +87,11 @@ class StyleClustersPageBodyState extends State { return TextButton( child: Text('queryRenderedFeatures'), onPressed: () { - var screenBox = ScreenBox( + final screenBox = ScreenBox( min: ScreenCoordinate(x: 0.0, y: 0.0), max: ScreenCoordinate(x: 150.0, y: 510.0)); - var renderedQueryGeometry = RenderedQueryGeometry( - value: json.encode(screenBox.toJson()), type: Type.SCREEN_BOX); + final renderedQueryGeometry = + RenderedQueryGeometry.fromScreenBox(screenBox); mapboxMap ?.queryRenderedFeatures(renderedQueryGeometry, RenderedQueryOptions(layerIds: ['clusters'], filter: null)) diff --git a/example/lib/map_interface.dart b/example/lib/map_interface.dart index 9466531a..52647e5d 100644 --- a/example/lib/map_interface.dart +++ b/example/lib/map_interface.dart @@ -278,11 +278,11 @@ class MapInterfacePageBodyState extends State { return TextButton( child: Text('queryRenderedFeatures'), onPressed: () { - var screenBox = ScreenBox( + final screenBox = ScreenBox( min: ScreenCoordinate(x: 0.0, y: 0.0), max: ScreenCoordinate(x: 150.0, y: 510.0)); - var renderedQueryGeometry = RenderedQueryGeometry( - value: json.encode(screenBox.toJson()), type: Type.SCREEN_BOX); + final renderedQueryGeometry = + RenderedQueryGeometry.fromScreenBox(screenBox); mapboxMap ?.queryRenderedFeatures( renderedQueryGeometry, diff --git a/example/pubspec.lock b/example/pubspec.lock index 0f71ae72..e25ef9e7 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -111,10 +111,10 @@ packages: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: "9ee02950848f61c4129af3d6ec84a1cfc0e47931abc746b03e7a3bc3e8ff6eda" + sha256: "8cf40eebf5dec866a6d1956ad7b4f7016e6c0cc69847ab946833b7d43743809f" url: "https://pub.dev" source: hosted - version: "2.0.22" + version: "2.0.19" flutter_test: dependency: "direct dev" description: flutter @@ -200,7 +200,7 @@ packages: path: ".." relative: true source: path - version: "2.3.0-rc.1" + version: "2.3.0" matcher: dependency: transitive description: @@ -245,10 +245,10 @@ packages: dependency: transitive description: name: path_provider_android - sha256: "6f01f8e37ec30b07bc424b4deabac37cacb1bc7e2e515ad74486039918a37eb7" + sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d url: "https://pub.dev" source: hosted - version: "2.2.10" + version: "2.2.4" path_provider_foundation: dependency: transitive description: @@ -487,5 +487,5 @@ packages: source: hosted version: "1.0.4" sdks: - dart: ">=3.4.0 <4.0.0" - flutter: ">=3.22.0" + dart: ">=3.3.0 <4.0.0" + flutter: ">=3.18.0-18.0.pre.54" diff --git a/ios/Classes/Generated/MapInterfaces.swift b/ios/Classes/Generated/MapInterfaces.swift index a85b45f3..95000dd1 100644 --- a/ios/Classes/Generated/MapInterfaces.swift +++ b/ios/Classes/Generated/MapInterfaces.swift @@ -1196,17 +1196,17 @@ struct QueriedFeature { /// Geometry for querying rendered features. /// /// Generated class from Pigeon that represents data sent in messages. -struct RenderedQueryGeometry { +struct _RenderedQueryGeometry { /// ScreenCoordinate/List/ScreenBox in Json mode. var value: String var type: Type // swift-format-ignore: AlwaysUseLowerCamelCase - static func fromList(_ __pigeon_list: [Any?]) -> RenderedQueryGeometry? { + static func fromList(_ __pigeon_list: [Any?]) -> _RenderedQueryGeometry? { let value = __pigeon_list[0] as! String let type = __pigeon_list[1] as! Type - return RenderedQueryGeometry( + return _RenderedQueryGeometry( value: value, type: type ) @@ -1750,7 +1750,7 @@ private class MapInterfacesPigeonCodecReader: FlutterStandardReader { case 155: return QueriedFeature.fromList(self.readValue() as! [Any?]) case 156: - return RenderedQueryGeometry.fromList(self.readValue() as! [Any?]) + return _RenderedQueryGeometry.fromList(self.readValue() as! [Any?]) case 157: return ProjectedMeters.fromList(self.readValue() as! [Any?]) case 158: @@ -2020,7 +2020,7 @@ private class MapInterfacesPigeonCodecWriter: FlutterStandardWriter { } else if let value = value as? QueriedFeature { super.writeByte(155) super.writeValue(value.toList()) - } else if let value = value as? RenderedQueryGeometry { + } else if let value = value as? _RenderedQueryGeometry { super.writeByte(156) super.writeValue(value.toList()) } else if let value = value as? ProjectedMeters { @@ -2926,7 +2926,7 @@ protocol _MapInterface { /// @param options The `render query options` for querying rendered features. /// @param completion The `query features completion` called when the query completes. /// @return A `cancelable` object that could be used to cancel the pending query. - func queryRenderedFeatures(geometry: RenderedQueryGeometry, options: RenderedQueryOptions, completion: @escaping (Result<[QueriedRenderedFeature?], Error>) -> Void) + func queryRenderedFeatures(geometry: _RenderedQueryGeometry, options: RenderedQueryOptions, completion: @escaping (Result<[QueriedRenderedFeature?], Error>) -> Void) /// Queries the map for source features. /// /// @param sourceId The style source identifier used to query for source features. @@ -3370,7 +3370,7 @@ class _MapInterfaceSetup { if let api = api { queryRenderedFeaturesChannel.setMessageHandler { message, reply in let args = message as! [Any?] - let geometryArg = args[0] as! RenderedQueryGeometry + let geometryArg = args[0] as! _RenderedQueryGeometry let optionsArg = args[1] as! RenderedQueryOptions api.queryRenderedFeatures(geometry: geometryArg, options: optionsArg) { result in switch result { diff --git a/ios/Classes/MapInterfaceController.swift b/ios/Classes/MapInterfaceController.swift index 753dbdd7..5cf1f539 100644 --- a/ios/Classes/MapInterfaceController.swift +++ b/ios/Classes/MapInterfaceController.swift @@ -140,14 +140,16 @@ final class MapInterfaceController: _MapInterface { self.mapboxMap.debugOptions = debugOptions.compactMap {$0?.toMapDebugOptions()} } - func queryRenderedFeatures(geometry: RenderedQueryGeometry, options: RenderedQueryOptions, completion: @escaping (Result<[QueriedRenderedFeature?], Error>) -> Void) { + func queryRenderedFeatures(geometry: _RenderedQueryGeometry, options: RenderedQueryOptions, completion: @escaping (Result<[QueriedRenderedFeature?], Error>) -> Void) { do { - if geometry.type == .sCREENBOX { + switch geometry.type { + case .sCREENBOX: let screenBoxArray = convertStringToDictionary(properties: geometry.value) guard let minCoord = screenBoxArray["min"] as? [String: Double] else { return } guard let maxCoord = screenBoxArray["max"] as? [String: Double] else { return } guard let minX = minCoord["x"], let minY = minCoord["y"], let maxX = maxCoord["x"], let maxY = maxCoord["y"] else { + completion(.failure(FlutterError(code: MapInterfaceController.errorCode, message: "Geometry format error", details: geometry.value))) return } let screenBox = ScreenBox(min: ScreenCoordinate(x: minX, y: minY), @@ -162,9 +164,10 @@ final class MapInterfaceController: _MapInterface { completion(.failure(FlutterError(code: MapInterfaceController.errorCode, message: "\(error)", details: nil))) } } - } else if geometry.type == .sCREENCOORDINATE { + case .sCREENCOORDINATE: guard let pointDict = convertStringToDictionary(properties: geometry.value) as? [String: Double], let x = pointDict["x"], let y = pointDict["y"] else { + completion(.failure(FlutterError(code: MapInterfaceController.errorCode, message: "Geometry format error", details: geometry.value))) return } let cgPoint = CGPoint(x: x, y: y) @@ -177,8 +180,12 @@ final class MapInterfaceController: _MapInterface { completion(.failure(FlutterError(code: MapInterfaceController.errorCode, message: "\(error)", details: nil))) } } - } else { - let rawPoints = try JSONDecoder().decode([[String: Double]].self, from: geometry.value.data(using: String.Encoding.utf8)!) + case .lIST: + guard let data = geometry.value.data(using: .utf8), + let rawPoints = try? JSONDecoder().decode([[String: Double]].self, from: data) else { + completion(.failure(FlutterError(code: MapInterfaceController.errorCode, message: "Geometry format error", details: geometry.value))) + return + } let cgPoints = rawPoints.compactMap { guard let x = $0["x"], let y = $0["y"] else { return Optional.none } return CGPoint(x: x, y: y) diff --git a/ios/Classes/StyleController.swift b/ios/Classes/StyleController.swift index dbe11f90..d2311459 100644 --- a/ios/Classes/StyleController.swift +++ b/ios/Classes/StyleController.swift @@ -226,7 +226,10 @@ final class StyleController: StyleManager { } func updateStyleImageSourceImage(sourceId: String, image: MbxImage, completion: @escaping (Result) -> Void) { - guard let image = UIImage(data: image.data.data, scale: UIScreen.main.scale) else { return } + guard let image = UIImage(data: image.data.data, scale: UIScreen.main.scale) else { + completion(.failure(FlutterError(code: StyleController.errorCode, message: "Could not initialize the image from the specified data.", details: nil))) + return + } do { try styleManager.updateImageSource(withId: sourceId, image: image) completion(.success(())) @@ -295,7 +298,10 @@ final class StyleController: StyleManager { } func addStyleImage(imageId: String, scale: Double, image: MbxImage, sdf: Bool, stretchX: [ImageStretches?], stretchY: [ImageStretches?], content: ImageContent?, completion: @escaping (Result) -> Void) { - guard let image = UIImage(data: image.data.data, scale: scale) else { return } + guard let image = UIImage(data: image.data.data, scale: scale) else { + completion(.failure(FlutterError(code: StyleController.errorCode, message: "Could not initialize the image from the specified data.", details: nil))) + return + } var imageContent: MapboxMaps.ImageContent? if let content { imageContent = MapboxMaps.ImageContent(left: Float(content.left), @@ -329,8 +335,8 @@ final class StyleController: StyleManager { } func hasStyleImage(imageId: String, completion: @escaping (Result) -> Void) { - let image = styleManager.image(withId: imageId) - completion(.success(image != nil)) + let imageExists = styleManager.imageExists(withId: imageId) + completion(.success(imageExists)) } func invalidateStyleCustomGeometrySourceTile(sourceId: String, tileId: CanonicalTileID, completion: @escaping (Result) -> Void) { diff --git a/ios/mapbox_maps_flutter.podspec b/ios/mapbox_maps_flutter.podspec index 11b3b998..8b77638b 100644 --- a/ios/mapbox_maps_flutter.podspec +++ b/ios/mapbox_maps_flutter.podspec @@ -4,7 +4,7 @@ # Pod::Spec.new do |s| s.name = 'mapbox_maps_flutter' - s.version = '2.3.0-rc.1' + s.version = '2.3.0' s.summary = 'Mapbox Maps SDK Flutter Plugin.' s.description = 'An officially developed solution from Mapbox that enables use of our latest Maps SDK product.' @@ -17,7 +17,7 @@ Pod::Spec.new do |s| s.dependency 'Flutter' s.platform = :ios, '12.0' - s.dependency 'MapboxMaps', '~> 11.7.0-rc.1' + s.dependency 'MapboxMaps', '~> 11.7.0' s.dependency 'Turf', '3.0.0' # Flutter.framework does not contain a i386 slice. diff --git a/lib/src/map_widget.dart b/lib/src/map_widget.dart index 95889763..c9f40f7d 100644 --- a/lib/src/map_widget.dart +++ b/lib/src/map_widget.dart @@ -185,7 +185,7 @@ class _MapWidgetState extends State { 'textureView': widget.textureView, 'styleUri': widget.styleUri, 'channelSuffix': _suffix, - 'mapboxPluginVersion': '2.3.0-rc.1', + 'mapboxPluginVersion': '2.3.0', 'eventTypes': _events.eventTypes.map((e) => e.index).toList(), }; diff --git a/lib/src/mapbox_map.dart b/lib/src/mapbox_map.dart index 9d80f33c..8d2be21d 100644 --- a/lib/src/mapbox_map.dart +++ b/lib/src/mapbox_map.dart @@ -1,5 +1,33 @@ part of mapbox_maps_flutter; +/// Geometry for querying rendered features. +class RenderedQueryGeometry { + @Deprecated( + 'Use RenderedQueryGeometry.fromList()/fromScreenBox()/fromScreenCoordinated() instead') + RenderedQueryGeometry({ + required this.value, + required this.type, + }); + + RenderedQueryGeometry.fromList(List points) + : value = jsonEncode(points.map((e) => e.toJson()).toList()), + type = Type.LIST; + + RenderedQueryGeometry.fromScreenBox(ScreenBox box) + : value = jsonEncode(box.toJson()), + type = Type.SCREEN_BOX; + + RenderedQueryGeometry.fromScreenCoordinate(ScreenCoordinate point) + : value = jsonEncode(point.toJson()), + type = Type.SCREEN_COORDINATE; + + /// ScreenCoordinate/List/ScreenBox in Json mode. + String value; + + /// Type of the geometry encoded in [value]. + Type type; +} + /// Options for enabling debugging features in a map. class MapWidgetDebugOptions { final _MapWidgetDebugOptions option; @@ -386,7 +414,9 @@ class MapboxMap extends ChangeNotifier { /// Queries the map for rendered features. Future> queryRenderedFeatures( RenderedQueryGeometry geometry, RenderedQueryOptions options) => - _mapInterface.queryRenderedFeatures(geometry, options); + _mapInterface.queryRenderedFeatures( + _RenderedQueryGeometry(value: geometry.value, type: geometry.type), + options); /// Queries the map for source features. Future> querySourceFeatures( diff --git a/lib/src/pigeons/map_interfaces.dart b/lib/src/pigeons/map_interfaces.dart index ccdbf83f..5c76cf4e 100644 --- a/lib/src/pigeons/map_interfaces.dart +++ b/lib/src/pigeons/map_interfaces.dart @@ -1285,8 +1285,8 @@ class QueriedFeature { } /// Geometry for querying rendered features. -class RenderedQueryGeometry { - RenderedQueryGeometry({ +class _RenderedQueryGeometry { + _RenderedQueryGeometry({ required this.value, required this.type, }); @@ -1303,9 +1303,9 @@ class RenderedQueryGeometry { ]; } - static RenderedQueryGeometry decode(Object result) { + static _RenderedQueryGeometry decode(Object result) { result as List; - return RenderedQueryGeometry( + return _RenderedQueryGeometry( value: result[0]! as String, type: result[1]! as Type, ); @@ -1919,7 +1919,7 @@ class MapInterfaces_PigeonCodec extends StandardMessageCodec { } else if (value is QueriedFeature) { buffer.putUint8(155); writeValue(buffer, value.encode()); - } else if (value is RenderedQueryGeometry) { + } else if (value is _RenderedQueryGeometry) { buffer.putUint8(156); writeValue(buffer, value.encode()); } else if (value is ProjectedMeters) { @@ -2090,7 +2090,7 @@ class MapInterfaces_PigeonCodec extends StandardMessageCodec { case 155: return QueriedFeature.decode(readValue(buffer)!); case 156: - return RenderedQueryGeometry.decode(readValue(buffer)!); + return _RenderedQueryGeometry.decode(readValue(buffer)!); case 157: return ProjectedMeters.decode(readValue(buffer)!); case 158: @@ -3635,7 +3635,7 @@ class _MapInterface { /// @param completion The `query features completion` called when the query completes. /// @return A `cancelable` object that could be used to cancel the pending query. Future> queryRenderedFeatures( - RenderedQueryGeometry geometry, RenderedQueryOptions options) async { + _RenderedQueryGeometry geometry, RenderedQueryOptions options) async { final String __pigeon_channelName = 'dev.flutter.pigeon.mapbox_maps_flutter._MapInterface.queryRenderedFeatures$__pigeon_messageChannelSuffix'; final BasicMessageChannel __pigeon_channel = diff --git a/pubspec.yaml b/pubspec.yaml index 4e2f0ec1..6684b56a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: mapbox_maps_flutter description: Interactive, thoroughly customizable maps powered by Mapbox Maps mobile SDKs. -version: 2.3.0-rc.1 +version: 2.3.0 homepage: https://github.com/mapbox/mapbox-maps-flutter environment: