From b37669360566551b92115eb4cf9c4fe3b3fb82a3 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 26 Apr 2022 16:50:07 -0700 Subject: [PATCH 1/7] draft remove unnecessary static funcctions clean up method name and remove unused code update version remove all static methods fix remove unnecessary imports review part 1 review 2 drat 2 format, crash, more tests --- .../google_maps_flutter/CHANGELOG.md | 1 + .../ios/Runner.xcodeproj/project.pbxproj | 8 + ...TGoogleMapJSONConversionsConversionTests.m | 291 +++++++++++ .../FLTGoogleMapTileOverlayController.h | 11 +- .../FLTGoogleMapTileOverlayController.m | 120 ++--- .../ios/Classes/FLTGoogleMapsPlugin.h | 4 + .../ios/Classes/FLTGoogleMapsPlugin.m | 14 +- .../ios/Classes/GoogleMapCircleController.h | 9 +- .../ios/Classes/GoogleMapCircleController.m | 192 ++++---- .../ios/Classes/GoogleMapController.h | 2 +- .../ios/Classes/GoogleMapController.m | 456 +++++++---------- .../ios/Classes/GoogleMapMarkerController.h | 31 +- .../ios/Classes/GoogleMapMarkerController.m | 466 +++++++++--------- .../ios/Classes/GoogleMapPolygonController.h | 9 +- .../ios/Classes/GoogleMapPolygonController.m | 202 ++++---- .../ios/Classes/GoogleMapPolylineController.h | 9 +- .../ios/Classes/GoogleMapPolylineController.m | 183 +++---- .../ios/Classes/JsonConversions.h | 33 +- .../ios/Classes/JsonConversions.m | 137 +++-- 19 files changed, 1245 insertions(+), 933 deletions(-) create mode 100644 packages/google_maps_flutter/google_maps_flutter/example/ios/RunnerTests/FLTGoogleMapJSONConversionsConversionTests.m diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md index b4fb6622edc2..62cc7a25b3af 100644 --- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md @@ -3,6 +3,7 @@ * Fixes issue in Flutter v3.0.0 where some updates to the map don't take effect on Android. * Fixes iOS native unit tests on M1 devices. * Minor fixes for new analysis options. +* Objective-C code cleanup. ## 2.1.5 diff --git a/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner.xcodeproj/project.pbxproj b/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner.xcodeproj/project.pbxproj index a8d37106bb83..b37246b98a47 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/google_maps_flutter/google_maps_flutter/example/ios/Runner.xcodeproj/project.pbxproj @@ -10,6 +10,8 @@ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 4510D964F3B1259FEDD3ABA6 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7755F8F4BABC3D6A0BD4048B /* libPods-Runner.a */; }; + 6851F3562835BC180032B7C8 /* FLTGoogleMapJSONConversionsConversionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6851F3552835BC180032B7C8 /* FLTGoogleMapJSONConversionsConversionTests.m */; }; + 68E4726A2836FF0C00BDDDAC /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 68E472692836FF0C00BDDDAC /* MapKit.framework */; }; 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; @@ -55,6 +57,8 @@ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 6851F3552835BC180032B7C8 /* FLTGoogleMapJSONConversionsConversionTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLTGoogleMapJSONConversionsConversionTests.m; sourceTree = ""; }; + 68E472692836FF0C00BDDDAC /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.0.sdk/System/iOSSupport/System/Library/Frameworks/MapKit.framework; sourceTree = DEVELOPER_DIR; }; 733AFAB37683A9DA7512F09C /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; 7755F8F4BABC3D6A0BD4048B /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; @@ -95,6 +99,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 68E4726A2836FF0C00BDDDAC /* MapKit.framework in Frameworks */, FC8F35FC8CD533B128950487 /* libPods-RunnerTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -112,6 +117,7 @@ 1E7CF0857EFC88FC263CF3B2 /* Frameworks */ = { isa = PBXGroup; children = ( + 68E472692836FF0C00BDDDAC /* MapKit.framework */, 7755F8F4BABC3D6A0BD4048B /* libPods-Runner.a */, F267F68029D1A4E2E4C572A7 /* libPods-RunnerTests.a */, ); @@ -190,6 +196,7 @@ F7151F11265D7ED70028CB91 /* RunnerTests */ = { isa = PBXGroup; children = ( + 6851F3552835BC180032B7C8 /* FLTGoogleMapJSONConversionsConversionTests.m */, F7151F12265D7ED70028CB91 /* GoogleMapsTests.m */, 982F2A6A27BADE17003C81F4 /* PartiallyMockedMapView.h */, 982F2A6B27BADE17003C81F4 /* PartiallyMockedMapView.m */, @@ -446,6 +453,7 @@ buildActionMask = 2147483647; files = ( F7151F13265D7ED70028CB91 /* GoogleMapsTests.m in Sources */, + 6851F3562835BC180032B7C8 /* FLTGoogleMapJSONConversionsConversionTests.m in Sources */, 982F2A6C27BADE17003C81F4 /* PartiallyMockedMapView.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/packages/google_maps_flutter/google_maps_flutter/example/ios/RunnerTests/FLTGoogleMapJSONConversionsConversionTests.m b/packages/google_maps_flutter/google_maps_flutter/example/ios/RunnerTests/FLTGoogleMapJSONConversionsConversionTests.m new file mode 100644 index 000000000000..5e31c5928c48 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter/example/ios/RunnerTests/FLTGoogleMapJSONConversionsConversionTests.m @@ -0,0 +1,291 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +@import google_maps_flutter; +@import google_maps_flutter.Test; +@import XCTest; +@import MapKit; +@import GoogleMaps; + +#import +#import "PartiallyMockedMapView.h" + +@interface FLTGoogleMapJSONConversionsTests : XCTestCase +@end + +@implementation FLTGoogleMapJSONConversionsTests + +- (void)testLocationFromLatlong { + NSArray *latlong = @[ @(1), @(2) ]; + CLLocationCoordinate2D location = [FLTGoogleMapJSONConversions locationFromLatlong:latlong]; + XCTAssertEqual(location.latitude, 1); + XCTAssertEqual(location.longitude, 2); +} + +- (void)testPointFromArray { + NSArray *array = @[ @(1), @(2) ]; + CGPoint point = [FLTGoogleMapJSONConversions pointFromArray:array]; + XCTAssertEqual(point.x, 1); + XCTAssertEqual(point.y, 2); +} + +- (void)testArrayFromLocation { + CLLocationCoordinate2D location = CLLocationCoordinate2DMake(1, 2); + NSArray *array = [FLTGoogleMapJSONConversions arrayFromLocation:location]; + XCTAssertEqual([array[0] integerValue], 1); + XCTAssertEqual([array[1] integerValue], 2); +} + +- (void)testColorFromRGBA { + NSNumber *rgba = @(0x01020304); + UIColor *color = [FLTGoogleMapJSONConversions colorFromRGBA:rgba]; + CGFloat red, green, blue, alpha; + BOOL success = [color getRed:&red green:&green blue:&blue alpha:&alpha]; + XCTAssertTrue(success); + const CGFloat accuracy = 0.0001; + XCTAssertEqualWithAccuracy(red, 2 / 255.0, accuracy); + XCTAssertEqualWithAccuracy(green, 3 / 255.0, accuracy); + XCTAssertEqualWithAccuracy(blue, 4 / 255.0, accuracy); + XCTAssertEqualWithAccuracy(alpha, 1 / 255.0, accuracy); +} + +- (void)testPointsFromLatlongs { + NSArray *latlongs = @[ @[ @(1), @(2) ], @[ @(3), @(4) ] ]; + NSArray *locations = [FLTGoogleMapJSONConversions pointsFromLatlongs:latlongs]; + XCTAssertEqual(locations.count, 2); + XCTAssertEqual(locations[0].coordinate.latitude, 1); + XCTAssertEqual(locations[0].coordinate.longitude, 2); + XCTAssertEqual(locations[1].coordinate.latitude, 3); + XCTAssertEqual(locations[1].coordinate.longitude, 4); +} + +- (void)testHolesFromPointsArray { + NSArray *pointsArray = + @[ @[ @[ @(1), @(2) ], @[ @(3), @(4) ] ], @[ @[ @(5), @(6) ], @[ @(7), @(8) ] ] ]; + NSArray *> *holes = + [FLTGoogleMapJSONConversions holesFromPointsArray:pointsArray]; + XCTAssertEqual(holes.count, 2); + XCTAssertEqual(holes[0][0].coordinate.latitude, 1); + XCTAssertEqual(holes[0][0].coordinate.longitude, 2); + XCTAssertEqual(holes[0][1].coordinate.latitude, 3); + XCTAssertEqual(holes[0][1].coordinate.longitude, 4); + XCTAssertEqual(holes[1][0].coordinate.latitude, 5); + XCTAssertEqual(holes[1][0].coordinate.longitude, 6); + XCTAssertEqual(holes[1][1].coordinate.latitude, 7); + XCTAssertEqual(holes[1][1].coordinate.longitude, 8); +} + +- (void)testDictionaryFromPosition { + id mockPosition = OCMClassMock([GMSCameraPosition class]); + NSValue *locationValue = [NSValue valueWithMKCoordinate:CLLocationCoordinate2DMake(1, 2)]; + [(GMSCameraPosition *)[[mockPosition stub] andReturnValue:locationValue] target]; + [[[mockPosition stub] andReturnValue:@(2.0)] zoom]; + [[[mockPosition stub] andReturnValue:@(3.0)] bearing]; + [[[mockPosition stub] andReturnValue:@(75.0)] viewingAngle]; + NSDictionary *dictionary = [FLTGoogleMapJSONConversions dictionaryFromPosition:mockPosition]; + NSArray *targetArray = @[ @1, @2 ]; + XCTAssertEqualObjects(dictionary[@"target"], targetArray); + XCTAssertEqualObjects(dictionary[@"zoom"], @2.0); + XCTAssertEqualObjects(dictionary[@"bearing"], @3.0); + XCTAssertEqualObjects(dictionary[@"tilt"], @75.0); +} + +- (void)testDictionaryFromPoint { + CGPoint point = CGPointMake(10, 20); + NSDictionary *dictionary = [FLTGoogleMapJSONConversions dictionaryFromPoint:point]; + const CGFloat accuracy = 0.0001; + XCTAssertEqualWithAccuracy([dictionary[@"x"] floatValue], point.x, accuracy); + XCTAssertEqualWithAccuracy([dictionary[@"y"] floatValue], point.y, accuracy); +} + +- (void)testDictionaryFromCoordinateBounds { + XCTAssertNil([FLTGoogleMapJSONConversions dictionaryFromCoordinateBounds:nil]); + + GMSCoordinateBounds *bounds = + [[GMSCoordinateBounds alloc] initWithCoordinate:CLLocationCoordinate2DMake(10, 20) + coordinate:CLLocationCoordinate2DMake(30, 40)]; + NSDictionary *dictionary = [FLTGoogleMapJSONConversions dictionaryFromCoordinateBounds:bounds]; + NSArray *southwest = @[ @10, @20 ]; + NSArray *northeast = @[ @30, @40 ]; + XCTAssertEqualObjects(dictionary[@"southwest"], southwest); + XCTAssertEqualObjects(dictionary[@"northeast"], northeast); +} + +- (void)testCameraPostionFromDictionary { + XCTAssertNil([FLTGoogleMapJSONConversions cameraPostionFromDictionary:nil]); + + NSDictionary *channelValue = + @{@"target" : @[ @(1), @(2) ], @"zoom" : @3, @"bearing" : @4, @"tilt" : @5}; + + GMSCameraPosition *cameraPosition = + [FLTGoogleMapJSONConversions cameraPostionFromDictionary:channelValue]; + + const CGFloat accuracy = 0.001; + XCTAssertEqualWithAccuracy(cameraPosition.target.latitude, 1, accuracy); + XCTAssertEqualWithAccuracy(cameraPosition.target.longitude, 2, accuracy); + XCTAssertEqualWithAccuracy(cameraPosition.zoom, 3, accuracy); + XCTAssertEqualWithAccuracy(cameraPosition.bearing, 4, accuracy); + XCTAssertEqualWithAccuracy(cameraPosition.viewingAngle, 5, accuracy); +} + +- (void)testPointFromDictionary { + XCTAssertNil([FLTGoogleMapJSONConversions cameraPostionFromDictionary:nil]); + + NSDictionary *dictionary = @{ + @"x" : @1, + @"y" : @2, + }; + + CGPoint point = [FLTGoogleMapJSONConversions pointFromDictionary:dictionary]; + + const CGFloat accuracy = 0.001; + XCTAssertEqualWithAccuracy(point.x, 1, accuracy); + XCTAssertEqualWithAccuracy(point.y, 2, accuracy); +} + +- (void)testCoordinateBoundsFromLatlongs { + NSArray *latlong1 = @[ @(1), @(2) ]; + NSArray *latlong2 = @[ @(3), @(4) ]; + + GMSCoordinateBounds *bounds = + [FLTGoogleMapJSONConversions coordinateBoundsFromLatlongs:@[ latlong1, latlong2 ]]; + + const CGFloat accuracy = 0.001; + XCTAssertEqualWithAccuracy(bounds.southWest.latitude, 1, accuracy); + XCTAssertEqualWithAccuracy(bounds.southWest.longitude, 2, accuracy); + XCTAssertEqualWithAccuracy(bounds.northEast.latitude, 3, accuracy); + XCTAssertEqualWithAccuracy(bounds.northEast.longitude, 4, accuracy); +} + +- (void)testMapViewTypeFromTypeValue { + XCTAssertEqual(kGMSTypeNormal, [FLTGoogleMapJSONConversions mapViewTypeFromTypeValue:@1]); + XCTAssertEqual(kGMSTypeSatellite, [FLTGoogleMapJSONConversions mapViewTypeFromTypeValue:@2]); + XCTAssertEqual(kGMSTypeTerrain, [FLTGoogleMapJSONConversions mapViewTypeFromTypeValue:@3]); + XCTAssertEqual(kGMSTypeHybrid, [FLTGoogleMapJSONConversions mapViewTypeFromTypeValue:@4]); + XCTAssertEqual(kGMSTypeNone, [FLTGoogleMapJSONConversions mapViewTypeFromTypeValue:@5]); +} + +- (void)testCameraUpdateFromChannelValueNewCameraPosition { + NSArray *channelValue = @[ + @"newCameraPosition", + @{@"target" : @[ @(1), @(2) ], @"zoom" : @3, @"bearing" : @4, @"tilt" : @5} + ]; + id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); + [FLTGoogleMapJSONConversions cameraUpdateFromChannelValue:channelValue]; + [[classMockCameraUpdate expect] + setCamera:[FLTGoogleMapJSONConversions cameraPostionFromDictionary:channelValue[1]]]; + [classMockCameraUpdate stopMocking]; +} + +// TODO(cyanglaz): Fix the test for CameraUpdateFromChannelValue with the "NewLatlng" key. +// 2 approaches have been tried and neither worked for the tests. +// +// 1. Use OCMock to vefiry that [GMSCameraUpdate setTarget:] is triggered with the correct value. +// This class method conflicts with certain category method in OCMock, causing OCMock not able to +// disambigious them. +// +// 2. Directly verify the GMSCameraUpdate object returned by the method. +// The GMSCameraUpdate object returned from the method doesn't have any accessors to the "target" +// property. It can be used to update the "camera" property in GMSMapView. However, [GMSMapView +// moveCamera:] doesn't update the camera immediately. Thus the GMSCameraUpdate object cannot be +// verified. +// +// The code in below test uses the 2nd approach. +- (void)skip_testCameraUpdateFromChannelValueNewLatlong { + NSArray *channelValue = @[ @"newLatLng", @[ @1, @2 ] ]; + + GMSCameraUpdate *update = [FLTGoogleMapJSONConversions cameraUpdateFromChannelValue:channelValue]; + + GMSMapView *mapView = [[GMSMapView alloc] + initWithFrame:CGRectZero + camera:[GMSCameraPosition cameraWithTarget:CLLocationCoordinate2DMake(5, 6) zoom:1]]; + [mapView moveCamera:update]; + const CGFloat accuracy = 0.001; + XCTAssertEqualWithAccuracy(mapView.camera.target.latitude, 1, + accuracy); // mapView.camera.target.latitude is still 5. + XCTAssertEqualWithAccuracy(mapView.camera.target.longitude, 2, + accuracy); // mapView.camera.target.longitude is still 6. +} + +- (void)testCameraUpdateFromChannelValueNewLatLngBounds { + NSArray *latlong1 = @[ @(1), @(2) ]; + NSArray *latlong2 = @[ @(3), @(4) ]; + GMSCoordinateBounds *bounds = + [FLTGoogleMapJSONConversions coordinateBoundsFromLatlongs:@[ latlong1, latlong2 ]]; + + NSArray *channelValue = @[ @"newLatLngBounds", @[ latlong1, latlong2 ], @20 ]; + id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); + [FLTGoogleMapJSONConversions cameraUpdateFromChannelValue:channelValue]; + + [[classMockCameraUpdate expect] fitBounds:bounds withPadding:20]; + [classMockCameraUpdate stopMocking]; +} + +- (void)testCameraUpdateFromChannelValueNewLatLngZoom { + NSArray *channelValue = @[ @"newLatLngZoom", @[ @1, @2 ], @3 ]; + + id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); + [FLTGoogleMapJSONConversions cameraUpdateFromChannelValue:channelValue]; + + [[classMockCameraUpdate expect] setTarget:CLLocationCoordinate2DMake(1, 2) zoom:3]; + [classMockCameraUpdate stopMocking]; +} + +- (void)testCameraUpdateFromChannelValueScrollBy { + NSArray *channelValue = @[ @"scrollBy", @1, @2 ]; + + id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); + [FLTGoogleMapJSONConversions cameraUpdateFromChannelValue:channelValue]; + + [[classMockCameraUpdate expect] scrollByX:1 Y:2]; + [classMockCameraUpdate stopMocking]; +} + +- (void)testCameraUpdateFromChannelValueZoomBy { + NSArray *channelValueNoPoint = @[ @"zoomBy", @1 ]; + + id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); + [FLTGoogleMapJSONConversions cameraUpdateFromChannelValue:channelValueNoPoint]; + + [[classMockCameraUpdate expect] zoomBy:1]; + + NSArray *channelValueWithPoint = @[ @"zoomBy", @1, @[ @2, @3 ] ]; + + [FLTGoogleMapJSONConversions cameraUpdateFromChannelValue:channelValueWithPoint]; + + [[classMockCameraUpdate expect] zoomBy:1 atPoint:CGPointMake(2, 3)]; + [classMockCameraUpdate stopMocking]; +} + +- (void)testCameraUpdateFromChannelValueZoomIn { + NSArray *channelValueNoPoint = @[ @"zoomIn" ]; + + id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); + [FLTGoogleMapJSONConversions cameraUpdateFromChannelValue:channelValueNoPoint]; + + [[classMockCameraUpdate expect] zoomIn]; + [classMockCameraUpdate stopMocking]; +} + +- (void)testCameraUpdateFromChannelValueZoomOut { + NSArray *channelValueNoPoint = @[ @"zoomOut" ]; + + id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); + [FLTGoogleMapJSONConversions cameraUpdateFromChannelValue:channelValueNoPoint]; + + [[classMockCameraUpdate expect] zoomOut]; + [classMockCameraUpdate stopMocking]; +} + +- (void)testCameraUpdateFromChannelValueZoomTo { + NSArray *channelValueNoPoint = @[ @"zoomTo", @1 ]; + + id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); + [FLTGoogleMapJSONConversions cameraUpdateFromChannelValue:channelValueNoPoint]; + + [[classMockCameraUpdate expect] zoomTo:1]; + [classMockCameraUpdate stopMocking]; +} + +@end diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.h index 356a13faba62..c29b2d2cdb91 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.h @@ -24,8 +24,9 @@ NS_ASSUME_NONNULL_BEGIN @end @interface FLTTileProviderController : GMSTileLayer -@property(copy, nonatomic, readonly) NSString *tileOverlayId; -- (instancetype)init:(FlutterMethodChannel *)methodChannel tileOverlayId:(NSString *)tileOverlayId; +@property(copy, nonatomic, readonly) NSString *tileOverlayIdentifier; +- (instancetype)init:(FlutterMethodChannel *)methodChannel + withTileOverlayIdentifier:(NSString *)identifier; @end @interface FLTTileOverlaysController : NSObject @@ -34,9 +35,9 @@ NS_ASSUME_NONNULL_BEGIN registrar:(NSObject *)registrar; - (void)addTileOverlays:(NSArray *)tileOverlaysToAdd; - (void)changeTileOverlays:(NSArray *)tileOverlaysToChange; -- (void)removeTileOverlayIds:(NSArray *)tileOverlayIdsToRemove; -- (void)clearTileCache:(NSString *)tileOverlayId; -- (nullable NSDictionary *)getTileOverlayInfo:(NSString *)tileverlayId; +- (void)removeTileOverlayWithIdentifiers:(NSArray *)identifiers; +- (void)clearTileCacheWithIdentifier:(NSString *)identifiers; +- (nullable NSDictionary *)tileOverlayInfoWithIdentifier:(NSString *)identifier; @end NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m index 6baa753ef999..71f3bbd22324 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m @@ -5,35 +5,6 @@ #import "FLTGoogleMapTileOverlayController.h" #import "JsonConversions.h" -static void InterpretTileOverlayOptions(NSDictionary *data, - id sink, - NSObject *registrar) { - NSNumber *visible = data[@"visible"]; - if (visible != nil) { - [sink setVisible:visible.boolValue]; - } - - NSNumber *transparency = data[@"transparency"]; - if (transparency != nil) { - [sink setTransparency:transparency.floatValue]; - } - - NSNumber *zIndex = data[@"zIndex"]; - if (zIndex != nil) { - [sink setZIndex:zIndex.intValue]; - } - - NSNumber *fadeIn = data[@"fadeIn"]; - if (fadeIn != nil) { - [sink setFadeIn:fadeIn.boolValue]; - } - - NSNumber *tileSize = data[@"tileSize"]; - if (tileSize != nil) { - [sink setTileSize:tileSize.integerValue]; - } -} - @interface FLTGoogleMapTileOverlayController () @property(strong, nonatomic) GMSTileLayer *layer; @@ -46,8 +17,8 @@ @implementation FLTGoogleMapTileOverlayController - (instancetype)initWithTileLayer:(GMSTileLayer *)tileLayer mapView:(GMSMapView *)mapView { self = [super init]; if (self) { - self.layer = tileLayer; - self.mapView = mapView; + _layer = tileLayer; + _mapView = mapView; } return self; } @@ -98,17 +69,17 @@ - (void)setTileSize:(NSInteger)tileSize { @interface FLTTileProviderController () @property(weak, nonatomic) FlutterMethodChannel *methodChannel; -@property(copy, nonatomic, readwrite) NSString *tileOverlayId; @end @implementation FLTTileProviderController -- (instancetype)init:(FlutterMethodChannel *)methodChannel tileOverlayId:(NSString *)tileOverlayId { +- (instancetype)init:(FlutterMethodChannel *)methodChannel + withTileOverlayIdentifier:(NSString *)identifier { self = [super init]; if (self) { - self.methodChannel = methodChannel; - self.tileOverlayId = tileOverlayId; + _methodChannel = methodChannel; + _tileOverlayIdentifier = identifier; } return self; } @@ -119,10 +90,11 @@ - (void)requestTileForX:(NSUInteger)x y:(NSUInteger)y zoom:(NSUInteger)zoom receiver:(id)receiver { + __weak typeof(self) weakSelf = self; [self.methodChannel invokeMethod:@"tileOverlay#getTile" arguments:@{ - @"tileOverlayId" : self.tileOverlayId, + @"tileOverlayId" : weakSelf.tileOverlayIdentifier, @"x" : @(x), @"y" : @(y), @"zoom" : @(zoom) @@ -156,9 +128,8 @@ - (void)requestTileForX:(NSUInteger)x @interface FLTTileOverlaysController () -@property(strong, nonatomic) NSMutableDictionary *tileOverlayIdToController; +@property(strong, nonatomic) NSMutableDictionary *tileOverlayIdentifierToController; @property(weak, nonatomic) FlutterMethodChannel *methodChannel; -@property(weak, nonatomic) NSObject *registrar; @property(weak, nonatomic) GMSMapView *mapView; @end @@ -170,65 +141,96 @@ - (instancetype)init:(FlutterMethodChannel *)methodChannel registrar:(NSObject *)registrar { self = [super init]; if (self) { - self.methodChannel = methodChannel; - self.mapView = mapView; - self.tileOverlayIdToController = [[NSMutableDictionary alloc] init]; - self.registrar = registrar; + _methodChannel = methodChannel; + _mapView = mapView; + _tileOverlayIdentifierToController = [[NSMutableDictionary alloc] init]; } return self; } - (void)addTileOverlays:(NSArray *)tileOverlaysToAdd { for (NSDictionary *tileOverlay in tileOverlaysToAdd) { - NSString *tileOverlayId = [FLTTileOverlaysController getTileOverlayId:tileOverlay]; + NSString *identifier = [FLTTileOverlaysController identifierForTileOverlay:tileOverlay]; FLTTileProviderController *tileProvider = - [[FLTTileProviderController alloc] init:self.methodChannel tileOverlayId:tileOverlayId]; + [[FLTTileProviderController alloc] init:self.methodChannel + withTileOverlayIdentifier:identifier]; FLTGoogleMapTileOverlayController *controller = [[FLTGoogleMapTileOverlayController alloc] initWithTileLayer:tileProvider mapView:self.mapView]; - InterpretTileOverlayOptions(tileOverlay, controller, self.registrar); - self.tileOverlayIdToController[tileOverlayId] = controller; + [FLTTileOverlaysController interpretTileOverlayOptions:tileOverlay sink:controller]; + self.tileOverlayIdentifierToController[identifier] = controller; } } - (void)changeTileOverlays:(NSArray *)tileOverlaysToChange { for (NSDictionary *tileOverlay in tileOverlaysToChange) { - NSString *tileOverlayId = [FLTTileOverlaysController getTileOverlayId:tileOverlay]; - FLTGoogleMapTileOverlayController *controller = self.tileOverlayIdToController[tileOverlayId]; + NSString *identifier = [FLTTileOverlaysController identifierForTileOverlay:tileOverlay]; + FLTGoogleMapTileOverlayController *controller = + self.tileOverlayIdentifierToController[identifier]; if (!controller) { continue; } - InterpretTileOverlayOptions(tileOverlay, controller, self.registrar); + [FLTTileOverlaysController interpretTileOverlayOptions:tileOverlay sink:controller]; } } -- (void)removeTileOverlayIds:(NSArray *)tileOverlayIdsToRemove { - for (NSString *tileOverlayId in tileOverlayIdsToRemove) { - FLTGoogleMapTileOverlayController *controller = self.tileOverlayIdToController[tileOverlayId]; +- (void)removeTileOverlayWithIdentifiers:(NSArray *)identifiers { + for (NSString *identifier in identifiers) { + FLTGoogleMapTileOverlayController *controller = + self.tileOverlayIdentifierToController[identifier]; if (!controller) { continue; } [controller removeTileOverlay]; - [self.tileOverlayIdToController removeObjectForKey:tileOverlayId]; + [self.tileOverlayIdentifierToController removeObjectForKey:identifier]; } } -- (void)clearTileCache:(NSString *)tileOverlayId { - FLTGoogleMapTileOverlayController *controller = self.tileOverlayIdToController[tileOverlayId]; +- (void)clearTileCacheWithIdentifier:(NSString *)identifier { + FLTGoogleMapTileOverlayController *controller = + self.tileOverlayIdentifierToController[identifier]; if (!controller) { return; } [controller clearTileCache]; } -- (nullable NSDictionary *)getTileOverlayInfo:(NSString *)tileverlayId { - if (self.tileOverlayIdToController[tileverlayId] == nil) { +- (nullable NSDictionary *)tileOverlayInfoWithIdentifier:(NSString *)identifier { + if (self.tileOverlayIdentifierToController[identifier] == nil) { return nil; } - return [self.tileOverlayIdToController[tileverlayId] getTileOverlayInfo]; + return [self.tileOverlayIdentifierToController[identifier] getTileOverlayInfo]; } -+ (NSString *)getTileOverlayId:(NSDictionary *)tileOverlay { ++ (NSString *)identifierForTileOverlay:(NSDictionary *)tileOverlay { return tileOverlay[@"tileOverlayId"]; } ++ (void)interpretTileOverlayOptions:(NSDictionary *)data + sink:(id)sink { + NSNumber *visible = data[@"visible"]; + if (visible != nil && visible != (id)[NSNull null]) { + [sink setVisible:visible.boolValue]; + } + + NSNumber *transparency = data[@"transparency"]; + if (transparency != nil && transparency != (id)[NSNull null]) { + [sink setTransparency:transparency.floatValue]; + } + + NSNumber *zIndex = data[@"zIndex"]; + if (zIndex != nil && zIndex != (id)[NSNull null]) { + [sink setZIndex:zIndex.intValue]; + } + + NSNumber *fadeIn = data[@"fadeIn"]; + if (fadeIn != nil && fadeIn != (id)[NSNull null]) { + [sink setFadeIn:fadeIn.boolValue]; + } + + NSNumber *tileSize = data[@"tileSize"]; + if (tileSize != nil && tileSize != (id)[NSNull null]) { + [sink setTileSize:tileSize.integerValue]; + } +} + @end diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.h index 953c0557ff20..26f69eaf3882 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.h @@ -10,5 +10,9 @@ #import "GoogleMapPolygonController.h" #import "GoogleMapPolylineController.h" +NS_ASSUME_NONNULL_BEGIN + @interface FLTGoogleMapsPlugin : NSObject @end + +NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.m index e78a505ecfb0..d62f19ced4f3 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapsPlugin.m @@ -6,11 +6,7 @@ #pragma mark - GoogleMaps plugin implementation -@implementation FLTGoogleMapsPlugin { - NSObject *_registrar; - FlutterMethodChannel *_channel; - NSMutableDictionary *_mapControllers; -} +@implementation FLTGoogleMapsPlugin + (void)registerWithRegistrar:(NSObject *)registrar { FLTGoogleMapFactory *googleMapFactory = [[FLTGoogleMapFactory alloc] initWithRegistrar:registrar]; @@ -20,12 +16,4 @@ + (void)registerWithRegistrar:(NSObject *)registrar { FlutterPlatformViewGestureRecognizersBlockingPolicyWaitUntilTouchesEnded]; } -- (FLTGoogleMapController *)mapFromCall:(FlutterMethodCall *)call error:(FlutterError **)error { - id mapId = call.arguments[@"map"]; - FLTGoogleMapController *controller = _mapControllers[mapId]; - if (!controller && error) { - *error = [FlutterError errorWithCode:@"unknown_map" message:nil details:mapId]; - } - return controller; -} @end diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.h index 26b7ce573bdf..260932dbfb4b 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.h @@ -19,10 +19,9 @@ // Defines circle controllable by Flutter. @interface FLTGoogleMapCircleController : NSObject -@property(atomic, readonly) NSString *circleId; - (instancetype)initCircleWithPosition:(CLLocationCoordinate2D)position radius:(CLLocationDistance)radius - circleId:(NSString *)circleId + circleId:(NSString *)circleIdentifier mapView:(GMSMapView *)mapView; - (void)removeCircle; @end @@ -33,7 +32,7 @@ registrar:(NSObject *)registrar; - (void)addCircles:(NSArray *)circlesToAdd; - (void)changeCircles:(NSArray *)circlesToChange; -- (void)removeCircleIds:(NSArray *)circleIdsToRemove; -- (void)onCircleTap:(NSString *)circleId; -- (bool)hasCircleWithId:(NSString *)circleId; +- (void)removeCircleWithIdentifiers:(NSArray *)identifiers; +- (void)didTapCircleWithIdentifier:(NSString *)identifier; +- (bool)hasCircleWithIdentifier:(NSString *)identifier; @end diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m index d97de587fb17..bebd15f0cdfa 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m @@ -5,120 +5,71 @@ #import "GoogleMapCircleController.h" #import "JsonConversions.h" -@implementation FLTGoogleMapCircleController { - GMSCircle *_circle; - GMSMapView *_mapView; -} +@interface FLTGoogleMapCircleController () + +@property(nonatomic, strong) GMSCircle *circle; +@property(nonatomic, weak) GMSMapView *mapView; + +@end + +@implementation FLTGoogleMapCircleController + - (instancetype)initCircleWithPosition:(CLLocationCoordinate2D)position radius:(CLLocationDistance)radius - circleId:(NSString *)circleId + circleId:(NSString *)circleIdentifier mapView:(GMSMapView *)mapView { self = [super init]; if (self) { _circle = [GMSCircle circleWithPosition:position radius:radius]; _mapView = mapView; - _circleId = circleId; - _circle.userData = @[ circleId ]; + _circle.userData = @[ circleIdentifier ]; } return self; } - (void)removeCircle { - _circle.map = nil; + self.circle.map = nil; } #pragma mark - FLTGoogleMapCircleOptionsSink methods - (void)setConsumeTapEvents:(BOOL)consumes { - _circle.tappable = consumes; + self.circle.tappable = consumes; } - (void)setVisible:(BOOL)visible { - _circle.map = visible ? _mapView : nil; + self.circle.map = visible ? self.mapView : nil; } - (void)setZIndex:(int)zIndex { - _circle.zIndex = zIndex; + self.circle.zIndex = zIndex; } - (void)setCenter:(CLLocationCoordinate2D)center { - _circle.position = center; + self.circle.position = center; } - (void)setRadius:(CLLocationDistance)radius { - _circle.radius = radius; + self.circle.radius = radius; } - (void)setStrokeColor:(UIColor *)color { - _circle.strokeColor = color; + self.circle.strokeColor = color; } - (void)setStrokeWidth:(CGFloat)width { - _circle.strokeWidth = width; + self.circle.strokeWidth = width; } - (void)setFillColor:(UIColor *)color { - _circle.fillColor = color; + self.circle.fillColor = color; } @end -static int ToInt(NSNumber *data) { return [FLTGoogleMapJsonConversions toInt:data]; } - -static BOOL ToBool(NSNumber *data) { return [FLTGoogleMapJsonConversions toBool:data]; } - -static CLLocationCoordinate2D ToLocation(NSArray *data) { - return [FLTGoogleMapJsonConversions toLocation:data]; -} - -static CLLocationDistance ToDistance(NSNumber *data) { - return [FLTGoogleMapJsonConversions toFloat:data]; -} - -static UIColor *ToColor(NSNumber *data) { return [FLTGoogleMapJsonConversions toColor:data]; } - -static void InterpretCircleOptions(NSDictionary *data, id sink, - NSObject *registrar) { - NSNumber *consumeTapEvents = data[@"consumeTapEvents"]; - if (consumeTapEvents != nil) { - [sink setConsumeTapEvents:ToBool(consumeTapEvents)]; - } - - NSNumber *visible = data[@"visible"]; - if (visible != nil) { - [sink setVisible:ToBool(visible)]; - } - - NSNumber *zIndex = data[@"zIndex"]; - if (zIndex != nil) { - [sink setZIndex:ToInt(zIndex)]; - } - - NSArray *center = data[@"center"]; - if (center) { - [sink setCenter:ToLocation(center)]; - } - - NSNumber *radius = data[@"radius"]; - if (radius != nil) { - [sink setRadius:ToDistance(radius)]; - } +@interface FLTCirclesController () - NSNumber *strokeColor = data[@"strokeColor"]; - if (strokeColor != nil) { - [sink setStrokeColor:ToColor(strokeColor)]; - } +@property(weak, nonatomic) FlutterMethodChannel *methodChannel; +@property(weak, nonatomic) GMSMapView *mapView; +@property(strong, nonatomic) NSMutableDictionary *circleIdToController; - NSNumber *strokeWidth = data[@"strokeWidth"]; - if (strokeWidth != nil) { - [sink setStrokeWidth:ToInt(strokeWidth)]; - } +@end - NSNumber *fillColor = data[@"fillColor"]; - if (fillColor != nil) { - [sink setFillColor:ToColor(fillColor)]; - } -} +@implementation FLTCirclesController -@implementation FLTCirclesController { - NSMutableDictionary *_circleIdToController; - FlutterMethodChannel *_methodChannel; - NSObject *_registrar; - GMSMapView *_mapView; -} - (instancetype)init:(FlutterMethodChannel *)methodChannel mapView:(GMSMapView *)mapView registrar:(NSObject *)registrar { @@ -127,10 +78,10 @@ - (instancetype)init:(FlutterMethodChannel *)methodChannel _methodChannel = methodChannel; _mapView = mapView; _circleIdToController = [NSMutableDictionary dictionaryWithCapacity:1]; - _registrar = registrar; } return self; } + - (void)addCircles:(NSArray *)circlesToAdd { for (NSDictionary *circle in circlesToAdd) { CLLocationCoordinate2D position = [FLTCirclesController getPosition:circle]; @@ -140,59 +91,106 @@ - (void)addCircles:(NSArray *)circlesToAdd { [[FLTGoogleMapCircleController alloc] initCircleWithPosition:position radius:radius circleId:circleId - mapView:_mapView]; - InterpretCircleOptions(circle, controller, _registrar); - _circleIdToController[circleId] = controller; + mapView:self.mapView]; + [FLTCirclesController interpretCircleOptions:circle sink:controller]; + self.circleIdToController[circleId] = controller; } } + - (void)changeCircles:(NSArray *)circlesToChange { for (NSDictionary *circle in circlesToChange) { NSString *circleId = [FLTCirclesController getCircleId:circle]; - FLTGoogleMapCircleController *controller = _circleIdToController[circleId]; + FLTGoogleMapCircleController *controller = self.circleIdToController[circleId]; if (!controller) { continue; } - InterpretCircleOptions(circle, controller, _registrar); + [FLTCirclesController interpretCircleOptions:circle sink:controller]; } } -- (void)removeCircleIds:(NSArray *)circleIdsToRemove { - for (NSString *circleId in circleIdsToRemove) { - if (!circleId) { - continue; - } - FLTGoogleMapCircleController *controller = _circleIdToController[circleId]; + +- (void)removeCircleWithIdentifiers:(NSArray *)identifiers { + for (NSString *identifier in identifiers) { + FLTGoogleMapCircleController *controller = self.circleIdToController[identifier]; if (!controller) { continue; } [controller removeCircle]; - [_circleIdToController removeObjectForKey:circleId]; + [self.circleIdToController removeObjectForKey:identifier]; } } -- (bool)hasCircleWithId:(NSString *)circleId { - if (!circleId) { + +- (bool)hasCircleWithIdentifier:(NSString *)identifier { + if (!identifier) { return false; } - return _circleIdToController[circleId] != nil; + return self.circleIdToController[identifier] != nil; } -- (void)onCircleTap:(NSString *)circleId { - if (!circleId) { + +- (void)didTapCircleWithIdentifier:(NSString *)identifier { + if (!identifier) { return; } - FLTGoogleMapCircleController *controller = _circleIdToController[circleId]; + FLTGoogleMapCircleController *controller = self.circleIdToController[identifier]; if (!controller) { return; } - [_methodChannel invokeMethod:@"circle#onTap" arguments:@{@"circleId" : circleId}]; + [self.methodChannel invokeMethod:@"circle#onTap" arguments:@{@"circleId" : identifier}]; } + + (CLLocationCoordinate2D)getPosition:(NSDictionary *)circle { NSArray *center = circle[@"center"]; - return ToLocation(center); + return [FLTGoogleMapJSONConversions locationFromLatlong:center]; } + + (CLLocationDistance)getRadius:(NSDictionary *)circle { NSNumber *radius = circle[@"radius"]; - return ToDistance(radius); + return [radius floatValue]; } + + (NSString *)getCircleId:(NSDictionary *)circle { return circle[@"circleId"]; } + ++ (void)interpretCircleOptions:(NSDictionary *)data sink:(id)sink { + NSNumber *consumeTapEvents = data[@"consumeTapEvents"]; + if (consumeTapEvents && consumeTapEvents != (id)[NSNull null]) { + [sink setConsumeTapEvents:consumeTapEvents.boolValue]; + } + + NSNumber *visible = data[@"visible"]; + if (visible && visible != (id)[NSNull null]) { + [sink setVisible:[visible boolValue]]; + } + + NSNumber *zIndex = data[@"zIndex"]; + if (zIndex && zIndex != (id)[NSNull null]) { + [sink setZIndex:[zIndex intValue]]; + } + + NSArray *center = data[@"center"]; + if (center && center != (id)[NSNull null]) { + [sink setCenter:[FLTGoogleMapJSONConversions locationFromLatlong:center]]; + } + + NSNumber *radius = data[@"radius"]; + if (radius && radius != (id)[NSNull null]) { + [sink setRadius:[radius floatValue]]; + } + + NSNumber *strokeColor = data[@"strokeColor"]; + if (strokeColor && strokeColor != (id)[NSNull null]) { + [sink setStrokeColor:[FLTGoogleMapJSONConversions colorFromRGBA:strokeColor]]; + } + + NSNumber *strokeWidth = data[@"strokeWidth"]; + if (strokeWidth && strokeWidth != (id)[NSNull null]) { + [sink setStrokeWidth:[strokeWidth intValue]]; + } + + NSNumber *fillColor = data[@"fillColor"]; + if (fillColor && fillColor != (id)[NSNull null]) { + [sink setFillColor:[FLTGoogleMapJSONConversions colorFromRGBA:fillColor]]; + } +} + @end diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.h index a8cebb983347..81a607636772 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.h @@ -38,7 +38,7 @@ NS_ASSUME_NONNULL_BEGIN viewIdentifier:(int64_t)viewId arguments:(nullable id)args registrar:(NSObject *)registrar; -- (void)showAtX:(CGFloat)x Y:(CGFloat)y; +- (void)showAtOrigin:(CGPoint)origin; - (void)hide; - (void)animateWithCameraUpdate:(GMSCameraUpdate *)cameraUpdate; - (void)moveWithCameraUpdate:(GMSCameraUpdate *)cameraUpdate; diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m index ca8068129566..825cd5ac9a93 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m @@ -8,20 +8,13 @@ #pragma mark - Conversion of JSON-like values sent via platform channels. Forward declarations. -static NSDictionary *PositionToJson(GMSCameraPosition *position); -static NSDictionary *PointToJson(CGPoint point); -static NSArray *LocationToJson(CLLocationCoordinate2D position); -static CGPoint ToCGPoint(NSDictionary *json); -static GMSCameraPosition *ToOptionalCameraPosition(NSDictionary *json); -static GMSCoordinateBounds *ToOptionalBounds(NSArray *json); -static GMSCameraUpdate *ToCameraUpdate(NSArray *data); -static NSDictionary *GMSCoordinateBoundsToJson(GMSCoordinateBounds *bounds); -static void InterpretMapOptions(NSDictionary *data, id sink); -static double ToDouble(NSNumber *data) { return [FLTGoogleMapJsonConversions toDouble:data]; } +@interface FLTGoogleMapFactory () -@implementation FLTGoogleMapFactory { - NSObject *_registrar; -} +@property(weak, nonatomic) NSObject *registrar; + +@end + +@implementation FLTGoogleMapFactory - (instancetype)initWithRegistrar:(NSObject *)registrar { self = [super init]; @@ -41,28 +34,32 @@ - (instancetype)initWithRegistrar:(NSObject *)registrar return [[FLTGoogleMapController alloc] initWithFrame:frame viewIdentifier:viewId arguments:args - registrar:_registrar]; + registrar:self.registrar]; } @end -@implementation FLTGoogleMapController { - GMSMapView *_mapView; - int64_t _viewId; - FlutterMethodChannel *_channel; - BOOL _trackCameraPosition; - NSObject *_registrar; - FLTMarkersController *_markersController; - FLTPolygonsController *_polygonsController; - FLTPolylinesController *_polylinesController; - FLTCirclesController *_circlesController; - FLTTileOverlaysController *_tileOverlaysController; -} +@interface FLTGoogleMapController () + +@property(nonatomic, strong) GMSMapView *mapView; +@property(nonatomic, strong) FlutterMethodChannel *channel; +@property(nonatomic, assign) BOOL trackCameraPosition; +@property(nonatomic, weak) NSObject *registrar; +@property(nonatomic, strong) FLTMarkersController *markersController; +@property(nonatomic, strong) FLTPolygonsController *polygonsController; +@property(nonatomic, strong) FLTPolylinesController *polylinesController; +@property(nonatomic, strong) FLTCirclesController *circlesController; +@property(nonatomic, strong) FLTTileOverlaysController *tileOverlaysController; + +@end + +@implementation FLTGoogleMapController - (instancetype)initWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id _Nullable)args registrar:(NSObject *)registrar { - GMSCameraPosition *camera = ToOptionalCameraPosition(args[@"initialCameraPosition"]); + GMSCameraPosition *camera = + [FLTGoogleMapJSONConversions cameraPostionFromDictionary:args[@"initialCameraPosition"]]; GMSMapView *mapView = [GMSMapView mapWithFrame:frame camera:camera]; return [self initWithMapView:mapView viewIdentifier:viewId arguments:args registrar:registrar]; } @@ -73,11 +70,11 @@ - (instancetype)initWithMapView:(GMSMapView *_Nonnull)mapView registrar:(NSObject *_Nonnull)registrar { if (self = [super init]) { _mapView = mapView; - _viewId = viewId; _mapView.accessibilityElementsHidden = NO; - _trackCameraPosition = NO; - InterpretMapOptions(args[@"options"], self); + // TODO(cyanglaz): avoid sending message to self in the middle of the init method. + // https://github.com/flutter/flutter/issues/104121 + [FLTGoogleMapController interpretMapOptions:args[@"options"] sink:self]; NSString *channelName = [NSString stringWithFormat:@"plugins.flutter.io/google_maps_%lld", viewId]; _channel = [FlutterMethodChannel methodChannelWithName:channelName @@ -90,9 +87,9 @@ - (instancetype)initWithMapView:(GMSMapView *_Nonnull)mapView }]; _mapView.delegate = weakSelf; _registrar = registrar; - _markersController = [[FLTMarkersController alloc] init:_channel - mapView:_mapView - registrar:registrar]; + _markersController = [[FLTMarkersController alloc] initWithMethodChannel:_channel + mapView:_mapView + registrar:registrar]; _polygonsController = [[FLTPolygonsController alloc] init:_channel mapView:_mapView registrar:registrar]; @@ -132,25 +129,25 @@ - (instancetype)initWithMapView:(GMSMapView *_Nonnull)mapView } - (UIView *)view { - return _mapView; + return self.mapView; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { - if (object == _mapView && [keyPath isEqualToString:@"frame"]) { - CGRect bounds = _mapView.bounds; + if (object == self.mapView && [keyPath isEqualToString:@"frame"]) { + CGRect bounds = self.mapView.bounds; if (CGRectEqualToRect(bounds, CGRectZero)) { // The workaround is to fix an issue that the camera location is not current when // the size of the map is zero at initialization. - // So We only care about the size of the `_mapView`, ignore the frame changes when the size is - // zero. + // So We only care about the size of the `self.mapView`, ignore the frame changes when the + // size is zero. return; } // We only observe the frame for initial setup. - [_mapView removeObserver:self forKeyPath:@"frame"]; - [_mapView moveCamera:[GMSCameraUpdate setCamera:_mapView.camera]]; + [self.mapView removeObserver:self forKeyPath:@"frame"]; + [self.mapView moveCamera:[GMSCameraUpdate setCamera:self.mapView.camera]]; } else { [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } @@ -158,46 +155,50 @@ - (void)observeValueForKeyPath:(NSString *)keyPath - (void)onMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { if ([call.method isEqualToString:@"map#show"]) { - [self showAtX:ToDouble(call.arguments[@"x"]) Y:ToDouble(call.arguments[@"y"])]; + [self showAtOrigin:CGPointMake([call.arguments[@"x"] doubleValue], + [call.arguments[@"y"] doubleValue])]; result(nil); } else if ([call.method isEqualToString:@"map#hide"]) { [self hide]; result(nil); } else if ([call.method isEqualToString:@"camera#animate"]) { - [self animateWithCameraUpdate:ToCameraUpdate(call.arguments[@"cameraUpdate"])]; + [self + animateWithCameraUpdate:[FLTGoogleMapJSONConversions + cameraUpdateFromChannelValue:call.arguments[@"cameraUpdate"]]]; result(nil); } else if ([call.method isEqualToString:@"camera#move"]) { - [self moveWithCameraUpdate:ToCameraUpdate(call.arguments[@"cameraUpdate"])]; + [self moveWithCameraUpdate:[FLTGoogleMapJSONConversions + cameraUpdateFromChannelValue:call.arguments[@"cameraUpdate"]]]; result(nil); } else if ([call.method isEqualToString:@"map#update"]) { - InterpretMapOptions(call.arguments[@"options"], self); - result(PositionToJson([self cameraPosition])); + [FLTGoogleMapController interpretMapOptions:call.arguments[@"options"] sink:self]; + result([FLTGoogleMapJSONConversions dictionaryFromPosition:[self cameraPosition]]); } else if ([call.method isEqualToString:@"map#getVisibleRegion"]) { - if (_mapView != nil) { - GMSVisibleRegion visibleRegion = _mapView.projection.visibleRegion; + if (self.mapView != nil) { + GMSVisibleRegion visibleRegion = self.mapView.projection.visibleRegion; GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] initWithRegion:visibleRegion]; - - result(GMSCoordinateBoundsToJson(bounds)); + result([FLTGoogleMapJSONConversions dictionaryFromCoordinateBounds:bounds]); } else { result([FlutterError errorWithCode:@"GoogleMap uninitialized" message:@"getVisibleRegion called prior to map initialization" details:nil]); } } else if ([call.method isEqualToString:@"map#getScreenCoordinate"]) { - if (_mapView != nil) { - CLLocationCoordinate2D location = [FLTGoogleMapJsonConversions toLocation:call.arguments]; - CGPoint point = [_mapView.projection pointForCoordinate:location]; - result(PointToJson(point)); + if (self.mapView != nil) { + CLLocationCoordinate2D location = + [FLTGoogleMapJSONConversions locationFromLatlong:call.arguments]; + CGPoint point = [self.mapView.projection pointForCoordinate:location]; + result([FLTGoogleMapJSONConversions dictionaryFromPoint:point]); } else { result([FlutterError errorWithCode:@"GoogleMap uninitialized" message:@"getScreenCoordinate called prior to map initialization" details:nil]); } } else if ([call.method isEqualToString:@"map#getLatLng"]) { - if (_mapView != nil && call.arguments) { - CGPoint point = ToCGPoint(call.arguments); - CLLocationCoordinate2D latlng = [_mapView.projection coordinateForPoint:point]; - result(LocationToJson(latlng)); + if (self.mapView != nil && call.arguments) { + CGPoint point = [FLTGoogleMapJSONConversions pointFromDictionary:call.arguments]; + CLLocationCoordinate2D latlng = [self.mapView.projection coordinateForPoint:point]; + result([FLTGoogleMapJSONConversions arrayFromLocation:latlng]); } else { result([FlutterError errorWithCode:@"GoogleMap uninitialized" message:@"getLatLng called prior to map initialization" @@ -207,14 +208,14 @@ - (void)onMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { result(nil); } else if ([call.method isEqualToString:@"map#takeSnapshot"]) { if (@available(iOS 10.0, *)) { - if (_mapView != nil) { + if (self.mapView != nil) { UIGraphicsImageRendererFormat *format = [UIGraphicsImageRendererFormat defaultFormat]; format.scale = [[UIScreen mainScreen] scale]; UIGraphicsImageRenderer *renderer = - [[UIGraphicsImageRenderer alloc] initWithSize:_mapView.frame.size format:format]; + [[UIGraphicsImageRenderer alloc] initWithSize:self.mapView.frame.size format:format]; UIImage *image = [renderer imageWithActions:^(UIGraphicsImageRendererContext *context) { - [_mapView.layer renderInContext:context.CGContext]; + [self.mapView.layer renderInContext:context.CGContext]; }]; result([FlutterStandardTypedData typedDataWithBytes:UIImagePNGRepresentation(image)]); } else { @@ -229,21 +230,21 @@ - (void)onMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { } else if ([call.method isEqualToString:@"markers#update"]) { id markersToAdd = call.arguments[@"markersToAdd"]; if ([markersToAdd isKindOfClass:[NSArray class]]) { - [_markersController addMarkers:markersToAdd]; + [self.markersController addMarkers:markersToAdd]; } id markersToChange = call.arguments[@"markersToChange"]; if ([markersToChange isKindOfClass:[NSArray class]]) { - [_markersController changeMarkers:markersToChange]; + [self.markersController changeMarkers:markersToChange]; } id markerIdsToRemove = call.arguments[@"markerIdsToRemove"]; if ([markerIdsToRemove isKindOfClass:[NSArray class]]) { - [_markersController removeMarkerIds:markerIdsToRemove]; + [self.markersController removeMarkersWithIdentifiers:markerIdsToRemove]; } result(nil); } else if ([call.method isEqualToString:@"markers#showInfoWindow"]) { id markerId = call.arguments[@"markerId"]; if ([markerId isKindOfClass:[NSString class]]) { - [_markersController showMarkerInfoWindow:markerId result:result]; + [self.markersController showMarkerInfoWindowWithIdentifier:markerId result:result]; } else { result([FlutterError errorWithCode:@"Invalid markerId" message:@"showInfoWindow called with invalid markerId" @@ -252,7 +253,7 @@ - (void)onMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { } else if ([call.method isEqualToString:@"markers#hideInfoWindow"]) { id markerId = call.arguments[@"markerId"]; if ([markerId isKindOfClass:[NSString class]]) { - [_markersController hideMarkerInfoWindow:markerId result:result]; + [self.markersController hideMarkerInfoWindowWithIdentifier:markerId result:result]; } else { result([FlutterError errorWithCode:@"Invalid markerId" message:@"hideInfoWindow called with invalid markerId" @@ -261,7 +262,7 @@ - (void)onMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { } else if ([call.method isEqualToString:@"markers#isInfoWindowShown"]) { id markerId = call.arguments[@"markerId"]; if ([markerId isKindOfClass:[NSString class]]) { - [_markersController isMarkerInfoWindowShown:markerId result:result]; + [self.markersController isInfoWindowShownForMarkerWithIdentifier:markerId result:result]; } else { result([FlutterError errorWithCode:@"Invalid markerId" message:@"isInfoWindowShown called with invalid markerId" @@ -270,97 +271,97 @@ - (void)onMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { } else if ([call.method isEqualToString:@"polygons#update"]) { id polygonsToAdd = call.arguments[@"polygonsToAdd"]; if ([polygonsToAdd isKindOfClass:[NSArray class]]) { - [_polygonsController addPolygons:polygonsToAdd]; + [self.polygonsController addPolygons:polygonsToAdd]; } id polygonsToChange = call.arguments[@"polygonsToChange"]; if ([polygonsToChange isKindOfClass:[NSArray class]]) { - [_polygonsController changePolygons:polygonsToChange]; + [self.polygonsController changePolygons:polygonsToChange]; } id polygonIdsToRemove = call.arguments[@"polygonIdsToRemove"]; if ([polygonIdsToRemove isKindOfClass:[NSArray class]]) { - [_polygonsController removePolygonIds:polygonIdsToRemove]; + [self.polygonsController removePolygonWithIdentifiers:polygonIdsToRemove]; } result(nil); } else if ([call.method isEqualToString:@"polylines#update"]) { id polylinesToAdd = call.arguments[@"polylinesToAdd"]; if ([polylinesToAdd isKindOfClass:[NSArray class]]) { - [_polylinesController addPolylines:polylinesToAdd]; + [self.polylinesController addPolylines:polylinesToAdd]; } id polylinesToChange = call.arguments[@"polylinesToChange"]; if ([polylinesToChange isKindOfClass:[NSArray class]]) { - [_polylinesController changePolylines:polylinesToChange]; + [self.polylinesController changePolylines:polylinesToChange]; } id polylineIdsToRemove = call.arguments[@"polylineIdsToRemove"]; if ([polylineIdsToRemove isKindOfClass:[NSArray class]]) { - [_polylinesController removePolylineIds:polylineIdsToRemove]; + [self.polylinesController removePolylineWithIdentifiers:polylineIdsToRemove]; } result(nil); } else if ([call.method isEqualToString:@"circles#update"]) { id circlesToAdd = call.arguments[@"circlesToAdd"]; if ([circlesToAdd isKindOfClass:[NSArray class]]) { - [_circlesController addCircles:circlesToAdd]; + [self.circlesController addCircles:circlesToAdd]; } id circlesToChange = call.arguments[@"circlesToChange"]; if ([circlesToChange isKindOfClass:[NSArray class]]) { - [_circlesController changeCircles:circlesToChange]; + [self.circlesController changeCircles:circlesToChange]; } id circleIdsToRemove = call.arguments[@"circleIdsToRemove"]; if ([circleIdsToRemove isKindOfClass:[NSArray class]]) { - [_circlesController removeCircleIds:circleIdsToRemove]; + [self.circlesController removeCircleWithIdentifiers:circleIdsToRemove]; } result(nil); } else if ([call.method isEqualToString:@"tileOverlays#update"]) { id tileOverlaysToAdd = call.arguments[@"tileOverlaysToAdd"]; if ([tileOverlaysToAdd isKindOfClass:[NSArray class]]) { - [_tileOverlaysController addTileOverlays:tileOverlaysToAdd]; + [self.tileOverlaysController addTileOverlays:tileOverlaysToAdd]; } id tileOverlaysToChange = call.arguments[@"tileOverlaysToChange"]; if ([tileOverlaysToChange isKindOfClass:[NSArray class]]) { - [_tileOverlaysController changeTileOverlays:tileOverlaysToChange]; + [self.tileOverlaysController changeTileOverlays:tileOverlaysToChange]; } id tileOverlayIdsToRemove = call.arguments[@"tileOverlayIdsToRemove"]; if ([tileOverlayIdsToRemove isKindOfClass:[NSArray class]]) { - [_tileOverlaysController removeTileOverlayIds:tileOverlayIdsToRemove]; + [self.tileOverlaysController removeTileOverlayWithIdentifiers:tileOverlayIdsToRemove]; } result(nil); } else if ([call.method isEqualToString:@"tileOverlays#clearTileCache"]) { id rawTileOverlayId = call.arguments[@"tileOverlayId"]; - [_tileOverlaysController clearTileCache:rawTileOverlayId]; + [self.tileOverlaysController clearTileCacheWithIdentifier:rawTileOverlayId]; result(nil); } else if ([call.method isEqualToString:@"map#isCompassEnabled"]) { - NSNumber *isCompassEnabled = @(_mapView.settings.compassButton); + NSNumber *isCompassEnabled = @(self.mapView.settings.compassButton); result(isCompassEnabled); } else if ([call.method isEqualToString:@"map#isMapToolbarEnabled"]) { NSNumber *isMapToolbarEnabled = @NO; result(isMapToolbarEnabled); } else if ([call.method isEqualToString:@"map#getMinMaxZoomLevels"]) { - NSArray *zoomLevels = @[ @(_mapView.minZoom), @(_mapView.maxZoom) ]; + NSArray *zoomLevels = @[ @(self.mapView.minZoom), @(self.mapView.maxZoom) ]; result(zoomLevels); } else if ([call.method isEqualToString:@"map#getZoomLevel"]) { - result(@(_mapView.camera.zoom)); + result(@(self.mapView.camera.zoom)); } else if ([call.method isEqualToString:@"map#isZoomGesturesEnabled"]) { - NSNumber *isZoomGesturesEnabled = @(_mapView.settings.zoomGestures); + NSNumber *isZoomGesturesEnabled = @(self.mapView.settings.zoomGestures); result(isZoomGesturesEnabled); } else if ([call.method isEqualToString:@"map#isZoomControlsEnabled"]) { NSNumber *isZoomControlsEnabled = @NO; result(isZoomControlsEnabled); } else if ([call.method isEqualToString:@"map#isTiltGesturesEnabled"]) { - NSNumber *isTiltGesturesEnabled = @(_mapView.settings.tiltGestures); + NSNumber *isTiltGesturesEnabled = @(self.mapView.settings.tiltGestures); result(isTiltGesturesEnabled); } else if ([call.method isEqualToString:@"map#isRotateGesturesEnabled"]) { - NSNumber *isRotateGesturesEnabled = @(_mapView.settings.rotateGestures); + NSNumber *isRotateGesturesEnabled = @(self.mapView.settings.rotateGestures); result(isRotateGesturesEnabled); } else if ([call.method isEqualToString:@"map#isScrollGesturesEnabled"]) { - NSNumber *isScrollGesturesEnabled = @(_mapView.settings.scrollGestures); + NSNumber *isScrollGesturesEnabled = @(self.mapView.settings.scrollGestures); result(isScrollGesturesEnabled); } else if ([call.method isEqualToString:@"map#isMyLocationButtonEnabled"]) { - NSNumber *isMyLocationButtonEnabled = @(_mapView.settings.myLocationButton); + NSNumber *isMyLocationButtonEnabled = @(self.mapView.settings.myLocationButton); result(isMyLocationButtonEnabled); } else if ([call.method isEqualToString:@"map#isTrafficEnabled"]) { - NSNumber *isTrafficEnabled = @(_mapView.trafficEnabled); + NSNumber *isTrafficEnabled = @(self.mapView.trafficEnabled); result(isTrafficEnabled); } else if ([call.method isEqualToString:@"map#isBuildingsEnabled"]) { - NSNumber *isBuildingsEnabled = @(_mapView.buildingsEnabled); + NSNumber *isBuildingsEnabled = @(self.mapView.buildingsEnabled); result(isBuildingsEnabled); } else if ([call.method isEqualToString:@"map#setStyle"]) { NSString *mapStyle = [call arguments]; @@ -372,33 +373,33 @@ - (void)onMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { } } else if ([call.method isEqualToString:@"map#getTileOverlayInfo"]) { NSString *rawTileOverlayId = call.arguments[@"tileOverlayId"]; - result([_tileOverlaysController getTileOverlayInfo:rawTileOverlayId]); + result([self.tileOverlaysController tileOverlayInfoWithIdentifier:rawTileOverlayId]); } else { result(FlutterMethodNotImplemented); } } -- (void)showAtX:(CGFloat)x Y:(CGFloat)y { - _mapView.frame = - CGRectMake(x, y, CGRectGetWidth(_mapView.frame), CGRectGetHeight(_mapView.frame)); - _mapView.hidden = NO; +- (void)showAtOrigin:(CGPoint)origin { + CGRect frame = {origin, self.mapView.frame.size}; + self.mapView.frame = frame; + self.mapView.hidden = NO; } - (void)hide { - _mapView.hidden = YES; + self.mapView.hidden = YES; } - (void)animateWithCameraUpdate:(GMSCameraUpdate *)cameraUpdate { - [_mapView animateWithCameraUpdate:cameraUpdate]; + [self.mapView animateWithCameraUpdate:cameraUpdate]; } - (void)moveWithCameraUpdate:(GMSCameraUpdate *)cameraUpdate { - [_mapView moveCamera:cameraUpdate]; + [self.mapView moveCamera:cameraUpdate]; } - (GMSCameraPosition *)cameraPosition { - if (_trackCameraPosition) { - return _mapView.camera; + if (self.trackCameraPosition) { + return self.mapView.camera; } else { return nil; } @@ -407,51 +408,51 @@ - (GMSCameraPosition *)cameraPosition { #pragma mark - FLTGoogleMapOptionsSink methods - (void)setCamera:(GMSCameraPosition *)camera { - _mapView.camera = camera; + self.mapView.camera = camera; } - (void)setCameraTargetBounds:(GMSCoordinateBounds *)bounds { - _mapView.cameraTargetBounds = bounds; + self.mapView.cameraTargetBounds = bounds; } - (void)setCompassEnabled:(BOOL)enabled { - _mapView.settings.compassButton = enabled; + self.mapView.settings.compassButton = enabled; } - (void)setIndoorEnabled:(BOOL)enabled { - _mapView.indoorEnabled = enabled; + self.mapView.indoorEnabled = enabled; } - (void)setTrafficEnabled:(BOOL)enabled { - _mapView.trafficEnabled = enabled; + self.mapView.trafficEnabled = enabled; } - (void)setBuildingsEnabled:(BOOL)enabled { - _mapView.buildingsEnabled = enabled; + self.mapView.buildingsEnabled = enabled; } - (void)setMapType:(GMSMapViewType)mapType { - _mapView.mapType = mapType; + self.mapView.mapType = mapType; } - (void)setMinZoom:(float)minZoom maxZoom:(float)maxZoom { - [_mapView setMinZoom:minZoom maxZoom:maxZoom]; + [self.mapView setMinZoom:minZoom maxZoom:maxZoom]; } - (void)setPaddingTop:(float)top left:(float)left bottom:(float)bottom right:(float)right { - _mapView.padding = UIEdgeInsetsMake(top, left, bottom, right); + self.mapView.padding = UIEdgeInsetsMake(top, left, bottom, right); } - (void)setRotateGesturesEnabled:(BOOL)enabled { - _mapView.settings.rotateGestures = enabled; + self.mapView.settings.rotateGestures = enabled; } - (void)setScrollGesturesEnabled:(BOOL)enabled { - _mapView.settings.scrollGestures = enabled; + self.mapView.settings.scrollGestures = enabled; } - (void)setTiltGesturesEnabled:(BOOL)enabled { - _mapView.settings.tiltGestures = enabled; + self.mapView.settings.tiltGestures = enabled; } - (void)setTrackCameraPosition:(BOOL)enabled { @@ -459,20 +460,20 @@ - (void)setTrackCameraPosition:(BOOL)enabled { } - (void)setZoomGesturesEnabled:(BOOL)enabled { - _mapView.settings.zoomGestures = enabled; + self.mapView.settings.zoomGestures = enabled; } - (void)setMyLocationEnabled:(BOOL)enabled { - _mapView.myLocationEnabled = enabled; + self.mapView.myLocationEnabled = enabled; } - (void)setMyLocationButtonEnabled:(BOOL)enabled { - _mapView.settings.myLocationButton = enabled; + self.mapView.settings.myLocationButton = enabled; } - (NSString *)setMapStyle:(NSString *)mapStyle { if (mapStyle == (id)[NSNull null] || mapStyle.length == 0) { - _mapView.mapStyle = nil; + self.mapView.mapStyle = nil; return nil; } NSError *error; @@ -480,7 +481,7 @@ - (NSString *)setMapStyle:(NSString *)mapStyle { if (!style) { return [error localizedDescription]; } else { - _mapView.mapStyle = style; + self.mapView.mapStyle = style; return nil; } } @@ -488,236 +489,141 @@ - (NSString *)setMapStyle:(NSString *)mapStyle { #pragma mark - GMSMapViewDelegate methods - (void)mapView:(GMSMapView *)mapView willMove:(BOOL)gesture { - [_channel invokeMethod:@"camera#onMoveStarted" arguments:@{@"isGesture" : @(gesture)}]; + [self.channel invokeMethod:@"camera#onMoveStarted" arguments:@{@"isGesture" : @(gesture)}]; } - (void)mapView:(GMSMapView *)mapView didChangeCameraPosition:(GMSCameraPosition *)position { - if (_trackCameraPosition) { - [_channel invokeMethod:@"camera#onMove" arguments:@{@"position" : PositionToJson(position)}]; + if (self.trackCameraPosition) { + [self.channel invokeMethod:@"camera#onMove" + arguments:@{ + @"position" : [FLTGoogleMapJSONConversions dictionaryFromPosition:position] + }]; } } - (void)mapView:(GMSMapView *)mapView idleAtCameraPosition:(GMSCameraPosition *)position { - [_channel invokeMethod:@"camera#onIdle" arguments:@{}]; + [self.channel invokeMethod:@"camera#onIdle" arguments:@{}]; } - (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker { NSString *markerId = marker.userData[0]; - return [_markersController onMarkerTap:markerId]; + return [self.markersController didTapMarkerWithIdentifier:markerId]; } - (void)mapView:(GMSMapView *)mapView didEndDraggingMarker:(GMSMarker *)marker { NSString *markerId = marker.userData[0]; - [_markersController onMarkerDragEnd:markerId coordinate:marker.position]; + [self.markersController didEndDraggingMarkerWithIdentifier:markerId location:marker.position]; } - (void)mapView:(GMSMapView *)mapView didStartDraggingMarker:(GMSMarker *)marker { NSString *markerId = marker.userData[0]; - [_markersController onMarkerDragStart:markerId coordinate:marker.position]; + [self.markersController didStartDraggingMarkerWithIdentifier:markerId location:marker.position]; } - (void)mapView:(GMSMapView *)mapView didDragMarker:(GMSMarker *)marker { NSString *markerId = marker.userData[0]; - [_markersController onMarkerDrag:markerId coordinate:marker.position]; + [self.markersController didDragMarkerWithIdentifier:markerId location:marker.position]; } - (void)mapView:(GMSMapView *)mapView didTapInfoWindowOfMarker:(GMSMarker *)marker { NSString *markerId = marker.userData[0]; - [_markersController onInfoWindowTap:markerId]; + [self.markersController didTapInfoWindowOfMarkerWithIdentifier:markerId]; } - (void)mapView:(GMSMapView *)mapView didTapOverlay:(GMSOverlay *)overlay { NSString *overlayId = overlay.userData[0]; - if ([_polylinesController hasPolylineWithId:overlayId]) { - [_polylinesController onPolylineTap:overlayId]; - } else if ([_polygonsController hasPolygonWithId:overlayId]) { - [_polygonsController onPolygonTap:overlayId]; - } else if ([_circlesController hasCircleWithId:overlayId]) { - [_circlesController onCircleTap:overlayId]; + if ([self.polylinesController hasPolylineWithIdentifier:overlayId]) { + [self.polylinesController didTapPolylineWithIdentifier:overlayId]; + } else if ([self.polygonsController hasPolygonWithIdentifier:overlayId]) { + [self.polygonsController didTapPolygonWithIdentifier:overlayId]; + } else if ([self.circlesController hasCircleWithIdentifier:overlayId]) { + [self.circlesController didTapCircleWithIdentifier:overlayId]; } } - (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate { - [_channel invokeMethod:@"map#onTap" arguments:@{@"position" : LocationToJson(coordinate)}]; + [self.channel + invokeMethod:@"map#onTap" + arguments:@{@"position" : [FLTGoogleMapJSONConversions arrayFromLocation:coordinate]}]; } - (void)mapView:(GMSMapView *)mapView didLongPressAtCoordinate:(CLLocationCoordinate2D)coordinate { - [_channel invokeMethod:@"map#onLongPress" arguments:@{@"position" : LocationToJson(coordinate)}]; -} - -@end - -#pragma mark - Implementations of JSON conversion functions. - -static NSArray *LocationToJson(CLLocationCoordinate2D position) { - return @[ @(position.latitude), @(position.longitude) ]; + [self.channel + invokeMethod:@"map#onLongPress" + arguments:@{@"position" : [FLTGoogleMapJSONConversions arrayFromLocation:coordinate]}]; } -static NSDictionary *PositionToJson(GMSCameraPosition *position) { - if (!position) { - return nil; - } - return @{ - @"target" : LocationToJson([position target]), - @"zoom" : @([position zoom]), - @"bearing" : @([position bearing]), - @"tilt" : @([position viewingAngle]), - }; -} - -static NSDictionary *PointToJson(CGPoint point) { - return @{ - @"x" : @(lroundf(point.x)), - @"y" : @(lroundf(point.y)), - }; -} - -static NSDictionary *GMSCoordinateBoundsToJson(GMSCoordinateBounds *bounds) { - if (!bounds) { - return nil; - } - return @{ - @"southwest" : LocationToJson([bounds southWest]), - @"northeast" : LocationToJson([bounds northEast]), - }; -} - -static float ToFloat(NSNumber *data) { return [FLTGoogleMapJsonConversions toFloat:data]; } - -static CLLocationCoordinate2D ToLocation(NSArray *data) { - return [FLTGoogleMapJsonConversions toLocation:data]; -} - -static int ToInt(NSNumber *data) { return [FLTGoogleMapJsonConversions toInt:data]; } - -static BOOL ToBool(NSNumber *data) { return [FLTGoogleMapJsonConversions toBool:data]; } - -static CGPoint ToPoint(NSArray *data) { return [FLTGoogleMapJsonConversions toPoint:data]; } - -static GMSCameraPosition *ToCameraPosition(NSDictionary *data) { - return [GMSCameraPosition cameraWithTarget:ToLocation(data[@"target"]) - zoom:ToFloat(data[@"zoom"]) - bearing:ToDouble(data[@"bearing"]) - viewingAngle:ToDouble(data[@"tilt"])]; -} - -static GMSCameraPosition *ToOptionalCameraPosition(NSDictionary *json) { - return json ? ToCameraPosition(json) : nil; -} - -static CGPoint ToCGPoint(NSDictionary *json) { - double x = ToDouble(json[@"x"]); - double y = ToDouble(json[@"y"]); - return CGPointMake(x, y); -} - -static GMSCoordinateBounds *ToBounds(NSArray *data) { - return [[GMSCoordinateBounds alloc] initWithCoordinate:ToLocation(data[0]) - coordinate:ToLocation(data[1])]; -} - -static GMSCoordinateBounds *ToOptionalBounds(NSArray *data) { - return (data[0] == [NSNull null]) ? nil : ToBounds(data[0]); -} - -static GMSMapViewType ToMapViewType(NSNumber *json) { - int value = ToInt(json); - return (GMSMapViewType)(value == 0 ? 5 : value); -} - -static GMSCameraUpdate *ToCameraUpdate(NSArray *data) { - NSString *update = data[0]; - if ([update isEqualToString:@"newCameraPosition"]) { - return [GMSCameraUpdate setCamera:ToCameraPosition(data[1])]; - } else if ([update isEqualToString:@"newLatLng"]) { - return [GMSCameraUpdate setTarget:ToLocation(data[1])]; - } else if ([update isEqualToString:@"newLatLngBounds"]) { - return [GMSCameraUpdate fitBounds:ToBounds(data[1]) withPadding:ToDouble(data[2])]; - } else if ([update isEqualToString:@"newLatLngZoom"]) { - return [GMSCameraUpdate setTarget:ToLocation(data[1]) zoom:ToFloat(data[2])]; - } else if ([update isEqualToString:@"scrollBy"]) { - return [GMSCameraUpdate scrollByX:ToDouble(data[1]) Y:ToDouble(data[2])]; - } else if ([update isEqualToString:@"zoomBy"]) { - if (data.count == 2) { - return [GMSCameraUpdate zoomBy:ToFloat(data[1])]; - } else { - return [GMSCameraUpdate zoomBy:ToFloat(data[1]) atPoint:ToPoint(data[2])]; - } - } else if ([update isEqualToString:@"zoomIn"]) { - return [GMSCameraUpdate zoomIn]; - } else if ([update isEqualToString:@"zoomOut"]) { - return [GMSCameraUpdate zoomOut]; - } else if ([update isEqualToString:@"zoomTo"]) { - return [GMSCameraUpdate zoomTo:ToFloat(data[1])]; - } - return nil; -} - -static void InterpretMapOptions(NSDictionary *data, id sink) { ++ (void)interpretMapOptions:(NSDictionary *)data sink:(id)sink { NSArray *cameraTargetBounds = data[@"cameraTargetBounds"]; - if (cameraTargetBounds) { - [sink setCameraTargetBounds:ToOptionalBounds(cameraTargetBounds)]; + if (cameraTargetBounds && cameraTargetBounds != (id)[NSNull null]) { + [sink + setCameraTargetBounds:cameraTargetBounds.count > 0 && cameraTargetBounds[0] != [NSNull null] + ? [FLTGoogleMapJSONConversions + coordinateBoundsFromLatlongs:cameraTargetBounds.firstObject] + : nil]; } NSNumber *compassEnabled = data[@"compassEnabled"]; - if (compassEnabled != nil) { - [sink setCompassEnabled:ToBool(compassEnabled)]; + if (compassEnabled && compassEnabled != (id)[NSNull null]) { + [sink setCompassEnabled:[compassEnabled boolValue]]; } id indoorEnabled = data[@"indoorEnabled"]; - if (indoorEnabled) { - [sink setIndoorEnabled:ToBool(indoorEnabled)]; + if (indoorEnabled && indoorEnabled != [NSNull null]) { + [sink setIndoorEnabled:[indoorEnabled boolValue]]; } id trafficEnabled = data[@"trafficEnabled"]; - if (trafficEnabled) { - [sink setTrafficEnabled:ToBool(trafficEnabled)]; + if (trafficEnabled && trafficEnabled != [NSNull null]) { + [sink setTrafficEnabled:[trafficEnabled boolValue]]; } id buildingsEnabled = data[@"buildingsEnabled"]; - if (buildingsEnabled) { - [sink setBuildingsEnabled:ToBool(buildingsEnabled)]; + if (buildingsEnabled && buildingsEnabled != [NSNull null]) { + [sink setBuildingsEnabled:[buildingsEnabled boolValue]]; } id mapType = data[@"mapType"]; - if (mapType) { - [sink setMapType:ToMapViewType(mapType)]; + if (mapType && mapType != [NSNull null]) { + [sink setMapType:[FLTGoogleMapJSONConversions mapViewTypeFromTypeValue:mapType]]; } NSArray *zoomData = data[@"minMaxZoomPreference"]; - if (zoomData) { - float minZoom = (zoomData[0] == [NSNull null]) ? kGMSMinZoomLevel : ToFloat(zoomData[0]); - float maxZoom = (zoomData[1] == [NSNull null]) ? kGMSMaxZoomLevel : ToFloat(zoomData[1]); + if (zoomData && zoomData != (id)[NSNull null]) { + float minZoom = (zoomData[0] == [NSNull null]) ? kGMSMinZoomLevel : [zoomData[0] floatValue]; + float maxZoom = (zoomData[1] == [NSNull null]) ? kGMSMaxZoomLevel : [zoomData[1] floatValue]; [sink setMinZoom:minZoom maxZoom:maxZoom]; } NSArray *paddingData = data[@"padding"]; if (paddingData) { - float top = (paddingData[0] == [NSNull null]) ? 0 : ToFloat(paddingData[0]); - float left = (paddingData[1] == [NSNull null]) ? 0 : ToFloat(paddingData[1]); - float bottom = (paddingData[2] == [NSNull null]) ? 0 : ToFloat(paddingData[2]); - float right = (paddingData[3] == [NSNull null]) ? 0 : ToFloat(paddingData[3]); + float top = (paddingData[0] == [NSNull null]) ? 0 : [paddingData[0] floatValue]; + float left = (paddingData[1] == [NSNull null]) ? 0 : [paddingData[1] floatValue]; + float bottom = (paddingData[2] == [NSNull null]) ? 0 : [paddingData[2] floatValue]; + float right = (paddingData[3] == [NSNull null]) ? 0 : [paddingData[3] floatValue]; [sink setPaddingTop:top left:left bottom:bottom right:right]; } NSNumber *rotateGesturesEnabled = data[@"rotateGesturesEnabled"]; - if (rotateGesturesEnabled != nil) { - [sink setRotateGesturesEnabled:ToBool(rotateGesturesEnabled)]; + if (rotateGesturesEnabled && rotateGesturesEnabled != (id)[NSNull null]) { + [sink setRotateGesturesEnabled:[rotateGesturesEnabled boolValue]]; } NSNumber *scrollGesturesEnabled = data[@"scrollGesturesEnabled"]; - if (scrollGesturesEnabled != nil) { - [sink setScrollGesturesEnabled:ToBool(scrollGesturesEnabled)]; + if (scrollGesturesEnabled && scrollGesturesEnabled != (id)[NSNull null]) { + [sink setScrollGesturesEnabled:[scrollGesturesEnabled boolValue]]; } NSNumber *tiltGesturesEnabled = data[@"tiltGesturesEnabled"]; - if (tiltGesturesEnabled != nil) { - [sink setTiltGesturesEnabled:ToBool(tiltGesturesEnabled)]; + if (tiltGesturesEnabled && tiltGesturesEnabled != (id)[NSNull null]) { + [sink setTiltGesturesEnabled:[tiltGesturesEnabled boolValue]]; } NSNumber *trackCameraPosition = data[@"trackCameraPosition"]; - if (trackCameraPosition != nil) { - [sink setTrackCameraPosition:ToBool(trackCameraPosition)]; + if (trackCameraPosition && trackCameraPosition != (id)[NSNull null]) { + [sink setTrackCameraPosition:[trackCameraPosition boolValue]]; } NSNumber *zoomGesturesEnabled = data[@"zoomGesturesEnabled"]; - if (zoomGesturesEnabled != nil) { - [sink setZoomGesturesEnabled:ToBool(zoomGesturesEnabled)]; + if (zoomGesturesEnabled && zoomGesturesEnabled != (id)[NSNull null]) { + [sink setZoomGesturesEnabled:[zoomGesturesEnabled boolValue]]; } NSNumber *myLocationEnabled = data[@"myLocationEnabled"]; - if (myLocationEnabled != nil) { - [sink setMyLocationEnabled:ToBool(myLocationEnabled)]; + if (myLocationEnabled && myLocationEnabled != (id)[NSNull null]) { + [sink setMyLocationEnabled:[myLocationEnabled boolValue]]; } NSNumber *myLocationButtonEnabled = data[@"myLocationButtonEnabled"]; - if (myLocationButtonEnabled != nil) { - [sink setMyLocationButtonEnabled:ToBool(myLocationButtonEnabled)]; + if (myLocationButtonEnabled && myLocationButtonEnabled != (id)[NSNull null]) { + [sink setMyLocationButtonEnabled:[myLocationButtonEnabled boolValue]]; } } + +@end diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.h index 8734c06fe929..b1adf18ff94f 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.h @@ -26,9 +26,8 @@ NS_ASSUME_NONNULL_BEGIN // Defines marker controllable by Flutter. @interface FLTGoogleMapMarkerController : NSObject -@property(atomic, readonly) NSString *markerId; - (instancetype)initMarkerWithPosition:(CLLocationCoordinate2D)position - markerId:(NSString *)markerId + identifier:(NSString *)identifier mapView:(GMSMapView *)mapView; - (void)showInfoWindow; - (void)hideInfoWindow; @@ -38,20 +37,24 @@ NS_ASSUME_NONNULL_BEGIN @end @interface FLTMarkersController : NSObject -- (instancetype)init:(FlutterMethodChannel *)methodChannel - mapView:(GMSMapView *)mapView - registrar:(NSObject *)registrar; +- (instancetype)initWithMethodChannel:(FlutterMethodChannel *)methodChannel + mapView:(GMSMapView *)mapView + registrar:(NSObject *)registrar; - (void)addMarkers:(NSArray *)markersToAdd; - (void)changeMarkers:(NSArray *)markersToChange; -- (void)removeMarkerIds:(NSArray *)markerIdsToRemove; -- (BOOL)onMarkerTap:(NSString *)markerId; -- (void)onMarkerDragStart:(NSString *)markerId coordinate:(CLLocationCoordinate2D)coordinate; -- (void)onMarkerDragEnd:(NSString *)markerId coordinate:(CLLocationCoordinate2D)coordinate; -- (void)onMarkerDrag:(NSString *)markerId coordinate:(CLLocationCoordinate2D)coordinate; -- (void)onInfoWindowTap:(NSString *)markerId; -- (void)showMarkerInfoWindow:(NSString *)markerId result:(FlutterResult)result; -- (void)hideMarkerInfoWindow:(NSString *)markerId result:(FlutterResult)result; -- (void)isMarkerInfoWindowShown:(NSString *)markerId result:(FlutterResult)result; +- (void)removeMarkersWithIdentifiers:(NSArray *)identifiers; +- (BOOL)didTapMarkerWithIdentifier:(NSString *)identifier; +- (void)didStartDraggingMarkerWithIdentifier:(NSString *)identifier + location:(CLLocationCoordinate2D)coordinate; +- (void)didEndDraggingMarkerWithIdentifier:(NSString *)identifier + location:(CLLocationCoordinate2D)coordinate; +- (void)didDragMarkerWithIdentifier:(NSString *)identifier + location:(CLLocationCoordinate2D)coordinate; +- (void)didTapInfoWindowOfMarkerWithIdentifier:(NSString *)identifier; +- (void)showMarkerInfoWindowWithIdentifier:(NSString *)identifier result:(FlutterResult)result; +- (void)hideMarkerInfoWindowWithIdentifier:(NSString *)identifier result:(FlutterResult)result; +- (void)isInfoWindowShownForMarkerWithIdentifier:(NSString *)identifier + result:(FlutterResult)result; @end NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m index c2877e2bd78f..fe1a166390a1 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m @@ -5,182 +5,333 @@ #import "GoogleMapMarkerController.h" #import "JsonConversions.h" -static UIImage *ExtractIcon(NSObject *registrar, NSArray *icon); -static void InterpretInfoWindow(id sink, NSDictionary *data); +@interface FLTGoogleMapMarkerController () + +@property(strong, nonatomic) GMSMarker *marker; +@property(weak, nonatomic) GMSMapView *mapView; +@property(assign, nonatomic) BOOL consumeTapEvents; + +@end + +@implementation FLTGoogleMapMarkerController -@implementation FLTGoogleMapMarkerController { - GMSMarker *_marker; - GMSMapView *_mapView; - BOOL _consumeTapEvents; -} - (instancetype)initMarkerWithPosition:(CLLocationCoordinate2D)position - markerId:(NSString *)markerId + identifier:(NSString *)identifier mapView:(GMSMapView *)mapView { self = [super init]; if (self) { _marker = [GMSMarker markerWithPosition:position]; _mapView = mapView; - _markerId = markerId; - _marker.userData = @[ _markerId ]; - _consumeTapEvents = NO; + _marker.userData = @[ identifier ]; } return self; } + - (void)showInfoWindow { - _mapView.selectedMarker = _marker; + self.mapView.selectedMarker = self.marker; } + - (void)hideInfoWindow { - if (_mapView.selectedMarker == _marker) { - _mapView.selectedMarker = nil; + if (self.mapView.selectedMarker == self.marker) { + self.mapView.selectedMarker = nil; } } + - (BOOL)isInfoWindowShown { - return _mapView.selectedMarker == _marker; + return self.mapView.selectedMarker == self.marker; } + - (BOOL)consumeTapEvents { - return _consumeTapEvents; + return self.consumeTapEvents; } + - (void)removeMarker { - _marker.map = nil; + self.marker.map = nil; } #pragma mark - FLTGoogleMapMarkerOptionsSink methods - (void)setAlpha:(float)alpha { - _marker.opacity = alpha; + self.marker.opacity = alpha; } + - (void)setAnchor:(CGPoint)anchor { - _marker.groundAnchor = anchor; + self.marker.groundAnchor = anchor; } + - (void)setConsumeTapEvents:(BOOL)consumes { - _consumeTapEvents = consumes; + self.consumeTapEvents = consumes; } + - (void)setDraggable:(BOOL)draggable { - _marker.draggable = draggable; + self.marker.draggable = draggable; } + - (void)setFlat:(BOOL)flat { - _marker.flat = flat; + self.marker.flat = flat; } + - (void)setIcon:(UIImage *)icon { - _marker.icon = icon; + self.marker.icon = icon; } + - (void)setInfoWindowAnchor:(CGPoint)anchor { - _marker.infoWindowAnchor = anchor; + self.marker.infoWindowAnchor = anchor; } + - (void)setInfoWindowTitle:(NSString *)title snippet:(NSString *)snippet { - _marker.title = title; - _marker.snippet = snippet; + self.marker.title = title; + self.marker.snippet = snippet; } + - (void)setPosition:(CLLocationCoordinate2D)position { - _marker.position = position; + self.marker.position = position; } + - (void)setRotation:(CLLocationDegrees)rotation { - _marker.rotation = rotation; + self.marker.rotation = rotation; } + - (void)setVisible:(BOOL)visible { - _marker.map = visible ? _mapView : nil; + self.marker.map = visible ? self.mapView : nil; } + - (void)setZIndex:(int)zIndex { - _marker.zIndex = zIndex; + self.marker.zIndex = zIndex; } + +@end + +@interface FLTMarkersController () + +@property(strong, nonatomic) NSMutableDictionary *markerIdentifierToController; +@property(weak, nonatomic) FlutterMethodChannel *methodChannel; +@property(weak, nonatomic) NSObject *registrar; +@property(weak, nonatomic) GMSMapView *mapView; + @end -static double ToDouble(NSNumber *data) { return [FLTGoogleMapJsonConversions toDouble:data]; } +@implementation FLTMarkersController + +- (instancetype)initWithMethodChannel:(FlutterMethodChannel *)methodChannel + mapView:(GMSMapView *)mapView + registrar:(NSObject *)registrar { + self = [super init]; + if (self) { + _methodChannel = methodChannel; + _mapView = mapView; + _markerIdentifierToController = [[NSMutableDictionary alloc] init]; + _registrar = registrar; + } + return self; +} + +- (void)addMarkers:(NSArray *)markersToAdd { + for (NSDictionary *marker in markersToAdd) { + CLLocationCoordinate2D position = [FLTMarkersController getPosition:marker]; + NSString *identifier = marker[@"markerId"]; + FLTGoogleMapMarkerController *controller = + [[FLTGoogleMapMarkerController alloc] initMarkerWithPosition:position + identifier:identifier + mapView:self.mapView]; + [FLTMarkersController interpretMarkerOptions:marker sink:controller registrar:self.registrar]; + self.markerIdentifierToController[identifier] = controller; + } +} + +- (void)changeMarkers:(NSArray *)markersToChange { + for (NSDictionary *marker in markersToChange) { + NSString *identifier = marker[@"markerId"]; + FLTGoogleMapMarkerController *controller = self.markerIdentifierToController[identifier]; + if (!controller) { + continue; + } + [FLTMarkersController interpretMarkerOptions:marker sink:controller registrar:self.registrar]; + } +} + +- (void)removeMarkersWithIdentifiers:(NSArray *)identifiers { + for (NSString *identifier in identifiers) { + FLTGoogleMapMarkerController *controller = self.markerIdentifierToController[identifier]; + if (!controller) { + continue; + } + [controller removeMarker]; + [self.markerIdentifierToController removeObjectForKey:identifier]; + } +} + +- (BOOL)didTapMarkerWithIdentifier:(NSString *)identifier { + if (!identifier) { + return NO; + } + FLTGoogleMapMarkerController *controller = self.markerIdentifierToController[identifier]; + if (!controller) { + return NO; + } + [self.methodChannel invokeMethod:@"marker#onTap" arguments:@{@"markerId" : identifier}]; + return controller.consumeTapEvents; +} -static float ToFloat(NSNumber *data) { return [FLTGoogleMapJsonConversions toFloat:data]; } +- (void)didStartDraggingMarkerWithIdentifier:(NSString *)identifier + location:(CLLocationCoordinate2D)location { + if (!identifier) { + return; + } + FLTGoogleMapMarkerController *controller = self.markerIdentifierToController[identifier]; + if (!controller) { + return; + } + [self.methodChannel invokeMethod:@"marker#onDragStart" + arguments:@{ + @"markerId" : identifier, + @"position" : [FLTGoogleMapJSONConversions arrayFromLocation:location] + }]; +} + +- (void)didDragMarkerWithIdentifier:(NSString *)identifier + location:(CLLocationCoordinate2D)location { + if (!identifier) { + return; + } + FLTGoogleMapMarkerController *controller = self.markerIdentifierToController[identifier]; + if (!controller) { + return; + } + [self.methodChannel invokeMethod:@"marker#onDrag" + arguments:@{ + @"markerId" : identifier, + @"position" : [FLTGoogleMapJSONConversions arrayFromLocation:location] + }]; +} + +- (void)didEndDraggingMarkerWithIdentifier:(NSString *)identifier + location:(CLLocationCoordinate2D)location { + FLTGoogleMapMarkerController *controller = self.markerIdentifierToController[identifier]; + if (!controller) { + return; + } + [self.methodChannel invokeMethod:@"marker#onDragEnd" + arguments:@{ + @"markerId" : identifier, + @"position" : [FLTGoogleMapJSONConversions arrayFromLocation:location] + }]; +} -static CLLocationCoordinate2D ToLocation(NSArray *data) { - return [FLTGoogleMapJsonConversions toLocation:data]; +- (void)didTapInfoWindowOfMarkerWithIdentifier:(NSString *)identifier { + if (identifier && self.markerIdentifierToController[identifier]) { + [self.methodChannel invokeMethod:@"infoWindow#onTap" arguments:@{@"markerId" : identifier}]; + } } -static int ToInt(NSNumber *data) { return [FLTGoogleMapJsonConversions toInt:data]; } +- (void)showMarkerInfoWindowWithIdentifier:(NSString *)identifier result:(FlutterResult)result { + FLTGoogleMapMarkerController *controller = self.markerIdentifierToController[identifier]; + if (controller) { + [controller showInfoWindow]; + result(nil); + } else { + result([FlutterError errorWithCode:@"Invalid markerId" + message:@"showInfoWindow called with invalid markerId" + details:nil]); + } +} -static BOOL ToBool(NSNumber *data) { return [FLTGoogleMapJsonConversions toBool:data]; } +- (void)hideMarkerInfoWindowWithIdentifier:(NSString *)identifier result:(FlutterResult)result { + FLTGoogleMapMarkerController *controller = self.markerIdentifierToController[identifier]; + if (controller) { + [controller hideInfoWindow]; + result(nil); + } else { + result([FlutterError errorWithCode:@"Invalid markerId" + message:@"hideInfoWindow called with invalid markerId" + details:nil]); + } +} -static CGPoint ToPoint(NSArray *data) { return [FLTGoogleMapJsonConversions toPoint:data]; } +- (void)isInfoWindowShownForMarkerWithIdentifier:(NSString *)identifier + result:(FlutterResult)result { + FLTGoogleMapMarkerController *controller = self.markerIdentifierToController[identifier]; + if (controller) { + result(@([controller isInfoWindowShown])); + } else { + result([FlutterError errorWithCode:@"Invalid markerId" + message:@"isInfoWindowShown called with invalid markerId" + details:nil]); + } +} -static NSArray *PositionToJson(CLLocationCoordinate2D data) { - return [FLTGoogleMapJsonConversions positionToJson:data]; ++ (CLLocationCoordinate2D)getPosition:(NSDictionary *)marker { + NSArray *position = marker[@"position"]; + return [FLTGoogleMapJSONConversions locationFromLatlong:position]; } -static void InterpretMarkerOptions(NSDictionary *data, id sink, - NSObject *registrar) { ++ (void)interpretMarkerOptions:(NSDictionary *)data + sink:(id)sink + registrar:(NSObject *)registrar { NSNumber *alpha = data[@"alpha"]; - if (alpha != nil) { - [sink setAlpha:ToFloat(alpha)]; + if (alpha && alpha != (id)[NSNull null]) { + [sink setAlpha:[alpha floatValue]]; } NSArray *anchor = data[@"anchor"]; - if (anchor) { - [sink setAnchor:ToPoint(anchor)]; + if (anchor && anchor != (id)[NSNull null]) { + [sink setAnchor:[FLTGoogleMapJSONConversions pointFromArray:anchor]]; } NSNumber *draggable = data[@"draggable"]; - if (draggable != nil) { - [sink setDraggable:ToBool(draggable)]; + if (draggable && draggable != (id)[NSNull null]) { + [sink setDraggable:[draggable boolValue]]; } NSArray *icon = data[@"icon"]; - if (icon) { - UIImage *image = ExtractIcon(registrar, icon); + if (icon && icon != (id)[NSNull null]) { + UIImage *image = [FLTMarkersController extractIconFromData:icon registrar:registrar]; [sink setIcon:image]; } NSNumber *flat = data[@"flat"]; - if (flat != nil) { - [sink setFlat:ToBool(flat)]; + if (flat && flat != (id)[NSNull null]) { + [sink setFlat:[flat boolValue]]; } NSNumber *consumeTapEvents = data[@"consumeTapEvents"]; - if (consumeTapEvents != nil) { - [sink setConsumeTapEvents:ToBool(consumeTapEvents)]; + if (consumeTapEvents && consumeTapEvents != (id)[NSNull null]) { + [sink setConsumeTapEvents:[consumeTapEvents boolValue]]; } - InterpretInfoWindow(sink, data); + [FLTMarkersController interpretInfoWindow:data sink:sink]; NSArray *position = data[@"position"]; - if (position) { - [sink setPosition:ToLocation(position)]; + if (position && position != (id)[NSNull null]) { + [sink setPosition:[FLTGoogleMapJSONConversions locationFromLatlong:position]]; } NSNumber *rotation = data[@"rotation"]; - if (rotation != nil) { - [sink setRotation:ToDouble(rotation)]; + if (rotation && rotation != (id)[NSNull null]) { + [sink setRotation:[rotation doubleValue]]; } NSNumber *visible = data[@"visible"]; - if (visible != nil) { - [sink setVisible:ToBool(visible)]; + if (visible && visible != (id)[NSNull null]) { + [sink setVisible:[visible boolValue]]; } NSNumber *zIndex = data[@"zIndex"]; - if (zIndex != nil) { - [sink setZIndex:ToInt(zIndex)]; + if (zIndex && zIndex != (id)[NSNull null]) { + [sink setZIndex:[zIndex intValue]]; } } -static void InterpretInfoWindow(id sink, NSDictionary *data) { ++ (void)interpretInfoWindow:(NSDictionary *)data sink:(id)sink { NSDictionary *infoWindow = data[@"infoWindow"]; - if (infoWindow) { + if (infoWindow && infoWindow != (id)[NSNull null]) { NSString *title = infoWindow[@"title"]; NSString *snippet = infoWindow[@"snippet"]; - if (title) { + if (title && title != (id)[NSNull null]) { [sink setInfoWindowTitle:title snippet:snippet]; } NSArray *infoWindowAnchor = infoWindow[@"infoWindowAnchor"]; - if (infoWindowAnchor) { - [sink setInfoWindowAnchor:ToPoint(infoWindowAnchor)]; + if (infoWindowAnchor && infoWindowAnchor != (id)[NSNull null]) { + [sink setInfoWindowAnchor:[FLTGoogleMapJSONConversions pointFromArray:infoWindowAnchor]]; } } } -static UIImage *scaleImage(UIImage *image, NSNumber *scaleParam) { - double scale = 1.0; - if ([scaleParam isKindOfClass:[NSNumber class]]) { - scale = scaleParam.doubleValue; - } - if (fabs(scale - 1) > 1e-3) { - return [UIImage imageWithCGImage:[image CGImage] - scale:(image.scale * scale) - orientation:(image.imageOrientation)]; - } - return image; -} - -static UIImage *ExtractIcon(NSObject *registrar, NSArray *iconData) { ++ (UIImage *)extractIconFromData:(NSArray *)iconData + registrar:(NSObject *)registrar { UIImage *image; if ([iconData.firstObject isEqualToString:@"defaultMarker"]) { - CGFloat hue = (iconData.count == 1) ? 0.0f : ToDouble(iconData[1]); + CGFloat hue = (iconData.count == 1) ? 0.0f : [iconData[1] doubleValue]; image = [GMSMarker markerImageWithColor:[UIColor colorWithHue:hue / 360.0 saturation:1.0 brightness:0.7 @@ -195,8 +346,8 @@ static void InterpretInfoWindow(id sink, NSDictio } else if ([iconData.firstObject isEqualToString:@"fromAssetImage"]) { if (iconData.count == 3) { image = [UIImage imageNamed:[registrar lookupKeyForAsset:iconData[1]]]; - NSNumber *scaleParam = iconData[2]; - image = scaleImage(image, scaleParam); + id scaleParam = iconData[2]; + image = [FLTMarkersController scaleImage:image by:scaleParam]; } else { NSString *error = [NSString stringWithFormat:@"'fromAssetImage' should have exactly 3 arguments. Got: %lu", @@ -231,146 +382,17 @@ static void InterpretInfoWindow(id sink, NSDictio return image; } -@implementation FLTMarkersController { - NSMutableDictionary *_markerIdToController; - FlutterMethodChannel *_methodChannel; - NSObject *_registrar; - GMSMapView *_mapView; -} -- (instancetype)init:(FlutterMethodChannel *)methodChannel - mapView:(GMSMapView *)mapView - registrar:(NSObject *)registrar { - self = [super init]; - if (self) { - _methodChannel = methodChannel; - _mapView = mapView; - _markerIdToController = [NSMutableDictionary dictionaryWithCapacity:1]; - _registrar = registrar; - } - return self; -} -- (void)addMarkers:(NSArray *)markersToAdd { - for (NSDictionary *marker in markersToAdd) { - CLLocationCoordinate2D position = [FLTMarkersController getPosition:marker]; - NSString *markerId = [FLTMarkersController getMarkerId:marker]; - FLTGoogleMapMarkerController *controller = - [[FLTGoogleMapMarkerController alloc] initMarkerWithPosition:position - markerId:markerId - mapView:_mapView]; - InterpretMarkerOptions(marker, controller, _registrar); - _markerIdToController[markerId] = controller; - } -} -- (void)changeMarkers:(NSArray *)markersToChange { - for (NSDictionary *marker in markersToChange) { - NSString *markerId = [FLTMarkersController getMarkerId:marker]; - FLTGoogleMapMarkerController *controller = _markerIdToController[markerId]; - if (!controller) { - continue; - } - InterpretMarkerOptions(marker, controller, _registrar); - } -} -- (void)removeMarkerIds:(NSArray *)markerIdsToRemove { - for (NSString *markerId in markerIdsToRemove) { - if (!markerId) { - continue; - } - FLTGoogleMapMarkerController *controller = _markerIdToController[markerId]; - if (!controller) { - continue; - } - [controller removeMarker]; - [_markerIdToController removeObjectForKey:markerId]; - } -} -- (BOOL)onMarkerTap:(NSString *)markerId { - if (!markerId) { - return NO; - } - FLTGoogleMapMarkerController *controller = _markerIdToController[markerId]; - if (!controller) { - return NO; - } - [_methodChannel invokeMethod:@"marker#onTap" arguments:@{@"markerId" : markerId}]; - return controller.consumeTapEvents; -} -- (void)onMarkerDragStart:(NSString *)markerId coordinate:(CLLocationCoordinate2D)coordinate { - if (!markerId) { - return; - } - FLTGoogleMapMarkerController *controller = _markerIdToController[markerId]; - if (!controller) { - return; - } - [_methodChannel invokeMethod:@"marker#onDragStart" - arguments:@{@"markerId" : markerId, @"position" : PositionToJson(coordinate)}]; -} -- (void)onMarkerDrag:(NSString *)markerId coordinate:(CLLocationCoordinate2D)coordinate { - if (!markerId) { - return; - } - FLTGoogleMapMarkerController *controller = _markerIdToController[markerId]; - if (!controller) { - return; - } - [_methodChannel invokeMethod:@"marker#onDrag" - arguments:@{@"markerId" : markerId, @"position" : PositionToJson(coordinate)}]; -} -- (void)onMarkerDragEnd:(NSString *)markerId coordinate:(CLLocationCoordinate2D)coordinate { - if (!markerId) { - return; - } - FLTGoogleMapMarkerController *controller = _markerIdToController[markerId]; - if (!controller) { - return; - } - [_methodChannel invokeMethod:@"marker#onDragEnd" - arguments:@{@"markerId" : markerId, @"position" : PositionToJson(coordinate)}]; -} -- (void)onInfoWindowTap:(NSString *)markerId { - if (markerId && _markerIdToController[markerId]) { - [_methodChannel invokeMethod:@"infoWindow#onTap" arguments:@{@"markerId" : markerId}]; - } -} -- (void)showMarkerInfoWindow:(NSString *)markerId result:(FlutterResult)result { - FLTGoogleMapMarkerController *controller = _markerIdToController[markerId]; - if (controller) { - [controller showInfoWindow]; - result(nil); - } else { - result([FlutterError errorWithCode:@"Invalid markerId" - message:@"showInfoWindow called with invalid markerId" - details:nil]); - } -} -- (void)hideMarkerInfoWindow:(NSString *)markerId result:(FlutterResult)result { - FLTGoogleMapMarkerController *controller = _markerIdToController[markerId]; - if (controller) { - [controller hideInfoWindow]; - result(nil); - } else { - result([FlutterError errorWithCode:@"Invalid markerId" - message:@"hideInfoWindow called with invalid markerId" - details:nil]); ++ (UIImage *)scaleImage:(UIImage *)image by:(id)scaleParam { + double scale = 1.0; + if ([scaleParam isKindOfClass:[NSNumber class]]) { + scale = [scaleParam doubleValue]; } -} -- (void)isMarkerInfoWindowShown:(NSString *)markerId result:(FlutterResult)result { - FLTGoogleMapMarkerController *controller = _markerIdToController[markerId]; - if (controller) { - result(@([controller isInfoWindowShown])); - } else { - result([FlutterError errorWithCode:@"Invalid markerId" - message:@"isInfoWindowShown called with invalid markerId" - details:nil]); + if (fabs(scale - 1) > 1e-3) { + return [UIImage imageWithCGImage:[image CGImage] + scale:(image.scale * scale) + orientation:(image.imageOrientation)]; } + return image; } -+ (CLLocationCoordinate2D)getPosition:(NSDictionary *)marker { - NSArray *position = marker[@"position"]; - return ToLocation(position); -} -+ (NSString *)getMarkerId:(NSDictionary *)marker { - return marker[@"markerId"]; -} @end diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.h index bdc5dd4bf850..833fd92f48d3 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.h @@ -19,9 +19,8 @@ // Defines polygon controllable by Flutter. @interface FLTGoogleMapPolygonController : NSObject -@property(atomic, readonly) NSString *polygonId; - (instancetype)initPolygonWithPath:(GMSMutablePath *)path - polygonId:(NSString *)polygonId + identifier:(NSString *)identifier mapView:(GMSMapView *)mapView; - (void)removePolygon; @end @@ -32,7 +31,7 @@ registrar:(NSObject *)registrar; - (void)addPolygons:(NSArray *)polygonsToAdd; - (void)changePolygons:(NSArray *)polygonsToChange; -- (void)removePolygonIds:(NSArray *)polygonIdsToRemove; -- (void)onPolygonTap:(NSString *)polygonId; -- (bool)hasPolygonWithId:(NSString *)polygonId; +- (void)removePolygonWithIdentifiers:(NSArray *)identifiers; +- (void)didTapPolygonWithIdentifier:(NSString *)identifier; +- (bool)hasPolygonWithIdentifier:(NSString *)identifier; @end diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m index 649ba98bca13..a7f49747c27d 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m @@ -5,37 +5,41 @@ #import "GoogleMapPolygonController.h" #import "JsonConversions.h" -@implementation FLTGoogleMapPolygonController { - GMSPolygon *_polygon; - GMSMapView *_mapView; -} +@interface FLTGoogleMapPolygonController () + +@property(strong, nonatomic) GMSPolygon *polygon; +@property(weak, nonatomic) GMSMapView *mapView; + +@end + +@implementation FLTGoogleMapPolygonController + - (instancetype)initPolygonWithPath:(GMSMutablePath *)path - polygonId:(NSString *)polygonId + identifier:(NSString *)identifier mapView:(GMSMapView *)mapView { self = [super init]; if (self) { _polygon = [GMSPolygon polygonWithPath:path]; _mapView = mapView; - _polygonId = polygonId; - _polygon.userData = @[ polygonId ]; + _polygon.userData = @[ identifier ]; } return self; } - (void)removePolygon { - _polygon.map = nil; + self.polygon.map = nil; } #pragma mark - FLTGoogleMapPolygonOptionsSink methods - (void)setConsumeTapEvents:(BOOL)consumes { - _polygon.tappable = consumes; + self.polygon.tappable = consumes; } - (void)setVisible:(BOOL)visible { - _polygon.map = visible ? _mapView : nil; + self.polygon.map = visible ? self.mapView : nil; } - (void)setZIndex:(int)zIndex { - _polygon.zIndex = zIndex; + self.polygon.zIndex = zIndex; } - (void)setPoints:(NSArray *)points { GMSMutablePath *path = [GMSMutablePath path]; @@ -43,7 +47,7 @@ - (void)setPoints:(NSArray *)points { for (CLLocation *location in points) { [path addCoordinate:location.coordinate]; } - _polygon.path = path; + self.polygon.path = path; } - (void)setHoles:(NSArray *> *)rawHoles { NSMutableArray *holes = [[NSMutableArray alloc] init]; @@ -56,83 +60,31 @@ - (void)setHoles:(NSArray *> *)rawHoles { [holes addObject:path]; } - _polygon.holes = holes; + self.polygon.holes = holes; } - (void)setFillColor:(UIColor *)color { - _polygon.fillColor = color; + self.polygon.fillColor = color; } - (void)setStrokeColor:(UIColor *)color { - _polygon.strokeColor = color; + self.polygon.strokeColor = color; } - (void)setStrokeWidth:(CGFloat)width { - _polygon.strokeWidth = width; + self.polygon.strokeWidth = width; } @end -static int ToInt(NSNumber *data) { return [FLTGoogleMapJsonConversions toInt:data]; } - -static BOOL ToBool(NSNumber *data) { return [FLTGoogleMapJsonConversions toBool:data]; } - -static NSArray *ToPoints(NSArray *data) { - return [FLTGoogleMapJsonConversions toPoints:data]; -} - -static NSArray *> *ToHoles(NSArray *data) { - return [FLTGoogleMapJsonConversions toHoles:data]; -} - -static UIColor *ToColor(NSNumber *data) { return [FLTGoogleMapJsonConversions toColor:data]; } +@interface FLTPolygonsController () -static void InterpretPolygonOptions(NSDictionary *data, id sink, - NSObject *registrar) { - NSNumber *consumeTapEvents = data[@"consumeTapEvents"]; - if (consumeTapEvents != nil) { - [sink setConsumeTapEvents:ToBool(consumeTapEvents)]; - } +@property(strong, nonatomic) NSMutableDictionary *polygonIdentifierToController; +@property(weak, nonatomic) FlutterMethodChannel *methodChannel; +@property(weak, nonatomic) NSObject *registrar; +@property(weak, nonatomic) GMSMapView *mapView; - NSNumber *visible = data[@"visible"]; - if (visible != nil) { - [sink setVisible:ToBool(visible)]; - } - - NSNumber *zIndex = data[@"zIndex"]; - if (zIndex != nil) { - [sink setZIndex:ToInt(zIndex)]; - } - - NSArray *points = data[@"points"]; - if (points) { - [sink setPoints:ToPoints(points)]; - } - - NSArray *holes = data[@"holes"]; - if (holes) { - [sink setHoles:ToHoles(holes)]; - } - - NSNumber *fillColor = data[@"fillColor"]; - if (fillColor != nil) { - [sink setFillColor:ToColor(fillColor)]; - } - - NSNumber *strokeColor = data[@"strokeColor"]; - if (strokeColor != nil) { - [sink setStrokeColor:ToColor(strokeColor)]; - } +@end - NSNumber *strokeWidth = data[@"strokeWidth"]; - if (strokeWidth != nil) { - [sink setStrokeWidth:ToInt(strokeWidth)]; - } -} +@implementation FLTPolygonsController -@implementation FLTPolygonsController { - NSMutableDictionary *_polygonIdToController; - FlutterMethodChannel *_methodChannel; - NSObject *_registrar; - GMSMapView *_mapView; -} - (instancetype)init:(FlutterMethodChannel *)methodChannel mapView:(GMSMapView *)mapView registrar:(NSObject *)registrar { @@ -140,72 +92,124 @@ - (instancetype)init:(FlutterMethodChannel *)methodChannel if (self) { _methodChannel = methodChannel; _mapView = mapView; - _polygonIdToController = [NSMutableDictionary dictionaryWithCapacity:1]; + _polygonIdentifierToController = [NSMutableDictionary dictionaryWithCapacity:1]; _registrar = registrar; } return self; } + - (void)addPolygons:(NSArray *)polygonsToAdd { for (NSDictionary *polygon in polygonsToAdd) { GMSMutablePath *path = [FLTPolygonsController getPath:polygon]; - NSString *polygonId = [FLTPolygonsController getPolygonId:polygon]; + NSString *identifier = [FLTPolygonsController getPolygonId:polygon]; FLTGoogleMapPolygonController *controller = [[FLTGoogleMapPolygonController alloc] initPolygonWithPath:path - polygonId:polygonId - mapView:_mapView]; - InterpretPolygonOptions(polygon, controller, _registrar); - _polygonIdToController[polygonId] = controller; + identifier:identifier + mapView:self.mapView]; + [FLTPolygonsController interpretPolygonOptions:polygon + sink:controller + registrar:self.registrar]; + self.polygonIdentifierToController[identifier] = controller; } } + - (void)changePolygons:(NSArray *)polygonsToChange { for (NSDictionary *polygon in polygonsToChange) { - NSString *polygonId = [FLTPolygonsController getPolygonId:polygon]; - FLTGoogleMapPolygonController *controller = _polygonIdToController[polygonId]; + NSString *identifier = [FLTPolygonsController getPolygonId:polygon]; + FLTGoogleMapPolygonController *controller = self.polygonIdentifierToController[identifier]; if (!controller) { continue; } - InterpretPolygonOptions(polygon, controller, _registrar); + [FLTPolygonsController interpretPolygonOptions:polygon + sink:controller + registrar:self.registrar]; } } -- (void)removePolygonIds:(NSArray *)polygonIdsToRemove { - for (NSString *polygonId in polygonIdsToRemove) { - if (!polygonId) { - continue; - } - FLTGoogleMapPolygonController *controller = _polygonIdToController[polygonId]; + +- (void)removePolygonWithIdentifiers:(NSArray *)identifiers { + for (NSString *identifier in identifiers) { + FLTGoogleMapPolygonController *controller = self.polygonIdentifierToController[identifier]; if (!controller) { continue; } [controller removePolygon]; - [_polygonIdToController removeObjectForKey:polygonId]; + [self.polygonIdentifierToController removeObjectForKey:identifier]; } } -- (void)onPolygonTap:(NSString *)polygonId { - if (!polygonId) { + +- (void)didTapPolygonWithIdentifier:(NSString *)identifier { + if (!identifier) { return; } - FLTGoogleMapPolygonController *controller = _polygonIdToController[polygonId]; + FLTGoogleMapPolygonController *controller = self.polygonIdentifierToController[identifier]; if (!controller) { return; } - [_methodChannel invokeMethod:@"polygon#onTap" arguments:@{@"polygonId" : polygonId}]; + [self.methodChannel invokeMethod:@"polygon#onTap" arguments:@{@"polygonId" : identifier}]; } -- (bool)hasPolygonWithId:(NSString *)polygonId { - if (!polygonId) { + +- (bool)hasPolygonWithIdentifier:(NSString *)identifier { + if (!identifier) { return false; } - return _polygonIdToController[polygonId] != nil; + return self.polygonIdentifierToController[identifier] != nil; } + + (GMSMutablePath *)getPath:(NSDictionary *)polygon { NSArray *pointArray = polygon[@"points"]; - NSArray *points = ToPoints(pointArray); + NSArray *points = [FLTGoogleMapJSONConversions pointsFromLatlongs:pointArray]; GMSMutablePath *path = [GMSMutablePath path]; for (CLLocation *location in points) { [path addCoordinate:location.coordinate]; } return path; } + + (NSString *)getPolygonId:(NSDictionary *)polygon { return polygon[@"polygonId"]; } + ++ (void)interpretPolygonOptions:(NSDictionary *)data + sink:(id)sink + registrar:(NSObject *)registrar { + NSNumber *consumeTapEvents = data[@"consumeTapEvents"]; + if (consumeTapEvents && consumeTapEvents != (id)[NSNull null]) { + [sink setConsumeTapEvents:[consumeTapEvents boolValue]]; + } + + NSNumber *visible = data[@"visible"]; + if (visible && visible != (id)[NSNull null]) { + [sink setVisible:[visible boolValue]]; + } + + NSNumber *zIndex = data[@"zIndex"]; + if (zIndex && zIndex != (id)[NSNull null]) { + [sink setZIndex:[zIndex intValue]]; + } + + NSArray *points = data[@"points"]; + if (points && points != (id)[NSNull null]) { + [sink setPoints:[FLTGoogleMapJSONConversions pointsFromLatlongs:points]]; + } + + NSArray *holes = data[@"holes"]; + if (holes && holes != (id)[NSNull null]) { + [sink setHoles:[FLTGoogleMapJSONConversions holesFromPointsArray:holes]]; + } + + NSNumber *fillColor = data[@"fillColor"]; + if (fillColor && fillColor != (id)[NSNull null]) { + [sink setFillColor:[FLTGoogleMapJSONConversions colorFromRGBA:fillColor]]; + } + + NSNumber *strokeColor = data[@"strokeColor"]; + if (strokeColor && strokeColor != (id)[NSNull null]) { + [sink setStrokeColor:[FLTGoogleMapJSONConversions colorFromRGBA:strokeColor]]; + } + + NSNumber *strokeWidth = data[@"strokeWidth"]; + if (strokeWidth && strokeWidth != (id)[NSNull null]) { + [sink setStrokeWidth:[strokeWidth intValue]]; + } +} @end diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.h index 0e614eeb62ab..1d255ad844a3 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.h @@ -18,9 +18,8 @@ // Defines polyline controllable by Flutter. @interface FLTGoogleMapPolylineController : NSObject -@property(atomic, readonly) NSString *polylineId; - (instancetype)initPolylineWithPath:(GMSMutablePath *)path - polylineId:(NSString *)polylineId + identifier:(NSString *)identifier mapView:(GMSMapView *)mapView; - (void)removePolyline; @end @@ -31,7 +30,7 @@ registrar:(NSObject *)registrar; - (void)addPolylines:(NSArray *)polylinesToAdd; - (void)changePolylines:(NSArray *)polylinesToChange; -- (void)removePolylineIds:(NSArray *)polylineIdsToRemove; -- (void)onPolylineTap:(NSString *)polylineId; -- (bool)hasPolylineWithId:(NSString *)polylineId; +- (void)removePolylineWithIdentifiers:(NSArray *)identifiers; +- (void)didTapPolylineWithIdentifier:(NSString *)identifier; +- (bool)hasPolylineWithIdentifier:(NSString *)identifier; @end diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m index f366051b4af2..07ea6391bd23 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m @@ -5,37 +5,41 @@ #import "GoogleMapPolylineController.h" #import "JsonConversions.h" -@implementation FLTGoogleMapPolylineController { - GMSPolyline *_polyline; - GMSMapView *_mapView; -} +@interface FLTGoogleMapPolylineController () + +@property(strong, nonatomic) GMSPolyline *polyline; +@property(weak, nonatomic) GMSMapView *mapView; + +@end + +@implementation FLTGoogleMapPolylineController + - (instancetype)initPolylineWithPath:(GMSMutablePath *)path - polylineId:(NSString *)polylineId + identifier:(NSString *)identifier mapView:(GMSMapView *)mapView { self = [super init]; if (self) { _polyline = [GMSPolyline polylineWithPath:path]; _mapView = mapView; - _polylineId = polylineId; - _polyline.userData = @[ polylineId ]; + _polyline.userData = @[ identifier ]; } return self; } - (void)removePolyline { - _polyline.map = nil; + self.polyline.map = nil; } #pragma mark - FLTGoogleMapPolylineOptionsSink methods - (void)setConsumeTapEvents:(BOOL)consumes { - _polyline.tappable = consumes; + self.polyline.tappable = consumes; } - (void)setVisible:(BOOL)visible { - _polyline.map = visible ? _mapView : nil; + self.polyline.map = visible ? self.mapView : nil; } - (void)setZIndex:(int)zIndex { - _polyline.zIndex = zIndex; + self.polyline.zIndex = zIndex; } - (void)setPoints:(NSArray *)points { GMSMutablePath *path = [GMSMutablePath path]; @@ -43,75 +47,33 @@ - (void)setPoints:(NSArray *)points { for (CLLocation *location in points) { [path addCoordinate:location.coordinate]; } - _polyline.path = path; + self.polyline.path = path; } - (void)setColor:(UIColor *)color { - _polyline.strokeColor = color; + self.polyline.strokeColor = color; } - (void)setStrokeWidth:(CGFloat)width { - _polyline.strokeWidth = width; + self.polyline.strokeWidth = width; } - (void)setGeodesic:(BOOL)isGeodesic { - _polyline.geodesic = isGeodesic; + self.polyline.geodesic = isGeodesic; } @end -static int ToInt(NSNumber *data) { return [FLTGoogleMapJsonConversions toInt:data]; } +@interface FLTPolylinesController () -static BOOL ToBool(NSNumber *data) { return [FLTGoogleMapJsonConversions toBool:data]; } - -static NSArray *ToPoints(NSArray *data) { - return [FLTGoogleMapJsonConversions toPoints:data]; -} - -static UIColor *ToColor(NSNumber *data) { return [FLTGoogleMapJsonConversions toColor:data]; } - -static void InterpretPolylineOptions(NSDictionary *data, id sink, - NSObject *registrar) { - NSNumber *consumeTapEvents = data[@"consumeTapEvents"]; - if (consumeTapEvents != nil) { - [sink setConsumeTapEvents:ToBool(consumeTapEvents)]; - } - - NSNumber *visible = data[@"visible"]; - if (visible != nil) { - [sink setVisible:ToBool(visible)]; - } +@property(strong, nonatomic) NSMutableDictionary *polylineIdentifierToController; +@property(weak, nonatomic) FlutterMethodChannel *methodChannel; +@property(weak, nonatomic) NSObject *registrar; +@property(weak, nonatomic) GMSMapView *mapView; - NSNumber *zIndex = data[@"zIndex"]; - if (zIndex != nil) { - [sink setZIndex:ToInt(zIndex)]; - } - - NSArray *points = data[@"points"]; - if (points) { - [sink setPoints:ToPoints(points)]; - } - - NSNumber *strokeColor = data[@"color"]; - if (strokeColor != nil) { - [sink setColor:ToColor(strokeColor)]; - } - - NSNumber *strokeWidth = data[@"width"]; - if (strokeWidth != nil) { - [sink setStrokeWidth:ToInt(strokeWidth)]; - } +@end +; - NSNumber *geodesic = data[@"geodesic"]; - if (geodesic != nil) { - [sink setGeodesic:geodesic.boolValue]; - } -} +@implementation FLTPolylinesController -@implementation FLTPolylinesController { - NSMutableDictionary *_polylineIdToController; - FlutterMethodChannel *_methodChannel; - NSObject *_registrar; - GMSMapView *_mapView; -} - (instancetype)init:(FlutterMethodChannel *)methodChannel mapView:(GMSMapView *)mapView registrar:(NSObject *)registrar { @@ -119,7 +81,7 @@ - (instancetype)init:(FlutterMethodChannel *)methodChannel if (self) { _methodChannel = methodChannel; _mapView = mapView; - _polylineIdToController = [NSMutableDictionary dictionaryWithCapacity:1]; + _polylineIdentifierToController = [NSMutableDictionary dictionaryWithCapacity:1]; _registrar = registrar; } return self; @@ -127,64 +89,105 @@ - (instancetype)init:(FlutterMethodChannel *)methodChannel - (void)addPolylines:(NSArray *)polylinesToAdd { for (NSDictionary *polyline in polylinesToAdd) { GMSMutablePath *path = [FLTPolylinesController getPath:polyline]; - NSString *polylineId = [FLTPolylinesController getPolylineId:polyline]; + NSString *identifier = [FLTPolylinesController getPolylineIdentifier:polyline]; FLTGoogleMapPolylineController *controller = [[FLTGoogleMapPolylineController alloc] initPolylineWithPath:path - polylineId:polylineId - mapView:_mapView]; - InterpretPolylineOptions(polyline, controller, _registrar); - _polylineIdToController[polylineId] = controller; + identifier:identifier + mapView:self.mapView]; + [FLTPolylinesController interpretPolylineOptions:polyline + sink:controller + registrar:self.registrar]; + self.polylineIdentifierToController[identifier] = controller; } } - (void)changePolylines:(NSArray *)polylinesToChange { for (NSDictionary *polyline in polylinesToChange) { - NSString *polylineId = [FLTPolylinesController getPolylineId:polyline]; - FLTGoogleMapPolylineController *controller = _polylineIdToController[polylineId]; + NSString *identifier = [FLTPolylinesController getPolylineIdentifier:polyline]; + FLTGoogleMapPolylineController *controller = self.polylineIdentifierToController[identifier]; if (!controller) { continue; } - InterpretPolylineOptions(polyline, controller, _registrar); + [FLTPolylinesController interpretPolylineOptions:polyline + sink:controller + registrar:self.registrar]; } } -- (void)removePolylineIds:(NSArray *)polylineIdsToRemove { - for (NSString *polylineId in polylineIdsToRemove) { - if (!polylineId) { - continue; - } - FLTGoogleMapPolylineController *controller = _polylineIdToController[polylineId]; +- (void)removePolylineWithIdentifiers:(NSArray *)identifiers { + for (NSString *identifier in identifiers) { + FLTGoogleMapPolylineController *controller = self.polylineIdentifierToController[identifier]; if (!controller) { continue; } [controller removePolyline]; - [_polylineIdToController removeObjectForKey:polylineId]; + [self.polylineIdentifierToController removeObjectForKey:identifier]; } } -- (void)onPolylineTap:(NSString *)polylineId { - if (!polylineId) { +- (void)didTapPolylineWithIdentifier:(NSString *)identifier { + if (!identifier) { return; } - FLTGoogleMapPolylineController *controller = _polylineIdToController[polylineId]; + FLTGoogleMapPolylineController *controller = self.polylineIdentifierToController[identifier]; if (!controller) { return; } - [_methodChannel invokeMethod:@"polyline#onTap" arguments:@{@"polylineId" : polylineId}]; + [self.methodChannel invokeMethod:@"polyline#onTap" arguments:@{@"polylineId" : identifier}]; } -- (bool)hasPolylineWithId:(NSString *)polylineId { - if (!polylineId) { +- (bool)hasPolylineWithIdentifier:(NSString *)identifier { + if (!identifier) { return false; } - return _polylineIdToController[polylineId] != nil; + return self.polylineIdentifierToController[identifier] != nil; } + (GMSMutablePath *)getPath:(NSDictionary *)polyline { NSArray *pointArray = polyline[@"points"]; - NSArray *points = ToPoints(pointArray); + NSArray *points = [FLTGoogleMapJSONConversions pointsFromLatlongs:pointArray]; GMSMutablePath *path = [GMSMutablePath path]; for (CLLocation *location in points) { [path addCoordinate:location.coordinate]; } return path; } -+ (NSString *)getPolylineId:(NSDictionary *)polyline { ++ (NSString *)getPolylineIdentifier:(NSDictionary *)polyline { return polyline[@"polylineId"]; } + ++ (void)interpretPolylineOptions:(NSDictionary *)data + sink:(id)sink + registrar:(NSObject *)registrar { + NSNumber *consumeTapEvents = data[@"consumeTapEvents"]; + if (consumeTapEvents && consumeTapEvents != (id)[NSNull null]) { + [sink setConsumeTapEvents:[consumeTapEvents boolValue]]; + } + + NSNumber *visible = data[@"visible"]; + if (visible && visible != (id)[NSNull null]) { + [sink setVisible:[visible boolValue]]; + } + + NSNumber *zIndex = data[@"zIndex"]; + if (zIndex && zIndex != (id)[NSNull null]) { + [sink setZIndex:[zIndex intValue]]; + } + + NSArray *points = data[@"points"]; + if (points && points != (id)[NSNull null]) { + [sink setPoints:[FLTGoogleMapJSONConversions pointsFromLatlongs:points]]; + } + + NSNumber *strokeColor = data[@"color"]; + if (strokeColor && strokeColor != (id)[NSNull null]) { + [sink setColor:[FLTGoogleMapJSONConversions colorFromRGBA:strokeColor]]; + } + + NSNumber *strokeWidth = data[@"width"]; + if (strokeWidth && strokeWidth != (id)[NSNull null]) { + [sink setStrokeWidth:[strokeWidth intValue]]; + } + + NSNumber *geodesic = data[@"geodesic"]; + if (geodesic && geodesic != (id)[NSNull null]) { + [sink setGeodesic:geodesic.boolValue]; + } +} + @end diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.h index c0f673ecd025..f971d18b0429 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.h @@ -5,15 +5,26 @@ #import #import -@interface FLTGoogleMapJsonConversions : NSObject -+ (bool)toBool:(NSNumber *)data; -+ (int)toInt:(NSNumber *)data; -+ (double)toDouble:(NSNumber *)data; -+ (float)toFloat:(NSNumber *)data; -+ (CLLocationCoordinate2D)toLocation:(NSArray *)data; -+ (CGPoint)toPoint:(NSArray *)data; -+ (NSArray *)positionToJson:(CLLocationCoordinate2D)position; -+ (UIColor *)toColor:(NSNumber *)data; -+ (NSArray *)toPoints:(NSArray *)data; -+ (NSArray *> *)toHoles:(NSArray *)data; +NS_ASSUME_NONNULL_BEGIN + +@interface FLTGoogleMapJSONConversions : NSObject + ++ (CLLocationCoordinate2D)locationFromLatlong:(NSArray *)latlong; ++ (CGPoint)pointFromArray:(NSArray *)array; ++ (NSArray *)arrayFromLocation:(CLLocationCoordinate2D)location; ++ (UIColor *)colorFromRGBA:(NSNumber *)data; ++ (NSArray *)pointsFromLatlongs:(NSArray *)data; ++ (NSArray *> *)holesFromPointsArray:(NSArray *)data; ++ (nullable NSDictionary *)dictionaryFromPosition: + (nullable GMSCameraPosition *)position; ++ (NSDictionary *)dictionaryFromPoint:(CGPoint)point; ++ (nullable NSDictionary *)dictionaryFromCoordinateBounds:(nullable GMSCoordinateBounds *)bounds; ++ (nullable GMSCameraPosition *)cameraPostionFromDictionary:(nullable NSDictionary *)channelValue; ++ (CGPoint)pointFromDictionary:(NSDictionary *)dictionary; ++ (GMSCoordinateBounds *)coordinateBoundsFromLatlongs:(NSArray *)latlongs; ++ (GMSMapViewType)mapViewTypeFromTypeValue:(NSNumber *)value; ++ (nullable GMSCameraUpdate *)cameraUpdateFromChannelValue:(NSArray *)channelValue; + @end + +NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.m index 0e88d4707489..7cfdfe9af007 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.m @@ -4,39 +4,21 @@ #import "JsonConversions.h" -@implementation FLTGoogleMapJsonConversions +@implementation FLTGoogleMapJSONConversions -+ (bool)toBool:(NSNumber *)data { - return data.boolValue; ++ (CLLocationCoordinate2D)locationFromLatlong:(NSArray *)latlong { + return CLLocationCoordinate2DMake([latlong[0] doubleValue], [latlong[1] doubleValue]); } -+ (int)toInt:(NSNumber *)data { - return data.intValue; ++ (CGPoint)pointFromArray:(NSArray *)array { + return CGPointMake([array[0] doubleValue], [array[1] doubleValue]); } -+ (double)toDouble:(NSNumber *)data { - return data.doubleValue; ++ (NSArray *)arrayFromLocation:(CLLocationCoordinate2D)location { + return @[ @(location.latitude), @(location.longitude) ]; } -+ (float)toFloat:(NSNumber *)data { - return data.floatValue; -} - -+ (CLLocationCoordinate2D)toLocation:(NSArray *)data { - return CLLocationCoordinate2DMake([FLTGoogleMapJsonConversions toDouble:data[0]], - [FLTGoogleMapJsonConversions toDouble:data[1]]); -} - -+ (CGPoint)toPoint:(NSArray *)data { - return CGPointMake([FLTGoogleMapJsonConversions toDouble:data[0]], - [FLTGoogleMapJsonConversions toDouble:data[1]]); -} - -+ (NSArray *)positionToJson:(CLLocationCoordinate2D)position { - return @[ @(position.latitude), @(position.longitude) ]; -} - -+ (UIColor *)toColor:(NSNumber *)numberColor { ++ (UIColor *)colorFromRGBA:(NSNumber *)numberColor { unsigned long value = [numberColor unsignedLongValue]; return [UIColor colorWithRed:((float)((value & 0xFF0000) >> 16)) / 255.0 green:((float)((value & 0xFF00) >> 8)) / 255.0 @@ -44,28 +26,119 @@ + (UIColor *)toColor:(NSNumber *)numberColor { alpha:((float)((value & 0xFF000000) >> 24)) / 255.0]; } -+ (NSArray *)toPoints:(NSArray *)data { ++ (NSArray *)pointsFromLatlongs:(NSArray *)data { NSMutableArray *points = [[NSMutableArray alloc] init]; for (unsigned i = 0; i < [data count]; i++) { NSNumber *latitude = data[i][0]; NSNumber *longitude = data[i][1]; - CLLocation *point = - [[CLLocation alloc] initWithLatitude:[FLTGoogleMapJsonConversions toDouble:latitude] - longitude:[FLTGoogleMapJsonConversions toDouble:longitude]]; + CLLocation *point = [[CLLocation alloc] initWithLatitude:[latitude doubleValue] + longitude:[longitude doubleValue]]; [points addObject:point]; } return points; } -+ (NSArray *> *)toHoles:(NSArray *)data { ++ (NSArray *> *)holesFromPointsArray:(NSArray *)data { NSMutableArray *> *holes = [[[NSMutableArray alloc] init] init]; for (unsigned i = 0; i < [data count]; i++) { - NSArray *points = [FLTGoogleMapJsonConversions toPoints:data[i]]; + NSArray *points = [FLTGoogleMapJSONConversions pointsFromLatlongs:data[i]]; [holes addObject:points]; } return holes; } ++ (nullable NSDictionary *)dictionaryFromPosition:(GMSCameraPosition *)position { + if (!position) { + return nil; + } + return @{ + @"target" : [FLTGoogleMapJSONConversions arrayFromLocation:[position target]], + @"zoom" : @([position zoom]), + @"bearing" : @([position bearing]), + @"tilt" : @([position viewingAngle]), + }; +} + ++ (NSDictionary *)dictionaryFromPoint:(CGPoint)point { + return @{ + @"x" : @(lroundf(point.x)), + @"y" : @(lroundf(point.y)), + }; +} + ++ (nullable NSDictionary *)dictionaryFromCoordinateBounds:(GMSCoordinateBounds *)bounds { + if (!bounds) { + return nil; + } + return @{ + @"southwest" : [FLTGoogleMapJSONConversions arrayFromLocation:[bounds southWest]], + @"northeast" : [FLTGoogleMapJSONConversions arrayFromLocation:[bounds northEast]], + }; +} + ++ (nullable GMSCameraPosition *)cameraPostionFromDictionary:(nullable NSDictionary *)data { + if (!data) { + return nil; + } + return [GMSCameraPosition + cameraWithTarget:[FLTGoogleMapJSONConversions locationFromLatlong:data[@"target"]] + zoom:[data[@"zoom"] floatValue] + bearing:[data[@"bearing"] doubleValue] + viewingAngle:[data[@"tilt"] doubleValue]]; +} + ++ (CGPoint)pointFromDictionary:(NSDictionary *)dictionary { + double x = [dictionary[@"x"] doubleValue]; + double y = [dictionary[@"y"] doubleValue]; + return CGPointMake(x, y); +} + ++ (GMSCoordinateBounds *)coordinateBoundsFromLatlongs:(NSArray *)latlongs { + return [[GMSCoordinateBounds alloc] + initWithCoordinate:[FLTGoogleMapJSONConversions locationFromLatlong:latlongs[0]] + coordinate:[FLTGoogleMapJSONConversions locationFromLatlong:latlongs[1]]]; +} + ++ (GMSMapViewType)mapViewTypeFromTypeValue:(NSNumber *)typeValue { + int value = [typeValue intValue]; + return (GMSMapViewType)(value == 0 ? 5 : value); +} + ++ (nullable GMSCameraUpdate *)cameraUpdateFromChannelValue:(NSArray *)channelValue { + NSString *update = channelValue[0]; + if ([update isEqualToString:@"newCameraPosition"]) { + return [GMSCameraUpdate + setCamera:[FLTGoogleMapJSONConversions cameraPostionFromDictionary:channelValue[1]]]; + } else if ([update isEqualToString:@"newLatLng"]) { + return [GMSCameraUpdate + setTarget:[FLTGoogleMapJSONConversions locationFromLatlong:channelValue[1]]]; + } else if ([update isEqualToString:@"newLatLngBounds"]) { + return [GMSCameraUpdate + fitBounds:[FLTGoogleMapJSONConversions coordinateBoundsFromLatlongs:channelValue[1]] + withPadding:[channelValue[2] doubleValue]]; + } else if ([update isEqualToString:@"newLatLngZoom"]) { + return + [GMSCameraUpdate setTarget:[FLTGoogleMapJSONConversions locationFromLatlong:channelValue[1]] + zoom:[channelValue[2] floatValue]]; + } else if ([update isEqualToString:@"scrollBy"]) { + return [GMSCameraUpdate scrollByX:[channelValue[1] doubleValue] + Y:[channelValue[2] doubleValue]]; + } else if ([update isEqualToString:@"zoomBy"]) { + if (channelValue.count == 2) { + return [GMSCameraUpdate zoomBy:[channelValue[1] floatValue]]; + } else { + return [GMSCameraUpdate zoomBy:[channelValue[1] floatValue] + atPoint:[FLTGoogleMapJSONConversions pointFromArray:channelValue[2]]]; + } + } else if ([update isEqualToString:@"zoomIn"]) { + return [GMSCameraUpdate zoomIn]; + } else if ([update isEqualToString:@"zoomOut"]) { + return [GMSCameraUpdate zoomOut]; + } else if ([update isEqualToString:@"zoomTo"]) { + return [GMSCameraUpdate zoomTo:[channelValue[1] floatValue]]; + } + return nil; +} @end From fcd3c69b8047d248e8ae5e448a5b0ce3ac23ab94 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 24 May 2022 16:01:25 -0700 Subject: [PATCH 2/7] update version --- .../google_maps_flutter/google_maps_flutter/CHANGELOG.md | 5 ++++- .../google_maps_flutter/google_maps_flutter/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md index 62cc7a25b3af..8d78ec38b057 100644 --- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md @@ -1,9 +1,12 @@ +## 2.1.7 + +* Objective-C code cleanup. + ## 2.1.6 * Fixes issue in Flutter v3.0.0 where some updates to the map don't take effect on Android. * Fixes iOS native unit tests on M1 devices. * Minor fixes for new analysis options. -* Objective-C code cleanup. ## 2.1.5 diff --git a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml index 59ee23d0b260..215a930c91b9 100644 --- a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml @@ -2,7 +2,7 @@ name: google_maps_flutter description: A Flutter plugin for integrating Google Maps in iOS and Android applications. repository: https://github.com/flutter/plugins/tree/main/packages/google_maps_flutter/google_maps_flutter issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 -version: 2.1.6 +version: 2.1.7 environment: sdk: ">=2.14.0 <3.0.0" From 367466ba1fb55d19dbf90cd1669dd0b877ac8d38 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 24 May 2022 16:37:14 -0700 Subject: [PATCH 3/7] fix crashes --- .../ios/Classes/GoogleMapMarkerController.h | 2 +- .../ios/Classes/GoogleMapMarkerController.m | 10 +--------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.h index b1adf18ff94f..3447509dafe7 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.h @@ -26,13 +26,13 @@ NS_ASSUME_NONNULL_BEGIN // Defines marker controllable by Flutter. @interface FLTGoogleMapMarkerController : NSObject +@property(assign, nonatomic, readonly) BOOL consumeTapEvents; - (instancetype)initMarkerWithPosition:(CLLocationCoordinate2D)position identifier:(NSString *)identifier mapView:(GMSMapView *)mapView; - (void)showInfoWindow; - (void)hideInfoWindow; - (BOOL)isInfoWindowShown; -- (BOOL)consumeTapEvents; - (void)removeMarker; @end diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m index fe1a166390a1..71ac17897618 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m @@ -9,7 +9,7 @@ @interface FLTGoogleMapMarkerController () @property(strong, nonatomic) GMSMarker *marker; @property(weak, nonatomic) GMSMapView *mapView; -@property(assign, nonatomic) BOOL consumeTapEvents; +@property(assign, nonatomic, readwrite) BOOL consumeTapEvents; @end @@ -41,10 +41,6 @@ - (BOOL)isInfoWindowShown { return self.mapView.selectedMarker == self.marker; } -- (BOOL)consumeTapEvents { - return self.consumeTapEvents; -} - - (void)removeMarker { self.marker.map = nil; } @@ -59,10 +55,6 @@ - (void)setAnchor:(CGPoint)anchor { self.marker.groundAnchor = anchor; } -- (void)setConsumeTapEvents:(BOOL)consumes { - self.consumeTapEvents = consumes; -} - - (void)setDraggable:(BOOL)draggable { self.marker.draggable = draggable; } From fb856e68212d9fe4cbf3f99ebb359b7116714c11 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Wed, 25 May 2022 13:29:18 -0700 Subject: [PATCH 4/7] review --- ...TGoogleMapJSONConversionsConversionTests.m | 17 +- .../FLTGoogleMapTileOverlayController.h | 17 +- .../FLTGoogleMapTileOverlayController.m | 75 ++--- .../ios/Classes/GoogleMapCircleController.h | 17 +- .../ios/Classes/GoogleMapCircleController.m | 97 +++---- .../ios/Classes/GoogleMapController.h | 23 +- .../ios/Classes/GoogleMapController.m | 38 ++- .../ios/Classes/GoogleMapMarkerController.h | 18 +- .../ios/Classes/GoogleMapMarkerController.m | 265 +++++++++--------- .../ios/Classes/GoogleMapPolygonController.h | 14 +- .../ios/Classes/GoogleMapPolygonController.m | 105 ++++--- .../ios/Classes/GoogleMapPolylineController.h | 13 +- .../ios/Classes/GoogleMapPolylineController.m | 95 +++---- 13 files changed, 348 insertions(+), 446 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/example/ios/RunnerTests/FLTGoogleMapJSONConversionsConversionTests.m b/packages/google_maps_flutter/google_maps_flutter/example/ios/RunnerTests/FLTGoogleMapJSONConversionsConversionTests.m index 5e31c5928c48..279d3a51365f 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/ios/RunnerTests/FLTGoogleMapJSONConversionsConversionTests.m +++ b/packages/google_maps_flutter/google_maps_flutter/example/ios/RunnerTests/FLTGoogleMapJSONConversionsConversionTests.m @@ -17,14 +17,14 @@ @interface FLTGoogleMapJSONConversionsTests : XCTestCase @implementation FLTGoogleMapJSONConversionsTests - (void)testLocationFromLatlong { - NSArray *latlong = @[ @(1), @(2) ]; + NSArray *latlong = @[ @1, @2 ]; CLLocationCoordinate2D location = [FLTGoogleMapJSONConversions locationFromLatlong:latlong]; XCTAssertEqual(location.latitude, 1); XCTAssertEqual(location.longitude, 2); } - (void)testPointFromArray { - NSArray *array = @[ @(1), @(2) ]; + NSArray *array = @[ @1, @2 ]; CGPoint point = [FLTGoogleMapJSONConversions pointFromArray:array]; XCTAssertEqual(point.x, 1); XCTAssertEqual(point.y, 2); @@ -51,7 +51,7 @@ - (void)testColorFromRGBA { } - (void)testPointsFromLatlongs { - NSArray *latlongs = @[ @[ @(1), @(2) ], @[ @(3), @(4) ] ]; + NSArray *latlongs = @[ @[ @1, @2 ], @[ @(3), @(4) ] ]; NSArray *locations = [FLTGoogleMapJSONConversions pointsFromLatlongs:latlongs]; XCTAssertEqual(locations.count, 2); XCTAssertEqual(locations[0].coordinate.latitude, 1); @@ -62,7 +62,7 @@ - (void)testPointsFromLatlongs { - (void)testHolesFromPointsArray { NSArray *pointsArray = - @[ @[ @[ @(1), @(2) ], @[ @(3), @(4) ] ], @[ @[ @(5), @(6) ], @[ @(7), @(8) ] ] ]; + @[ @[ @[ @1, @2 ], @[ @(3), @(4) ] ], @[ @[ @(5), @(6) ], @[ @(7), @(8) ] ] ]; NSArray *> *holes = [FLTGoogleMapJSONConversions holesFromPointsArray:pointsArray]; XCTAssertEqual(holes.count, 2); @@ -116,7 +116,7 @@ - (void)testCameraPostionFromDictionary { XCTAssertNil([FLTGoogleMapJSONConversions cameraPostionFromDictionary:nil]); NSDictionary *channelValue = - @{@"target" : @[ @(1), @(2) ], @"zoom" : @3, @"bearing" : @4, @"tilt" : @5}; + @{@"target" : @[ @1, @2 ], @"zoom" : @3, @"bearing" : @4, @"tilt" : @5}; GMSCameraPosition *cameraPosition = [FLTGoogleMapJSONConversions cameraPostionFromDictionary:channelValue]; @@ -145,7 +145,7 @@ - (void)testPointFromDictionary { } - (void)testCoordinateBoundsFromLatlongs { - NSArray *latlong1 = @[ @(1), @(2) ]; + NSArray *latlong1 = @[ @1, @2 ]; NSArray *latlong2 = @[ @(3), @(4) ]; GMSCoordinateBounds *bounds = @@ -168,8 +168,7 @@ - (void)testMapViewTypeFromTypeValue { - (void)testCameraUpdateFromChannelValueNewCameraPosition { NSArray *channelValue = @[ - @"newCameraPosition", - @{@"target" : @[ @(1), @(2) ], @"zoom" : @3, @"bearing" : @4, @"tilt" : @5} + @"newCameraPosition", @{@"target" : @[ @1, @2 ], @"zoom" : @3, @"bearing" : @4, @"tilt" : @5} ]; id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); [FLTGoogleMapJSONConversions cameraUpdateFromChannelValue:channelValue]; @@ -209,7 +208,7 @@ - (void)skip_testCameraUpdateFromChannelValueNewLatlong { } - (void)testCameraUpdateFromChannelValueNewLatLngBounds { - NSArray *latlong1 = @[ @(1), @(2) ]; + NSArray *latlong1 = @[ @1, @2 ]; NSArray *latlong2 = @[ @(3), @(4) ]; GMSCoordinateBounds *bounds = [FLTGoogleMapJSONConversions coordinateBoundsFromLatlongs:@[ latlong1, latlong2 ]]; diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.h index c29b2d2cdb91..5dcc66594f18 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.h @@ -7,17 +7,10 @@ NS_ASSUME_NONNULL_BEGIN -// Defines map UI options writable from Flutter. -@protocol FLTGoogleMapTileOverlayOptionsSink -- (void)setFadeIn:(BOOL)fadeIn; -- (void)setTransparency:(float)transparency; -- (void)setZIndex:(int)zIndex; -- (void)setVisible:(BOOL)visible; -- (void)setTileSize:(NSInteger)tileSize; -@end - -@interface FLTGoogleMapTileOverlayController : NSObject -- (instancetype)initWithTileLayer:(GMSTileLayer *)tileLayer mapView:(GMSMapView *)mapView; +@interface FLTGoogleMapTileOverlayController : NSObject +- (instancetype)initWithTileLayer:(GMSTileLayer *)tileLayer + mapView:(GMSMapView *)mapView + options:(NSDictionary *)optionsData; - (void)removeTileOverlay; - (void)clearTileCache; - (NSDictionary *)getTileOverlayInfo; @@ -36,7 +29,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)addTileOverlays:(NSArray *)tileOverlaysToAdd; - (void)changeTileOverlays:(NSArray *)tileOverlaysToChange; - (void)removeTileOverlayWithIdentifiers:(NSArray *)identifiers; -- (void)clearTileCacheWithIdentifier:(NSString *)identifiers; +- (void)clearTileCacheWithIdentifier:(NSString *)identifier; - (nullable NSDictionary *)tileOverlayInfoWithIdentifier:(NSString *)identifier; @end diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m index 71f3bbd22324..09a03be551c2 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m @@ -14,11 +14,14 @@ @interface FLTGoogleMapTileOverlayController () @implementation FLTGoogleMapTileOverlayController -- (instancetype)initWithTileLayer:(GMSTileLayer *)tileLayer mapView:(GMSMapView *)mapView { +- (instancetype)initWithTileLayer:(GMSTileLayer *)tileLayer + mapView:(GMSMapView *)mapView + options:(NSDictionary *)optionsData { self = [super init]; if (self) { _layer = tileLayer; _mapView = mapView; + [self interpretTileOverlayOptions:optionsData]; } return self; } @@ -42,8 +45,6 @@ - (NSDictionary *)getTileOverlayInfo { return info; } -#pragma mark - FLTGoogleMapTileOverlayOptionsSink methods - - (void)setFadeIn:(BOOL)fadeIn { self.layer.fadeIn = fadeIn; } @@ -64,6 +65,37 @@ - (void)setZIndex:(int)zIndex { - (void)setTileSize:(NSInteger)tileSize { self.layer.tileSize = tileSize; } + +- (void)interpretTileOverlayOptions:(NSDictionary *)data { + if (!data) { + return; + } + NSNumber *visible = data[@"visible"]; + if (visible != nil && visible != (id)[NSNull null]) { + [self setVisible:visible.boolValue]; + } + + NSNumber *transparency = data[@"transparency"]; + if (transparency != nil && transparency != (id)[NSNull null]) { + [self setTransparency:transparency.floatValue]; + } + + NSNumber *zIndex = data[@"zIndex"]; + if (zIndex != nil && zIndex != (id)[NSNull null]) { + [self setZIndex:zIndex.intValue]; + } + + NSNumber *fadeIn = data[@"fadeIn"]; + if (fadeIn != nil && fadeIn != (id)[NSNull null]) { + [self setFadeIn:fadeIn.boolValue]; + } + + NSNumber *tileSize = data[@"tileSize"]; + if (tileSize != nil && tileSize != (id)[NSNull null]) { + [self setTileSize:tileSize.integerValue]; + } +} + @end @interface FLTTileProviderController () @@ -90,11 +122,10 @@ - (void)requestTileForX:(NSUInteger)x y:(NSUInteger)y zoom:(NSUInteger)zoom receiver:(id)receiver { - __weak typeof(self) weakSelf = self; [self.methodChannel invokeMethod:@"tileOverlay#getTile" arguments:@{ - @"tileOverlayId" : weakSelf.tileOverlayIdentifier, + @"tileOverlayId" : self.tileOverlayIdentifier, @"x" : @(x), @"y" : @(y), @"zoom" : @(zoom) @@ -156,8 +187,8 @@ - (void)addTileOverlays:(NSArray *)tileOverlaysToAdd { withTileOverlayIdentifier:identifier]; FLTGoogleMapTileOverlayController *controller = [[FLTGoogleMapTileOverlayController alloc] initWithTileLayer:tileProvider - mapView:self.mapView]; - [FLTTileOverlaysController interpretTileOverlayOptions:tileOverlay sink:controller]; + mapView:self.mapView + options:tileOverlay]; self.tileOverlayIdentifierToController[identifier] = controller; } } @@ -170,7 +201,7 @@ - (void)changeTileOverlays:(NSArray *)tileOverlaysToChange { if (!controller) { continue; } - [FLTTileOverlaysController interpretTileOverlayOptions:tileOverlay sink:controller]; + [controller interpretTileOverlayOptions:tileOverlay]; } } - (void)removeTileOverlayWithIdentifiers:(NSArray *)identifiers { @@ -205,32 +236,4 @@ + (NSString *)identifierForTileOverlay:(NSDictionary *)tileOverlay { return tileOverlay[@"tileOverlayId"]; } -+ (void)interpretTileOverlayOptions:(NSDictionary *)data - sink:(id)sink { - NSNumber *visible = data[@"visible"]; - if (visible != nil && visible != (id)[NSNull null]) { - [sink setVisible:visible.boolValue]; - } - - NSNumber *transparency = data[@"transparency"]; - if (transparency != nil && transparency != (id)[NSNull null]) { - [sink setTransparency:transparency.floatValue]; - } - - NSNumber *zIndex = data[@"zIndex"]; - if (zIndex != nil && zIndex != (id)[NSNull null]) { - [sink setZIndex:zIndex.intValue]; - } - - NSNumber *fadeIn = data[@"fadeIn"]; - if (fadeIn != nil && fadeIn != (id)[NSNull null]) { - [sink setFadeIn:fadeIn.boolValue]; - } - - NSNumber *tileSize = data[@"tileSize"]; - if (tileSize != nil && tileSize != (id)[NSNull null]) { - [sink setTileSize:tileSize.integerValue]; - } -} - @end diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.h index 260932dbfb4b..6b67760fdaff 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.h @@ -5,24 +5,13 @@ #import #import -// Defines circle UI options writable from Flutter. -@protocol FLTGoogleMapCircleOptionsSink -- (void)setConsumeTapEvents:(BOOL)consume; -- (void)setVisible:(BOOL)visible; -- (void)setStrokeColor:(UIColor *)color; -- (void)setStrokeWidth:(CGFloat)width; -- (void)setFillColor:(UIColor *)color; -- (void)setCenter:(CLLocationCoordinate2D)center; -- (void)setRadius:(CLLocationDistance)radius; -- (void)setZIndex:(int)zIndex; -@end - // Defines circle controllable by Flutter. -@interface FLTGoogleMapCircleController : NSObject +@interface FLTGoogleMapCircleController : NSObject - (instancetype)initCircleWithPosition:(CLLocationCoordinate2D)position radius:(CLLocationDistance)radius circleId:(NSString *)circleIdentifier - mapView:(GMSMapView *)mapView; + mapView:(GMSMapView *)mapView + options:(NSDictionary *)options; - (void)removeCircle; @end diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m index bebd15f0cdfa..e278c40806e8 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m @@ -17,12 +17,14 @@ @implementation FLTGoogleMapCircleController - (instancetype)initCircleWithPosition:(CLLocationCoordinate2D)position radius:(CLLocationDistance)radius circleId:(NSString *)circleIdentifier - mapView:(GMSMapView *)mapView { + mapView:(GMSMapView *)mapView + options:(NSDictionary *)options { self = [super init]; if (self) { _circle = [GMSCircle circleWithPosition:position radius:radius]; _mapView = mapView; _circle.userData = @[ circleIdentifier ]; + [self interpretCircleOptions:options]; } return self; } @@ -31,8 +33,6 @@ - (void)removeCircle { self.circle.map = nil; } -#pragma mark - FLTGoogleMapCircleOptionsSink methods - - (void)setConsumeTapEvents:(BOOL)consumes { self.circle.tappable = consumes; } @@ -58,6 +58,49 @@ - (void)setStrokeWidth:(CGFloat)width { - (void)setFillColor:(UIColor *)color { self.circle.fillColor = color; } + +- (void)interpretCircleOptions:(NSDictionary *)data { + NSNumber *consumeTapEvents = data[@"consumeTapEvents"]; + if (consumeTapEvents && consumeTapEvents != (id)[NSNull null]) { + [self setConsumeTapEvents:consumeTapEvents.boolValue]; + } + + NSNumber *visible = data[@"visible"]; + if (visible && visible != (id)[NSNull null]) { + [self setVisible:[visible boolValue]]; + } + + NSNumber *zIndex = data[@"zIndex"]; + if (zIndex && zIndex != (id)[NSNull null]) { + [self setZIndex:[zIndex intValue]]; + } + + NSArray *center = data[@"center"]; + if (center && center != (id)[NSNull null]) { + [self setCenter:[FLTGoogleMapJSONConversions locationFromLatlong:center]]; + } + + NSNumber *radius = data[@"radius"]; + if (radius && radius != (id)[NSNull null]) { + [self setRadius:[radius floatValue]]; + } + + NSNumber *strokeColor = data[@"strokeColor"]; + if (strokeColor && strokeColor != (id)[NSNull null]) { + [self setStrokeColor:[FLTGoogleMapJSONConversions colorFromRGBA:strokeColor]]; + } + + NSNumber *strokeWidth = data[@"strokeWidth"]; + if (strokeWidth && strokeWidth != (id)[NSNull null]) { + [self setStrokeWidth:[strokeWidth intValue]]; + } + + NSNumber *fillColor = data[@"fillColor"]; + if (fillColor && fillColor != (id)[NSNull null]) { + [self setFillColor:[FLTGoogleMapJSONConversions colorFromRGBA:fillColor]]; + } +} + @end @interface FLTCirclesController () @@ -91,8 +134,8 @@ - (void)addCircles:(NSArray *)circlesToAdd { [[FLTGoogleMapCircleController alloc] initCircleWithPosition:position radius:radius circleId:circleId - mapView:self.mapView]; - [FLTCirclesController interpretCircleOptions:circle sink:controller]; + mapView:self.mapView + options:circle]; self.circleIdToController[circleId] = controller; } } @@ -104,7 +147,7 @@ - (void)changeCircles:(NSArray *)circlesToChange { if (!controller) { continue; } - [FLTCirclesController interpretCircleOptions:circle sink:controller]; + [controller interpretCircleOptions:circle]; } } @@ -151,46 +194,4 @@ + (NSString *)getCircleId:(NSDictionary *)circle { return circle[@"circleId"]; } -+ (void)interpretCircleOptions:(NSDictionary *)data sink:(id)sink { - NSNumber *consumeTapEvents = data[@"consumeTapEvents"]; - if (consumeTapEvents && consumeTapEvents != (id)[NSNull null]) { - [sink setConsumeTapEvents:consumeTapEvents.boolValue]; - } - - NSNumber *visible = data[@"visible"]; - if (visible && visible != (id)[NSNull null]) { - [sink setVisible:[visible boolValue]]; - } - - NSNumber *zIndex = data[@"zIndex"]; - if (zIndex && zIndex != (id)[NSNull null]) { - [sink setZIndex:[zIndex intValue]]; - } - - NSArray *center = data[@"center"]; - if (center && center != (id)[NSNull null]) { - [sink setCenter:[FLTGoogleMapJSONConversions locationFromLatlong:center]]; - } - - NSNumber *radius = data[@"radius"]; - if (radius && radius != (id)[NSNull null]) { - [sink setRadius:[radius floatValue]]; - } - - NSNumber *strokeColor = data[@"strokeColor"]; - if (strokeColor && strokeColor != (id)[NSNull null]) { - [sink setStrokeColor:[FLTGoogleMapJSONConversions colorFromRGBA:strokeColor]]; - } - - NSNumber *strokeWidth = data[@"strokeWidth"]; - if (strokeWidth && strokeWidth != (id)[NSNull null]) { - [sink setStrokeWidth:[strokeWidth intValue]]; - } - - NSNumber *fillColor = data[@"fillColor"]; - if (fillColor && fillColor != (id)[NSNull null]) { - [sink setFillColor:[FLTGoogleMapJSONConversions colorFromRGBA:fillColor]]; - } -} - @end diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.h index 81a607636772..d1069ac16b39 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.h @@ -11,29 +11,8 @@ NS_ASSUME_NONNULL_BEGIN -// Defines map UI options writable from Flutter. -@protocol FLTGoogleMapOptionsSink -- (void)setCameraTargetBounds:(nullable GMSCoordinateBounds *)bounds; -- (void)setCompassEnabled:(BOOL)enabled; -- (void)setIndoorEnabled:(BOOL)enabled; -- (void)setTrafficEnabled:(BOOL)enabled; -- (void)setBuildingsEnabled:(BOOL)enabled; -- (void)setMapType:(GMSMapViewType)type; -- (void)setMinZoom:(float)minZoom maxZoom:(float)maxZoom; -- (void)setPaddingTop:(float)top left:(float)left bottom:(float)bottom right:(float)right; -- (void)setRotateGesturesEnabled:(BOOL)enabled; -- (void)setScrollGesturesEnabled:(BOOL)enabled; -- (void)setTiltGesturesEnabled:(BOOL)enabled; -- (void)setTrackCameraPosition:(BOOL)enabled; -- (void)setZoomGesturesEnabled:(BOOL)enabled; -- (void)setMyLocationEnabled:(BOOL)enabled; -- (void)setMyLocationButtonEnabled:(BOOL)enabled; -- (nullable NSString *)setMapStyle:(NSString *)mapStyle; -@end - // Defines map overlay controllable from Flutter. -@interface FLTGoogleMapController - : NSObject +@interface FLTGoogleMapController : NSObject - (instancetype)initWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(nullable id)args diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m index 825cd5ac9a93..c11f1649d70d 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m @@ -74,7 +74,7 @@ - (instancetype)initWithMapView:(GMSMapView *_Nonnull)mapView _mapView.accessibilityElementsHidden = NO; // TODO(cyanglaz): avoid sending message to self in the middle of the init method. // https://github.com/flutter/flutter/issues/104121 - [FLTGoogleMapController interpretMapOptions:args[@"options"] sink:self]; + [self interpretMapOptions:args[@"options"]]; NSString *channelName = [NSString stringWithFormat:@"plugins.flutter.io/google_maps_%lld", viewId]; _channel = [FlutterMethodChannel methodChannelWithName:channelName @@ -171,7 +171,7 @@ - (void)onMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { cameraUpdateFromChannelValue:call.arguments[@"cameraUpdate"]]]; result(nil); } else if ([call.method isEqualToString:@"map#update"]) { - [FLTGoogleMapController interpretMapOptions:call.arguments[@"options"] sink:self]; + [self interpretMapOptions:call.arguments[@"options"]]; result([FLTGoogleMapJSONConversions dictionaryFromPosition:[self cameraPosition]]); } else if ([call.method isEqualToString:@"map#getVisibleRegion"]) { if (self.mapView != nil) { @@ -405,8 +405,6 @@ - (GMSCameraPosition *)cameraPosition { } } -#pragma mark - FLTGoogleMapOptionsSink methods - - (void)setCamera:(GMSCameraPosition *)camera { self.mapView.camera = camera; } @@ -552,10 +550,10 @@ - (void)mapView:(GMSMapView *)mapView didLongPressAtCoordinate:(CLLocationCoordi arguments:@{@"position" : [FLTGoogleMapJSONConversions arrayFromLocation:coordinate]}]; } -+ (void)interpretMapOptions:(NSDictionary *)data sink:(id)sink { +- (void)interpretMapOptions:(NSDictionary *)data { NSArray *cameraTargetBounds = data[@"cameraTargetBounds"]; if (cameraTargetBounds && cameraTargetBounds != (id)[NSNull null]) { - [sink + [self setCameraTargetBounds:cameraTargetBounds.count > 0 && cameraTargetBounds[0] != [NSNull null] ? [FLTGoogleMapJSONConversions coordinateBoundsFromLatlongs:cameraTargetBounds.firstObject] @@ -563,29 +561,29 @@ + (void)interpretMapOptions:(NSDictionary *)data sink:(id +@interface FLTGoogleMapMarkerController : NSObject @property(assign, nonatomic, readonly) BOOL consumeTapEvents; - (instancetype)initMarkerWithPosition:(CLLocationCoordinate2D)position identifier:(NSString *)identifier diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m index 71ac17897618..5572b95781c6 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m @@ -45,8 +45,6 @@ - (void)removeMarker { self.marker.map = nil; } -#pragma mark - FLTGoogleMapMarkerOptionsSink methods - - (void)setAlpha:(float)alpha { self.marker.opacity = alpha; } @@ -92,6 +90,135 @@ - (void)setZIndex:(int)zIndex { self.marker.zIndex = zIndex; } +- (void)interpretMarkerOptions:(NSDictionary *)data + registrar:(NSObject *)registrar { + NSNumber *alpha = data[@"alpha"]; + if (alpha && alpha != (id)[NSNull null]) { + [self setAlpha:[alpha floatValue]]; + } + NSArray *anchor = data[@"anchor"]; + if (anchor && anchor != (id)[NSNull null]) { + [self setAnchor:[FLTGoogleMapJSONConversions pointFromArray:anchor]]; + } + NSNumber *draggable = data[@"draggable"]; + if (draggable && draggable != (id)[NSNull null]) { + [self setDraggable:[draggable boolValue]]; + } + NSArray *icon = data[@"icon"]; + if (icon && icon != (id)[NSNull null]) { + UIImage *image = [self extractIconFromData:icon registrar:registrar]; + [self setIcon:image]; + } + NSNumber *flat = data[@"flat"]; + if (flat && flat != (id)[NSNull null]) { + [self setFlat:[flat boolValue]]; + } + NSNumber *consumeTapEvents = data[@"consumeTapEvents"]; + if (consumeTapEvents && consumeTapEvents != (id)[NSNull null]) { + [self setConsumeTapEvents:[consumeTapEvents boolValue]]; + } + [self interpretInfoWindow:data]; + NSArray *position = data[@"position"]; + if (position && position != (id)[NSNull null]) { + [self setPosition:[FLTGoogleMapJSONConversions locationFromLatlong:position]]; + } + NSNumber *rotation = data[@"rotation"]; + if (rotation && rotation != (id)[NSNull null]) { + [self setRotation:[rotation doubleValue]]; + } + NSNumber *visible = data[@"visible"]; + if (visible && visible != (id)[NSNull null]) { + [self setVisible:[visible boolValue]]; + } + NSNumber *zIndex = data[@"zIndex"]; + if (zIndex && zIndex != (id)[NSNull null]) { + [self setZIndex:[zIndex intValue]]; + } +} + +- (void)interpretInfoWindow:(NSDictionary *)data { + NSDictionary *infoWindow = data[@"infoWindow"]; + if (infoWindow && infoWindow != (id)[NSNull null]) { + NSString *title = infoWindow[@"title"]; + NSString *snippet = infoWindow[@"snippet"]; + if (title && title != (id)[NSNull null]) { + [self setInfoWindowTitle:title snippet:snippet]; + } + NSArray *infoWindowAnchor = infoWindow[@"infoWindowAnchor"]; + if (infoWindowAnchor && infoWindowAnchor != (id)[NSNull null]) { + [self setInfoWindowAnchor:[FLTGoogleMapJSONConversions pointFromArray:infoWindowAnchor]]; + } + } +} + +- (UIImage *)extractIconFromData:(NSArray *)iconData + registrar:(NSObject *)registrar { + UIImage *image; + if ([iconData.firstObject isEqualToString:@"defaultMarker"]) { + CGFloat hue = (iconData.count == 1) ? 0.0f : [iconData[1] doubleValue]; + image = [GMSMarker markerImageWithColor:[UIColor colorWithHue:hue / 360.0 + saturation:1.0 + brightness:0.7 + alpha:1.0]]; + } else if ([iconData.firstObject isEqualToString:@"fromAsset"]) { + if (iconData.count == 2) { + image = [UIImage imageNamed:[registrar lookupKeyForAsset:iconData[1]]]; + } else { + image = [UIImage imageNamed:[registrar lookupKeyForAsset:iconData[1] + fromPackage:iconData[2]]]; + } + } else if ([iconData.firstObject isEqualToString:@"fromAssetImage"]) { + if (iconData.count == 3) { + image = [UIImage imageNamed:[registrar lookupKeyForAsset:iconData[1]]]; + id scaleParam = iconData[2]; + image = [self scaleImage:image by:scaleParam]; + } else { + NSString *error = + [NSString stringWithFormat:@"'fromAssetImage' should have exactly 3 arguments. Got: %lu", + (unsigned long)iconData.count]; + NSException *exception = [NSException exceptionWithName:@"InvalidBitmapDescriptor" + reason:error + userInfo:nil]; + @throw exception; + } + } else if ([iconData[0] isEqualToString:@"fromBytes"]) { + if (iconData.count == 2) { + @try { + FlutterStandardTypedData *byteData = iconData[1]; + CGFloat screenScale = [[UIScreen mainScreen] scale]; + image = [UIImage imageWithData:[byteData data] scale:screenScale]; + } @catch (NSException *exception) { + @throw [NSException exceptionWithName:@"InvalidByteDescriptor" + reason:@"Unable to interpret bytes as a valid image." + userInfo:nil]; + } + } else { + NSString *error = [NSString + stringWithFormat:@"fromBytes should have exactly one argument, the bytes. Got: %lu", + (unsigned long)iconData.count]; + NSException *exception = [NSException exceptionWithName:@"InvalidByteDescriptor" + reason:error + userInfo:nil]; + @throw exception; + } + } + + return image; +} + +- (UIImage *)scaleImage:(UIImage *)image by:(id)scaleParam { + double scale = 1.0; + if ([scaleParam isKindOfClass:[NSNumber class]]) { + scale = [scaleParam doubleValue]; + } + if (fabs(scale - 1) > 1e-3) { + return [UIImage imageWithCGImage:[image CGImage] + scale:(image.scale * scale) + orientation:(image.imageOrientation)]; + } + return image; +} + @end @interface FLTMarkersController () @@ -126,7 +253,7 @@ - (void)addMarkers:(NSArray *)markersToAdd { [[FLTGoogleMapMarkerController alloc] initMarkerWithPosition:position identifier:identifier mapView:self.mapView]; - [FLTMarkersController interpretMarkerOptions:marker sink:controller registrar:self.registrar]; + [controller interpretMarkerOptions:marker registrar:self.registrar]; self.markerIdentifierToController[identifier] = controller; } } @@ -138,7 +265,7 @@ - (void)changeMarkers:(NSArray *)markersToChange { if (!controller) { continue; } - [FLTMarkersController interpretMarkerOptions:marker sink:controller registrar:self.registrar]; + [controller interpretMarkerOptions:marker registrar:self.registrar]; } } @@ -257,134 +384,4 @@ + (CLLocationCoordinate2D)getPosition:(NSDictionary *)marker { return [FLTGoogleMapJSONConversions locationFromLatlong:position]; } -+ (void)interpretMarkerOptions:(NSDictionary *)data - sink:(id)sink - registrar:(NSObject *)registrar { - NSNumber *alpha = data[@"alpha"]; - if (alpha && alpha != (id)[NSNull null]) { - [sink setAlpha:[alpha floatValue]]; - } - NSArray *anchor = data[@"anchor"]; - if (anchor && anchor != (id)[NSNull null]) { - [sink setAnchor:[FLTGoogleMapJSONConversions pointFromArray:anchor]]; - } - NSNumber *draggable = data[@"draggable"]; - if (draggable && draggable != (id)[NSNull null]) { - [sink setDraggable:[draggable boolValue]]; - } - NSArray *icon = data[@"icon"]; - if (icon && icon != (id)[NSNull null]) { - UIImage *image = [FLTMarkersController extractIconFromData:icon registrar:registrar]; - [sink setIcon:image]; - } - NSNumber *flat = data[@"flat"]; - if (flat && flat != (id)[NSNull null]) { - [sink setFlat:[flat boolValue]]; - } - NSNumber *consumeTapEvents = data[@"consumeTapEvents"]; - if (consumeTapEvents && consumeTapEvents != (id)[NSNull null]) { - [sink setConsumeTapEvents:[consumeTapEvents boolValue]]; - } - [FLTMarkersController interpretInfoWindow:data sink:sink]; - NSArray *position = data[@"position"]; - if (position && position != (id)[NSNull null]) { - [sink setPosition:[FLTGoogleMapJSONConversions locationFromLatlong:position]]; - } - NSNumber *rotation = data[@"rotation"]; - if (rotation && rotation != (id)[NSNull null]) { - [sink setRotation:[rotation doubleValue]]; - } - NSNumber *visible = data[@"visible"]; - if (visible && visible != (id)[NSNull null]) { - [sink setVisible:[visible boolValue]]; - } - NSNumber *zIndex = data[@"zIndex"]; - if (zIndex && zIndex != (id)[NSNull null]) { - [sink setZIndex:[zIndex intValue]]; - } -} - -+ (void)interpretInfoWindow:(NSDictionary *)data sink:(id)sink { - NSDictionary *infoWindow = data[@"infoWindow"]; - if (infoWindow && infoWindow != (id)[NSNull null]) { - NSString *title = infoWindow[@"title"]; - NSString *snippet = infoWindow[@"snippet"]; - if (title && title != (id)[NSNull null]) { - [sink setInfoWindowTitle:title snippet:snippet]; - } - NSArray *infoWindowAnchor = infoWindow[@"infoWindowAnchor"]; - if (infoWindowAnchor && infoWindowAnchor != (id)[NSNull null]) { - [sink setInfoWindowAnchor:[FLTGoogleMapJSONConversions pointFromArray:infoWindowAnchor]]; - } - } -} - -+ (UIImage *)extractIconFromData:(NSArray *)iconData - registrar:(NSObject *)registrar { - UIImage *image; - if ([iconData.firstObject isEqualToString:@"defaultMarker"]) { - CGFloat hue = (iconData.count == 1) ? 0.0f : [iconData[1] doubleValue]; - image = [GMSMarker markerImageWithColor:[UIColor colorWithHue:hue / 360.0 - saturation:1.0 - brightness:0.7 - alpha:1.0]]; - } else if ([iconData.firstObject isEqualToString:@"fromAsset"]) { - if (iconData.count == 2) { - image = [UIImage imageNamed:[registrar lookupKeyForAsset:iconData[1]]]; - } else { - image = [UIImage imageNamed:[registrar lookupKeyForAsset:iconData[1] - fromPackage:iconData[2]]]; - } - } else if ([iconData.firstObject isEqualToString:@"fromAssetImage"]) { - if (iconData.count == 3) { - image = [UIImage imageNamed:[registrar lookupKeyForAsset:iconData[1]]]; - id scaleParam = iconData[2]; - image = [FLTMarkersController scaleImage:image by:scaleParam]; - } else { - NSString *error = - [NSString stringWithFormat:@"'fromAssetImage' should have exactly 3 arguments. Got: %lu", - (unsigned long)iconData.count]; - NSException *exception = [NSException exceptionWithName:@"InvalidBitmapDescriptor" - reason:error - userInfo:nil]; - @throw exception; - } - } else if ([iconData[0] isEqualToString:@"fromBytes"]) { - if (iconData.count == 2) { - @try { - FlutterStandardTypedData *byteData = iconData[1]; - CGFloat screenScale = [[UIScreen mainScreen] scale]; - image = [UIImage imageWithData:[byteData data] scale:screenScale]; - } @catch (NSException *exception) { - @throw [NSException exceptionWithName:@"InvalidByteDescriptor" - reason:@"Unable to interpret bytes as a valid image." - userInfo:nil]; - } - } else { - NSString *error = [NSString - stringWithFormat:@"fromBytes should have exactly one argument, the bytes. Got: %lu", - (unsigned long)iconData.count]; - NSException *exception = [NSException exceptionWithName:@"InvalidByteDescriptor" - reason:error - userInfo:nil]; - @throw exception; - } - } - - return image; -} - -+ (UIImage *)scaleImage:(UIImage *)image by:(id)scaleParam { - double scale = 1.0; - if ([scaleParam isKindOfClass:[NSNumber class]]) { - scale = [scaleParam doubleValue]; - } - if (fabs(scale - 1) > 1e-3) { - return [UIImage imageWithCGImage:[image CGImage] - scale:(image.scale * scale) - orientation:(image.imageOrientation)]; - } - return image; -} - @end diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.h index 833fd92f48d3..bd0c9110200e 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.h @@ -5,20 +5,8 @@ #import #import -// Defines polygon UI options writable from Flutter. -@protocol FLTGoogleMapPolygonOptionsSink -- (void)setConsumeTapEvents:(BOOL)consume; -- (void)setVisible:(BOOL)visible; -- (void)setFillColor:(UIColor *)color; -- (void)setStrokeColor:(UIColor *)color; -- (void)setStrokeWidth:(CGFloat)width; -- (void)setPoints:(NSArray *)points; -- (void)setHoles:(NSArray *> *)holes; -- (void)setZIndex:(int)zIndex; -@end - // Defines polygon controllable by Flutter. -@interface FLTGoogleMapPolygonController : NSObject +@interface FLTGoogleMapPolygonController : NSObject - (instancetype)initPolygonWithPath:(GMSMutablePath *)path identifier:(NSString *)identifier mapView:(GMSMapView *)mapView; diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m index a7f49747c27d..ed9db46ccc31 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m @@ -30,8 +30,6 @@ - (void)removePolygon { self.polygon.map = nil; } -#pragma mark - FLTGoogleMapPolygonOptionsSink methods - - (void)setConsumeTapEvents:(BOOL)consumes { self.polygon.tappable = consumes; } @@ -72,6 +70,50 @@ - (void)setStrokeColor:(UIColor *)color { - (void)setStrokeWidth:(CGFloat)width { self.polygon.strokeWidth = width; } + +- (void)interpretPolygonOptions:(NSDictionary *)data + registrar:(NSObject *)registrar { + NSNumber *consumeTapEvents = data[@"consumeTapEvents"]; + if (consumeTapEvents && consumeTapEvents != (id)[NSNull null]) { + [self setConsumeTapEvents:[consumeTapEvents boolValue]]; + } + + NSNumber *visible = data[@"visible"]; + if (visible && visible != (id)[NSNull null]) { + [self setVisible:[visible boolValue]]; + } + + NSNumber *zIndex = data[@"zIndex"]; + if (zIndex && zIndex != (id)[NSNull null]) { + [self setZIndex:[zIndex intValue]]; + } + + NSArray *points = data[@"points"]; + if (points && points != (id)[NSNull null]) { + [self setPoints:[FLTGoogleMapJSONConversions pointsFromLatlongs:points]]; + } + + NSArray *holes = data[@"holes"]; + if (holes && holes != (id)[NSNull null]) { + [self setHoles:[FLTGoogleMapJSONConversions holesFromPointsArray:holes]]; + } + + NSNumber *fillColor = data[@"fillColor"]; + if (fillColor && fillColor != (id)[NSNull null]) { + [self setFillColor:[FLTGoogleMapJSONConversions colorFromRGBA:fillColor]]; + } + + NSNumber *strokeColor = data[@"strokeColor"]; + if (strokeColor && strokeColor != (id)[NSNull null]) { + [self setStrokeColor:[FLTGoogleMapJSONConversions colorFromRGBA:strokeColor]]; + } + + NSNumber *strokeWidth = data[@"strokeWidth"]; + if (strokeWidth && strokeWidth != (id)[NSNull null]) { + [self setStrokeWidth:[strokeWidth intValue]]; + } +} + @end @interface FLTPolygonsController () @@ -101,28 +143,24 @@ - (instancetype)init:(FlutterMethodChannel *)methodChannel - (void)addPolygons:(NSArray *)polygonsToAdd { for (NSDictionary *polygon in polygonsToAdd) { GMSMutablePath *path = [FLTPolygonsController getPath:polygon]; - NSString *identifier = [FLTPolygonsController getPolygonId:polygon]; + NSString *identifier = polygon[@"polygonId"]; FLTGoogleMapPolygonController *controller = [[FLTGoogleMapPolygonController alloc] initPolygonWithPath:path identifier:identifier mapView:self.mapView]; - [FLTPolygonsController interpretPolygonOptions:polygon - sink:controller - registrar:self.registrar]; + [controller interpretPolygonOptions:polygon registrar:self.registrar]; self.polygonIdentifierToController[identifier] = controller; } } - (void)changePolygons:(NSArray *)polygonsToChange { for (NSDictionary *polygon in polygonsToChange) { - NSString *identifier = [FLTPolygonsController getPolygonId:polygon]; + NSString *identifier = polygon[@"polygonId"]; FLTGoogleMapPolygonController *controller = self.polygonIdentifierToController[identifier]; if (!controller) { continue; } - [FLTPolygonsController interpretPolygonOptions:polygon - sink:controller - registrar:self.registrar]; + [controller interpretPolygonOptions:polygon registrar:self.registrar]; } } @@ -165,51 +203,4 @@ + (GMSMutablePath *)getPath:(NSDictionary *)polygon { return path; } -+ (NSString *)getPolygonId:(NSDictionary *)polygon { - return polygon[@"polygonId"]; -} - -+ (void)interpretPolygonOptions:(NSDictionary *)data - sink:(id)sink - registrar:(NSObject *)registrar { - NSNumber *consumeTapEvents = data[@"consumeTapEvents"]; - if (consumeTapEvents && consumeTapEvents != (id)[NSNull null]) { - [sink setConsumeTapEvents:[consumeTapEvents boolValue]]; - } - - NSNumber *visible = data[@"visible"]; - if (visible && visible != (id)[NSNull null]) { - [sink setVisible:[visible boolValue]]; - } - - NSNumber *zIndex = data[@"zIndex"]; - if (zIndex && zIndex != (id)[NSNull null]) { - [sink setZIndex:[zIndex intValue]]; - } - - NSArray *points = data[@"points"]; - if (points && points != (id)[NSNull null]) { - [sink setPoints:[FLTGoogleMapJSONConversions pointsFromLatlongs:points]]; - } - - NSArray *holes = data[@"holes"]; - if (holes && holes != (id)[NSNull null]) { - [sink setHoles:[FLTGoogleMapJSONConversions holesFromPointsArray:holes]]; - } - - NSNumber *fillColor = data[@"fillColor"]; - if (fillColor && fillColor != (id)[NSNull null]) { - [sink setFillColor:[FLTGoogleMapJSONConversions colorFromRGBA:fillColor]]; - } - - NSNumber *strokeColor = data[@"strokeColor"]; - if (strokeColor && strokeColor != (id)[NSNull null]) { - [sink setStrokeColor:[FLTGoogleMapJSONConversions colorFromRGBA:strokeColor]]; - } - - NSNumber *strokeWidth = data[@"strokeWidth"]; - if (strokeWidth && strokeWidth != (id)[NSNull null]) { - [sink setStrokeWidth:[strokeWidth intValue]]; - } -} @end diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.h index 1d255ad844a3..f85d1a3896fa 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.h @@ -5,19 +5,8 @@ #import #import -// Defines polyline UI options writable from Flutter. -@protocol FLTGoogleMapPolylineOptionsSink -- (void)setConsumeTapEvents:(BOOL)consume; -- (void)setVisible:(BOOL)visible; -- (void)setColor:(UIColor *)color; -- (void)setStrokeWidth:(CGFloat)width; -- (void)setPoints:(NSArray *)points; -- (void)setZIndex:(int)zIndex; -- (void)setGeodesic:(BOOL)isGeodesic; -@end - // Defines polyline controllable by Flutter. -@interface FLTGoogleMapPolylineController : NSObject +@interface FLTGoogleMapPolylineController : NSObject - (instancetype)initPolylineWithPath:(GMSMutablePath *)path identifier:(NSString *)identifier mapView:(GMSMapView *)mapView; diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m index 07ea6391bd23..6fd8f9601592 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m @@ -30,8 +30,6 @@ - (void)removePolyline { self.polyline.map = nil; } -#pragma mark - FLTGoogleMapPolylineOptionsSink methods - - (void)setConsumeTapEvents:(BOOL)consumes { self.polyline.tappable = consumes; } @@ -60,6 +58,45 @@ - (void)setStrokeWidth:(CGFloat)width { - (void)setGeodesic:(BOOL)isGeodesic { self.polyline.geodesic = isGeodesic; } + +- (void)interpretPolylineOptions:(NSDictionary *)data + registrar:(NSObject *)registrar { + NSNumber *consumeTapEvents = data[@"consumeTapEvents"]; + if (consumeTapEvents && consumeTapEvents != (id)[NSNull null]) { + [self setConsumeTapEvents:[consumeTapEvents boolValue]]; + } + + NSNumber *visible = data[@"visible"]; + if (visible && visible != (id)[NSNull null]) { + [self setVisible:[visible boolValue]]; + } + + NSNumber *zIndex = data[@"zIndex"]; + if (zIndex && zIndex != (id)[NSNull null]) { + [self setZIndex:[zIndex intValue]]; + } + + NSArray *points = data[@"points"]; + if (points && points != (id)[NSNull null]) { + [self setPoints:[FLTGoogleMapJSONConversions pointsFromLatlongs:points]]; + } + + NSNumber *strokeColor = data[@"color"]; + if (strokeColor && strokeColor != (id)[NSNull null]) { + [self setColor:[FLTGoogleMapJSONConversions colorFromRGBA:strokeColor]]; + } + + NSNumber *strokeWidth = data[@"width"]; + if (strokeWidth && strokeWidth != (id)[NSNull null]) { + [self setStrokeWidth:[strokeWidth intValue]]; + } + + NSNumber *geodesic = data[@"geodesic"]; + if (geodesic && geodesic != (id)[NSNull null]) { + [self setGeodesic:geodesic.boolValue]; + } +} + @end @interface FLTPolylinesController () @@ -89,27 +126,23 @@ - (instancetype)init:(FlutterMethodChannel *)methodChannel - (void)addPolylines:(NSArray *)polylinesToAdd { for (NSDictionary *polyline in polylinesToAdd) { GMSMutablePath *path = [FLTPolylinesController getPath:polyline]; - NSString *identifier = [FLTPolylinesController getPolylineIdentifier:polyline]; + NSString *identifier = polyline[@"polylineId"]; FLTGoogleMapPolylineController *controller = [[FLTGoogleMapPolylineController alloc] initPolylineWithPath:path identifier:identifier mapView:self.mapView]; - [FLTPolylinesController interpretPolylineOptions:polyline - sink:controller - registrar:self.registrar]; + [controller interpretPolylineOptions:polyline registrar:self.registrar]; self.polylineIdentifierToController[identifier] = controller; } } - (void)changePolylines:(NSArray *)polylinesToChange { for (NSDictionary *polyline in polylinesToChange) { - NSString *identifier = [FLTPolylinesController getPolylineIdentifier:polyline]; + NSString *identifier = polyline[@"polylineId"]; FLTGoogleMapPolylineController *controller = self.polylineIdentifierToController[identifier]; if (!controller) { continue; } - [FLTPolylinesController interpretPolylineOptions:polyline - sink:controller - registrar:self.registrar]; + [controller interpretPolylineOptions:polyline registrar:self.registrar]; } } - (void)removePolylineWithIdentifiers:(NSArray *)identifiers { @@ -147,47 +180,5 @@ + (GMSMutablePath *)getPath:(NSDictionary *)polyline { } return path; } -+ (NSString *)getPolylineIdentifier:(NSDictionary *)polyline { - return polyline[@"polylineId"]; -} - -+ (void)interpretPolylineOptions:(NSDictionary *)data - sink:(id)sink - registrar:(NSObject *)registrar { - NSNumber *consumeTapEvents = data[@"consumeTapEvents"]; - if (consumeTapEvents && consumeTapEvents != (id)[NSNull null]) { - [sink setConsumeTapEvents:[consumeTapEvents boolValue]]; - } - - NSNumber *visible = data[@"visible"]; - if (visible && visible != (id)[NSNull null]) { - [sink setVisible:[visible boolValue]]; - } - - NSNumber *zIndex = data[@"zIndex"]; - if (zIndex && zIndex != (id)[NSNull null]) { - [sink setZIndex:[zIndex intValue]]; - } - - NSArray *points = data[@"points"]; - if (points && points != (id)[NSNull null]) { - [sink setPoints:[FLTGoogleMapJSONConversions pointsFromLatlongs:points]]; - } - - NSNumber *strokeColor = data[@"color"]; - if (strokeColor && strokeColor != (id)[NSNull null]) { - [sink setColor:[FLTGoogleMapJSONConversions colorFromRGBA:strokeColor]]; - } - - NSNumber *strokeWidth = data[@"width"]; - if (strokeWidth && strokeWidth != (id)[NSNull null]) { - [sink setStrokeWidth:[strokeWidth intValue]]; - } - - NSNumber *geodesic = data[@"geodesic"]; - if (geodesic && geodesic != (id)[NSNull null]) { - [sink setGeodesic:geodesic.boolValue]; - } -} @end From 459555d5a8d832d946c374a9c69777979a4ae3ed Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Fri, 27 May 2022 10:10:20 -0700 Subject: [PATCH 5/7] method channels to strong --- .../ios/Classes/FLTGoogleMapTileOverlayController.m | 4 ++-- .../ios/Classes/GoogleMapCircleController.m | 2 +- .../ios/Classes/GoogleMapMarkerController.m | 2 +- .../ios/Classes/GoogleMapPolygonController.m | 2 +- .../ios/Classes/GoogleMapPolylineController.m | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m index 09a03be551c2..ba20106736d5 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m @@ -100,7 +100,7 @@ - (void)interpretTileOverlayOptions:(NSDictionary *)data { @interface FLTTileProviderController () -@property(weak, nonatomic) FlutterMethodChannel *methodChannel; +@property(strong, nonatomic) FlutterMethodChannel *methodChannel; @end @@ -160,7 +160,7 @@ - (void)requestTileForX:(NSUInteger)x @interface FLTTileOverlaysController () @property(strong, nonatomic) NSMutableDictionary *tileOverlayIdentifierToController; -@property(weak, nonatomic) FlutterMethodChannel *methodChannel; +@property(strong, nonatomic) FlutterMethodChannel *methodChannel; @property(weak, nonatomic) GMSMapView *mapView; @end diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m index e278c40806e8..a6c611f3173a 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m @@ -105,7 +105,7 @@ - (void)interpretCircleOptions:(NSDictionary *)data { @interface FLTCirclesController () -@property(weak, nonatomic) FlutterMethodChannel *methodChannel; +@property(strong, nonatomic) FlutterMethodChannel *methodChannel; @property(weak, nonatomic) GMSMapView *mapView; @property(strong, nonatomic) NSMutableDictionary *circleIdToController; diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m index 5572b95781c6..427cdeeeb2f5 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m @@ -224,7 +224,7 @@ - (UIImage *)scaleImage:(UIImage *)image by:(id)scaleParam { @interface FLTMarkersController () @property(strong, nonatomic) NSMutableDictionary *markerIdentifierToController; -@property(weak, nonatomic) FlutterMethodChannel *methodChannel; +@property(strong, nonatomic) FlutterMethodChannel *methodChannel; @property(weak, nonatomic) NSObject *registrar; @property(weak, nonatomic) GMSMapView *mapView; diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m index ed9db46ccc31..99ae2c3ec000 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m @@ -119,7 +119,7 @@ - (void)interpretPolygonOptions:(NSDictionary *)data @interface FLTPolygonsController () @property(strong, nonatomic) NSMutableDictionary *polygonIdentifierToController; -@property(weak, nonatomic) FlutterMethodChannel *methodChannel; +@property(strong, nonatomic) FlutterMethodChannel *methodChannel; @property(weak, nonatomic) NSObject *registrar; @property(weak, nonatomic) GMSMapView *mapView; diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m index 6fd8f9601592..a0a42136ea3e 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m @@ -102,7 +102,7 @@ - (void)interpretPolylineOptions:(NSDictionary *)data @interface FLTPolylinesController () @property(strong, nonatomic) NSMutableDictionary *polylineIdentifierToController; -@property(weak, nonatomic) FlutterMethodChannel *methodChannel; +@property(strong, nonatomic) FlutterMethodChannel *methodChannel; @property(weak, nonatomic) NSObject *registrar; @property(weak, nonatomic) GMSMapView *mapView; From f23fcbeb0a0910afb5959c4354ace09fabaa2c59 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 31 May 2022 10:28:30 -0700 Subject: [PATCH 6/7] renaming --- ...TGoogleMapJSONConversionsConversionTests.m | 16 +++++++------- ...rsions.h => FLTGoogleMapJSONConversions.h} | 6 ++--- ...rsions.m => FLTGoogleMapJSONConversions.m} | 22 +++++++++---------- .../FLTGoogleMapTileOverlayController.m | 2 +- .../ios/Classes/GoogleMapCircleController.m | 6 ++--- .../ios/Classes/GoogleMapController.m | 6 ++--- .../ios/Classes/GoogleMapMarkerController.m | 6 ++--- .../ios/Classes/GoogleMapPolygonController.m | 6 ++--- .../ios/Classes/GoogleMapPolylineController.m | 6 ++--- .../Classes/google_maps_flutter-umbrella.h | 2 +- 10 files changed, 39 insertions(+), 39 deletions(-) rename packages/google_maps_flutter/google_maps_flutter/ios/Classes/{JsonConversions.h => FLTGoogleMapJSONConversions.h} (85%) rename packages/google_maps_flutter/google_maps_flutter/ios/Classes/{JsonConversions.m => FLTGoogleMapJSONConversions.m} (91%) diff --git a/packages/google_maps_flutter/google_maps_flutter/example/ios/RunnerTests/FLTGoogleMapJSONConversionsConversionTests.m b/packages/google_maps_flutter/google_maps_flutter/example/ios/RunnerTests/FLTGoogleMapJSONConversionsConversionTests.m index 279d3a51365f..bf226feb2341 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/ios/RunnerTests/FLTGoogleMapJSONConversionsConversionTests.m +++ b/packages/google_maps_flutter/google_maps_flutter/example/ios/RunnerTests/FLTGoogleMapJSONConversionsConversionTests.m @@ -16,9 +16,9 @@ @interface FLTGoogleMapJSONConversionsTests : XCTestCase @implementation FLTGoogleMapJSONConversionsTests -- (void)testLocationFromLatlong { +- (void)testLocationFromLatLong { NSArray *latlong = @[ @1, @2 ]; - CLLocationCoordinate2D location = [FLTGoogleMapJSONConversions locationFromLatlong:latlong]; + CLLocationCoordinate2D location = [FLTGoogleMapJSONConversions locationFromLatLong:latlong]; XCTAssertEqual(location.latitude, 1); XCTAssertEqual(location.longitude, 2); } @@ -50,9 +50,9 @@ - (void)testColorFromRGBA { XCTAssertEqualWithAccuracy(alpha, 1 / 255.0, accuracy); } -- (void)testPointsFromLatlongs { +- (void)testPointsFromLatLongs { NSArray *latlongs = @[ @[ @1, @2 ], @[ @(3), @(4) ] ]; - NSArray *locations = [FLTGoogleMapJSONConversions pointsFromLatlongs:latlongs]; + NSArray *locations = [FLTGoogleMapJSONConversions pointsFromLatLongs:latlongs]; XCTAssertEqual(locations.count, 2); XCTAssertEqual(locations[0].coordinate.latitude, 1); XCTAssertEqual(locations[0].coordinate.longitude, 2); @@ -144,12 +144,12 @@ - (void)testPointFromDictionary { XCTAssertEqualWithAccuracy(point.y, 2, accuracy); } -- (void)testCoordinateBoundsFromLatlongs { +- (void)testCoordinateBoundsFromLatLongs { NSArray *latlong1 = @[ @1, @2 ]; NSArray *latlong2 = @[ @(3), @(4) ]; GMSCoordinateBounds *bounds = - [FLTGoogleMapJSONConversions coordinateBoundsFromLatlongs:@[ latlong1, latlong2 ]]; + [FLTGoogleMapJSONConversions coordinateBoundsFromLatLongs:@[ latlong1, latlong2 ]]; const CGFloat accuracy = 0.001; XCTAssertEqualWithAccuracy(bounds.southWest.latitude, 1, accuracy); @@ -191,7 +191,7 @@ - (void)testCameraUpdateFromChannelValueNewCameraPosition { // verified. // // The code in below test uses the 2nd approach. -- (void)skip_testCameraUpdateFromChannelValueNewLatlong { +- (void)skip_testCameraUpdateFromChannelValueNewLatLong { NSArray *channelValue = @[ @"newLatLng", @[ @1, @2 ] ]; GMSCameraUpdate *update = [FLTGoogleMapJSONConversions cameraUpdateFromChannelValue:channelValue]; @@ -211,7 +211,7 @@ - (void)testCameraUpdateFromChannelValueNewLatLngBounds { NSArray *latlong1 = @[ @1, @2 ]; NSArray *latlong2 = @[ @(3), @(4) ]; GMSCoordinateBounds *bounds = - [FLTGoogleMapJSONConversions coordinateBoundsFromLatlongs:@[ latlong1, latlong2 ]]; + [FLTGoogleMapJSONConversions coordinateBoundsFromLatLongs:@[ latlong1, latlong2 ]]; NSArray *channelValue = @[ @"newLatLngBounds", @[ latlong1, latlong2 ], @20 ]; id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapJSONConversions.h similarity index 85% rename from packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.h rename to packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapJSONConversions.h index f971d18b0429..cfccb7b0b5f9 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapJSONConversions.h @@ -9,11 +9,11 @@ NS_ASSUME_NONNULL_BEGIN @interface FLTGoogleMapJSONConversions : NSObject -+ (CLLocationCoordinate2D)locationFromLatlong:(NSArray *)latlong; ++ (CLLocationCoordinate2D)locationFromLatLong:(NSArray *)latlong; + (CGPoint)pointFromArray:(NSArray *)array; + (NSArray *)arrayFromLocation:(CLLocationCoordinate2D)location; + (UIColor *)colorFromRGBA:(NSNumber *)data; -+ (NSArray *)pointsFromLatlongs:(NSArray *)data; ++ (NSArray *)pointsFromLatLongs:(NSArray *)data; + (NSArray *> *)holesFromPointsArray:(NSArray *)data; + (nullable NSDictionary *)dictionaryFromPosition: (nullable GMSCameraPosition *)position; @@ -21,7 +21,7 @@ NS_ASSUME_NONNULL_BEGIN + (nullable NSDictionary *)dictionaryFromCoordinateBounds:(nullable GMSCoordinateBounds *)bounds; + (nullable GMSCameraPosition *)cameraPostionFromDictionary:(nullable NSDictionary *)channelValue; + (CGPoint)pointFromDictionary:(NSDictionary *)dictionary; -+ (GMSCoordinateBounds *)coordinateBoundsFromLatlongs:(NSArray *)latlongs; ++ (GMSCoordinateBounds *)coordinateBoundsFromLatLongs:(NSArray *)latlongs; + (GMSMapViewType)mapViewTypeFromTypeValue:(NSNumber *)value; + (nullable GMSCameraUpdate *)cameraUpdateFromChannelValue:(NSArray *)channelValue; diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapJSONConversions.m similarity index 91% rename from packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.m rename to packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapJSONConversions.m index 7cfdfe9af007..d554c501b1e2 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapJSONConversions.m @@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "JsonConversions.h" +#import "FLTGoogleMapJSONConversions.h" @implementation FLTGoogleMapJSONConversions -+ (CLLocationCoordinate2D)locationFromLatlong:(NSArray *)latlong { ++ (CLLocationCoordinate2D)locationFromLatLong:(NSArray *)latlong { return CLLocationCoordinate2DMake([latlong[0] doubleValue], [latlong[1] doubleValue]); } @@ -26,7 +26,7 @@ + (UIColor *)colorFromRGBA:(NSNumber *)numberColor { alpha:((float)((value & 0xFF000000) >> 24)) / 255.0]; } -+ (NSArray *)pointsFromLatlongs:(NSArray *)data { ++ (NSArray *)pointsFromLatLongs:(NSArray *)data { NSMutableArray *points = [[NSMutableArray alloc] init]; for (unsigned i = 0; i < [data count]; i++) { NSNumber *latitude = data[i][0]; @@ -42,7 +42,7 @@ + (UIColor *)colorFromRGBA:(NSNumber *)numberColor { + (NSArray *> *)holesFromPointsArray:(NSArray *)data { NSMutableArray *> *holes = [[[NSMutableArray alloc] init] init]; for (unsigned i = 0; i < [data count]; i++) { - NSArray *points = [FLTGoogleMapJSONConversions pointsFromLatlongs:data[i]]; + NSArray *points = [FLTGoogleMapJSONConversions pointsFromLatLongs:data[i]]; [holes addObject:points]; } @@ -83,7 +83,7 @@ + (nullable GMSCameraPosition *)cameraPostionFromDictionary:(nullable NSDictiona return nil; } return [GMSCameraPosition - cameraWithTarget:[FLTGoogleMapJSONConversions locationFromLatlong:data[@"target"]] + cameraWithTarget:[FLTGoogleMapJSONConversions locationFromLatLong:data[@"target"]] zoom:[data[@"zoom"] floatValue] bearing:[data[@"bearing"] doubleValue] viewingAngle:[data[@"tilt"] doubleValue]]; @@ -95,10 +95,10 @@ + (CGPoint)pointFromDictionary:(NSDictionary *)dictionary { return CGPointMake(x, y); } -+ (GMSCoordinateBounds *)coordinateBoundsFromLatlongs:(NSArray *)latlongs { ++ (GMSCoordinateBounds *)coordinateBoundsFromLatLongs:(NSArray *)latlongs { return [[GMSCoordinateBounds alloc] - initWithCoordinate:[FLTGoogleMapJSONConversions locationFromLatlong:latlongs[0]] - coordinate:[FLTGoogleMapJSONConversions locationFromLatlong:latlongs[1]]]; + initWithCoordinate:[FLTGoogleMapJSONConversions locationFromLatLong:latlongs[0]] + coordinate:[FLTGoogleMapJSONConversions locationFromLatLong:latlongs[1]]]; } + (GMSMapViewType)mapViewTypeFromTypeValue:(NSNumber *)typeValue { @@ -113,14 +113,14 @@ + (nullable GMSCameraUpdate *)cameraUpdateFromChannelValue:(NSArray *)channelVal setCamera:[FLTGoogleMapJSONConversions cameraPostionFromDictionary:channelValue[1]]]; } else if ([update isEqualToString:@"newLatLng"]) { return [GMSCameraUpdate - setTarget:[FLTGoogleMapJSONConversions locationFromLatlong:channelValue[1]]]; + setTarget:[FLTGoogleMapJSONConversions locationFromLatLong:channelValue[1]]]; } else if ([update isEqualToString:@"newLatLngBounds"]) { return [GMSCameraUpdate - fitBounds:[FLTGoogleMapJSONConversions coordinateBoundsFromLatlongs:channelValue[1]] + fitBounds:[FLTGoogleMapJSONConversions coordinateBoundsFromLatLongs:channelValue[1]] withPadding:[channelValue[2] doubleValue]]; } else if ([update isEqualToString:@"newLatLngZoom"]) { return - [GMSCameraUpdate setTarget:[FLTGoogleMapJSONConversions locationFromLatlong:channelValue[1]] + [GMSCameraUpdate setTarget:[FLTGoogleMapJSONConversions locationFromLatLong:channelValue[1]] zoom:[channelValue[2] floatValue]]; } else if ([update isEqualToString:@"scrollBy"]) { return [GMSCameraUpdate scrollByX:[channelValue[1] doubleValue] diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m index 09a03be551c2..7b39785c4953 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m @@ -3,7 +3,7 @@ // found in the LICENSE file. #import "FLTGoogleMapTileOverlayController.h" -#import "JsonConversions.h" +#import "FLTGoogleMapJSONConversions.h" @interface FLTGoogleMapTileOverlayController () diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m index e278c40806e8..f640d7774c47 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.m @@ -3,7 +3,7 @@ // found in the LICENSE file. #import "GoogleMapCircleController.h" -#import "JsonConversions.h" +#import "FLTGoogleMapJSONConversions.h" @interface FLTGoogleMapCircleController () @@ -77,7 +77,7 @@ - (void)interpretCircleOptions:(NSDictionary *)data { NSArray *center = data[@"center"]; if (center && center != (id)[NSNull null]) { - [self setCenter:[FLTGoogleMapJSONConversions locationFromLatlong:center]]; + [self setCenter:[FLTGoogleMapJSONConversions locationFromLatLong:center]]; } NSNumber *radius = data[@"radius"]; @@ -182,7 +182,7 @@ - (void)didTapCircleWithIdentifier:(NSString *)identifier { + (CLLocationCoordinate2D)getPosition:(NSDictionary *)circle { NSArray *center = circle[@"center"]; - return [FLTGoogleMapJSONConversions locationFromLatlong:center]; + return [FLTGoogleMapJSONConversions locationFromLatLong:center]; } + (CLLocationDistance)getRadius:(NSDictionary *)circle { diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m index c11f1649d70d..159141a65a4d 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m @@ -4,7 +4,7 @@ #import "GoogleMapController.h" #import "FLTGoogleMapTileOverlayController.h" -#import "JsonConversions.h" +#import "FLTGoogleMapJSONConversions.h" #pragma mark - Conversion of JSON-like values sent via platform channels. Forward declarations. @@ -186,7 +186,7 @@ - (void)onMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { } else if ([call.method isEqualToString:@"map#getScreenCoordinate"]) { if (self.mapView != nil) { CLLocationCoordinate2D location = - [FLTGoogleMapJSONConversions locationFromLatlong:call.arguments]; + [FLTGoogleMapJSONConversions locationFromLatLong:call.arguments]; CGPoint point = [self.mapView.projection pointForCoordinate:location]; result([FLTGoogleMapJSONConversions dictionaryFromPoint:point]); } else { @@ -556,7 +556,7 @@ - (void)interpretMapOptions:(NSDictionary *)data { [self setCameraTargetBounds:cameraTargetBounds.count > 0 && cameraTargetBounds[0] != [NSNull null] ? [FLTGoogleMapJSONConversions - coordinateBoundsFromLatlongs:cameraTargetBounds.firstObject] + coordinateBoundsFromLatLongs:cameraTargetBounds.firstObject] : nil]; } NSNumber *compassEnabled = data[@"compassEnabled"]; diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m index 5572b95781c6..1d85fb020bd6 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapMarkerController.m @@ -3,7 +3,7 @@ // found in the LICENSE file. #import "GoogleMapMarkerController.h" -#import "JsonConversions.h" +#import "FLTGoogleMapJSONConversions.h" @interface FLTGoogleMapMarkerController () @@ -120,7 +120,7 @@ - (void)interpretMarkerOptions:(NSDictionary *)data [self interpretInfoWindow:data]; NSArray *position = data[@"position"]; if (position && position != (id)[NSNull null]) { - [self setPosition:[FLTGoogleMapJSONConversions locationFromLatlong:position]]; + [self setPosition:[FLTGoogleMapJSONConversions locationFromLatLong:position]]; } NSNumber *rotation = data[@"rotation"]; if (rotation && rotation != (id)[NSNull null]) { @@ -381,7 +381,7 @@ - (void)isInfoWindowShownForMarkerWithIdentifier:(NSString *)identifier + (CLLocationCoordinate2D)getPosition:(NSDictionary *)marker { NSArray *position = marker[@"position"]; - return [FLTGoogleMapJSONConversions locationFromLatlong:position]; + return [FLTGoogleMapJSONConversions locationFromLatLong:position]; } @end diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m index ed9db46ccc31..a7630a885675 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m @@ -3,7 +3,7 @@ // found in the LICENSE file. #import "GoogleMapPolygonController.h" -#import "JsonConversions.h" +#import "FLTGoogleMapJSONConversions.h" @interface FLTGoogleMapPolygonController () @@ -90,7 +90,7 @@ - (void)interpretPolygonOptions:(NSDictionary *)data NSArray *points = data[@"points"]; if (points && points != (id)[NSNull null]) { - [self setPoints:[FLTGoogleMapJSONConversions pointsFromLatlongs:points]]; + [self setPoints:[FLTGoogleMapJSONConversions pointsFromLatLongs:points]]; } NSArray *holes = data[@"holes"]; @@ -195,7 +195,7 @@ - (bool)hasPolygonWithIdentifier:(NSString *)identifier { + (GMSMutablePath *)getPath:(NSDictionary *)polygon { NSArray *pointArray = polygon[@"points"]; - NSArray *points = [FLTGoogleMapJSONConversions pointsFromLatlongs:pointArray]; + NSArray *points = [FLTGoogleMapJSONConversions pointsFromLatLongs:pointArray]; GMSMutablePath *path = [GMSMutablePath path]; for (CLLocation *location in points) { [path addCoordinate:location.coordinate]; diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m index 6fd8f9601592..3ff475517703 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolylineController.m @@ -3,7 +3,7 @@ // found in the LICENSE file. #import "GoogleMapPolylineController.h" -#import "JsonConversions.h" +#import "FLTGoogleMapJSONConversions.h" @interface FLTGoogleMapPolylineController () @@ -78,7 +78,7 @@ - (void)interpretPolylineOptions:(NSDictionary *)data NSArray *points = data[@"points"]; if (points && points != (id)[NSNull null]) { - [self setPoints:[FLTGoogleMapJSONConversions pointsFromLatlongs:points]]; + [self setPoints:[FLTGoogleMapJSONConversions pointsFromLatLongs:points]]; } NSNumber *strokeColor = data[@"color"]; @@ -173,7 +173,7 @@ - (bool)hasPolylineWithIdentifier:(NSString *)identifier { } + (GMSMutablePath *)getPath:(NSDictionary *)polyline { NSArray *pointArray = polyline[@"points"]; - NSArray *points = [FLTGoogleMapJSONConversions pointsFromLatlongs:pointArray]; + NSArray *points = [FLTGoogleMapJSONConversions pointsFromLatLongs:pointArray]; GMSMutablePath *path = [GMSMutablePath path]; for (CLLocation *location in points) { [path addCoordinate:location.coordinate]; diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/google_maps_flutter-umbrella.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/google_maps_flutter-umbrella.h index 50880a2b9e9d..5a0f41039f9a 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/google_maps_flutter-umbrella.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/google_maps_flutter-umbrella.h @@ -5,7 +5,7 @@ #import #import #import -#import +#import FOUNDATION_EXPORT double google_maps_flutterVersionNumber; FOUNDATION_EXPORT const unsigned char google_maps_flutterVersionString[]; From da044f1b411b420cc4bf2a051d2ce16fb21f9725 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 31 May 2022 15:14:09 -0700 Subject: [PATCH 7/7] format --- .../google_maps_flutter/ios/Classes/GoogleMapController.m | 2 +- .../ios/Classes/google_maps_flutter-umbrella.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m index 159141a65a4d..6378994819dd 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m @@ -3,8 +3,8 @@ // found in the LICENSE file. #import "GoogleMapController.h" -#import "FLTGoogleMapTileOverlayController.h" #import "FLTGoogleMapJSONConversions.h" +#import "FLTGoogleMapTileOverlayController.h" #pragma mark - Conversion of JSON-like values sent via platform channels. Forward declarations. diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/google_maps_flutter-umbrella.h b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/google_maps_flutter-umbrella.h index 5a0f41039f9a..9969e716c26b 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/google_maps_flutter-umbrella.h +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/google_maps_flutter-umbrella.h @@ -3,9 +3,9 @@ // found in the LICENSE file. #import +#import #import #import -#import FOUNDATION_EXPORT double google_maps_flutterVersionNumber; FOUNDATION_EXPORT const unsigned char google_maps_flutterVersionString[];