diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_ios/CHANGELOG.md index 5e577772cba2..3338803175ed 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_ios/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.17.1 + +* Refactors code for improved testability. + ## 2.17.0 * Restructures code to prepare for SwiftPM support. diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/Podfile b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/Podfile index 391330adc7d6..c2c1dc5432d3 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/Podfile +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/Podfile @@ -33,8 +33,6 @@ target 'Runner' do flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) target 'RunnerTests' do inherit! :search_paths - - pod 'OCMock', '~> 3.9.1' end end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/Runner.xcodeproj/project.pbxproj b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/Runner.xcodeproj/project.pbxproj index 0ed22957bea8..0caf990b9847 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/Runner.xcodeproj/project.pbxproj @@ -12,10 +12,12 @@ 2A6906C72D263DF4001F8426 /* GoogleMapsGroundOverlayControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A6906C62D263DE7001F8426 /* GoogleMapsGroundOverlayControllerTests.m */; }; 2BDE99378062AE3E60B40021 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3ACE0AFE8D82CD5962486AFD /* Pods_RunnerTests.framework */; }; 330909FF2D99B7A60077A751 /* GoogleMapsMarkerControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 330909FE2D99B79B0077A751 /* GoogleMapsMarkerControllerTests.m */; }; + 3378E6352F23F9300045E7DA /* TestMapEventHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 3378E6342F23F92E0045E7DA /* TestMapEventHandler.m */; }; 339355BA2EB3E50300EBF864 /* GoogleMapsCircleControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 339355B92EB3E4F900EBF864 /* GoogleMapsCircleControllerTests.m */; }; 339355BD2EB3E56300EBF864 /* GoogleMapsTileOverlayControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 339355BC2EB3E55600EBF864 /* GoogleMapsTileOverlayControllerTests.m */; }; 339355BF2EB535A600EBF864 /* FLTGoogleMapHeatmapControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 339355BE2EB5359B00EBF864 /* FLTGoogleMapHeatmapControllerTests.m */; }; 339DF1F02F1FE49800748863 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 339DF1EF2F1FE49300748863 /* AppDelegate.swift */; }; + 33BF9C6E2F2182DF0005FA15 /* TestAssetProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 33BF9C6D2F2182DB0005FA15 /* TestAssetProvider.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 478116522BEF8F47002F593E /* GoogleMapsPolylineControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 478116512BEF8F47002F593E /* GoogleMapsPolylineControllerTests.m */; }; 528F16832C62941000148160 /* FGMClusterManagersControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 528F16822C62941000148160 /* FGMClusterManagersControllerTests.m */; }; @@ -68,12 +70,16 @@ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 2A6906C62D263DE7001F8426 /* GoogleMapsGroundOverlayControllerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GoogleMapsGroundOverlayControllerTests.m; sourceTree = ""; }; 330909FE2D99B79B0077A751 /* GoogleMapsMarkerControllerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GoogleMapsMarkerControllerTests.m; sourceTree = ""; }; + 3378E6332F23F9220045E7DA /* TestMapEventHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestMapEventHandler.h; sourceTree = ""; }; + 3378E6342F23F92E0045E7DA /* TestMapEventHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestMapEventHandler.m; sourceTree = ""; }; 339355B82EB3E4D500EBF864 /* GoogleMapsPolygonControllerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GoogleMapsPolygonControllerTests.m; sourceTree = ""; }; 339355B92EB3E4F900EBF864 /* GoogleMapsCircleControllerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GoogleMapsCircleControllerTests.m; sourceTree = ""; }; 339355BC2EB3E55600EBF864 /* GoogleMapsTileOverlayControllerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GoogleMapsTileOverlayControllerTests.m; sourceTree = ""; }; 339355BE2EB5359B00EBF864 /* FLTGoogleMapHeatmapControllerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FLTGoogleMapHeatmapControllerTests.m; sourceTree = ""; }; 339DF1EF2F1FE49300748863 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 339DF1F12F1FE4AD00748863 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 33BF9C6C2F2182CB0005FA15 /* TestAssetProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestAssetProvider.h; sourceTree = ""; }; + 33BF9C6D2F2182DB0005FA15 /* TestAssetProvider.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestAssetProvider.m; sourceTree = ""; }; 3ACE0AFE8D82CD5962486AFD /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 478116512BEF8F47002F593E /* GoogleMapsPolylineControllerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GoogleMapsPolylineControllerTests.m; sourceTree = ""; }; @@ -82,6 +88,7 @@ 61A9A8623F5CA9BBC813DC6B /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 6851F3552835BC180032B7C8 /* FGMConversionsUtilsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FGMConversionsUtilsTests.m; sourceTree = ""; }; 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 = ""; }; + 784666492D4C4C64000A1A5F /* FlutterFramework */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterFramework; path = Flutter/ephemeral/Packages/.packages/FlutterFramework; sourceTree = ""; }; 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; @@ -145,6 +152,7 @@ 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( + 784666492D4C4C64000A1A5F /* FlutterFramework */, 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 9740EEB21CF90195004384FC /* Debug.xcconfig */, @@ -221,6 +229,10 @@ 339355BC2EB3E55600EBF864 /* GoogleMapsTileOverlayControllerTests.m */, 982F2A6A27BADE17003C81F4 /* PartiallyMockedMapView.h */, 982F2A6B27BADE17003C81F4 /* PartiallyMockedMapView.m */, + 33BF9C6C2F2182CB0005FA15 /* TestAssetProvider.h */, + 33BF9C6D2F2182DB0005FA15 /* TestAssetProvider.m */, + 3378E6332F23F9220045E7DA /* TestMapEventHandler.h */, + 3378E6342F23F92E0045E7DA /* TestMapEventHandler.m */, F7151F14265D7ED70028CB91 /* Info.plist */, ); path = RunnerTests; @@ -509,8 +521,10 @@ 339355BF2EB535A600EBF864 /* FLTGoogleMapHeatmapControllerTests.m in Sources */, 339355BD2EB3E56300EBF864 /* GoogleMapsTileOverlayControllerTests.m in Sources */, F7151F13265D7ED70028CB91 /* GoogleMapsTests.m in Sources */, + 33BF9C6E2F2182DF0005FA15 /* TestAssetProvider.m in Sources */, 6851F3562835BC180032B7C8 /* FGMConversionsUtilsTests.m in Sources */, 982F2A6C27BADE17003C81F4 /* PartiallyMockedMapView.m in Sources */, + 3378E6352F23F9300045E7DA /* TestMapEventHandler.m in Sources */, 330909FF2D99B7A60077A751 /* GoogleMapsMarkerControllerTests.m in Sources */, 478116522BEF8F47002F593E /* GoogleMapsPolylineControllerTests.m in Sources */, 2A6906C72D263DF4001F8426 /* GoogleMapsGroundOverlayControllerTests.m in Sources */, diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/ExtractIconFromDataTests.m b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/ExtractIconFromDataTests.m index 4d7da98cac59..4fc1e9eef7d5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/ExtractIconFromDataTests.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/ExtractIconFromDataTests.m @@ -5,8 +5,7 @@ @import google_maps_flutter_ios; @import XCTest; -#import -#import +#import "TestAssetProvider.h" @interface ExtractIconFromDataTests : XCTestCase - (UIImage *)createOnePixelImage; @@ -15,15 +14,14 @@ - (UIImage *)createOnePixelImage; @implementation ExtractIconFromDataTests - (void)testExtractIconFromDataAssetAuto { - NSObject *mockRegistrar = - OCMStrictProtocolMock(@protocol(FlutterPluginRegistrar)); - id mockImageClass = OCMClassMock([UIImage class]); UIImage *testImage = [self createOnePixelImage]; - OCMStub([mockRegistrar lookupKeyForAsset:@"fakeImageNameKey"]).andReturn(@"fakeAssetKey"); - OCMStub(ClassMethod([mockImageClass imageNamed:@"fakeAssetKey"])).andReturn(testImage); + NSString *assetName = @"fakeImageName"; + TestAssetProvider *assetProvider = [[TestAssetProvider alloc] initWithImage:testImage + forAssetName:assetName + package:nil]; FGMPlatformBitmapAssetMap *bitmap = - [FGMPlatformBitmapAssetMap makeWithAssetName:@"fakeImageNameKey" + [FGMPlatformBitmapAssetMap makeWithAssetName:assetName bitmapScaling:FGMPlatformMapBitmapScalingAuto imagePixelRatio:1 width:nil @@ -32,7 +30,7 @@ - (void)testExtractIconFromDataAssetAuto { CGFloat screenScale = 3.0; UIImage *resultImage = - FGMIconFromBitmap([FGMPlatformBitmap makeWithBitmap:bitmap], mockRegistrar, screenScale); + FGMIconFromBitmap([FGMPlatformBitmap makeWithBitmap:bitmap], assetProvider, screenScale); XCTAssertNotNil(resultImage); XCTAssertEqual(resultImage.scale, 1.0); @@ -41,16 +39,15 @@ - (void)testExtractIconFromDataAssetAuto { } - (void)testExtractIconFromDataAssetAutoWithScale { - NSObject *mockRegistrar = - OCMStrictProtocolMock(@protocol(FlutterPluginRegistrar)); - id mockImageClass = OCMClassMock([UIImage class]); UIImage *testImage = [self createOnePixelImage]; - OCMStub([mockRegistrar lookupKeyForAsset:@"fakeImageNameKey"]).andReturn(@"fakeAssetKey"); - OCMStub(ClassMethod([mockImageClass imageNamed:@"fakeAssetKey"])).andReturn(testImage); + NSString *assetName = @"fakeImageName"; + TestAssetProvider *assetProvider = [[TestAssetProvider alloc] initWithImage:testImage + forAssetName:assetName + package:nil]; FGMPlatformBitmapAssetMap *bitmap = - [FGMPlatformBitmapAssetMap makeWithAssetName:@"fakeImageNameKey" + [FGMPlatformBitmapAssetMap makeWithAssetName:assetName bitmapScaling:FGMPlatformMapBitmapScalingAuto imagePixelRatio:10 width:nil @@ -59,7 +56,7 @@ - (void)testExtractIconFromDataAssetAutoWithScale { CGFloat screenScale = 3.0; UIImage *resultImage = - FGMIconFromBitmap([FGMPlatformBitmap makeWithBitmap:bitmap], mockRegistrar, screenScale); + FGMIconFromBitmap([FGMPlatformBitmap makeWithBitmap:bitmap], assetProvider, screenScale); XCTAssertNotNil(resultImage); XCTAssertEqual(resultImage.scale, 10); @@ -68,18 +65,17 @@ - (void)testExtractIconFromDataAssetAutoWithScale { } - (void)testExtractIconFromDataAssetAutoAndSizeWithSameAspectRatio { - NSObject *mockRegistrar = - OCMStrictProtocolMock(@protocol(FlutterPluginRegistrar)); - id mockImageClass = OCMClassMock([UIImage class]); UIImage *testImage = [self createOnePixelImage]; XCTAssertEqual(testImage.scale, 1.0); - OCMStub([mockRegistrar lookupKeyForAsset:@"fakeImageNameKey"]).andReturn(@"fakeAssetKey"); - OCMStub(ClassMethod([mockImageClass imageNamed:@"fakeAssetKey"])).andReturn(testImage); + NSString *assetName = @"fakeImageName"; + TestAssetProvider *assetProvider = [[TestAssetProvider alloc] initWithImage:testImage + forAssetName:assetName + package:nil]; const CGFloat width = 15.0; FGMPlatformBitmapAssetMap *bitmap = - [FGMPlatformBitmapAssetMap makeWithAssetName:@"fakeImageNameKey" + [FGMPlatformBitmapAssetMap makeWithAssetName:assetName bitmapScaling:FGMPlatformMapBitmapScalingAuto imagePixelRatio:1 width:@(width) @@ -88,7 +84,7 @@ - (void)testExtractIconFromDataAssetAutoAndSizeWithSameAspectRatio { CGFloat screenScale = 3.0; UIImage *resultImage = - FGMIconFromBitmap([FGMPlatformBitmap makeWithBitmap:bitmap], mockRegistrar, screenScale); + FGMIconFromBitmap([FGMPlatformBitmap makeWithBitmap:bitmap], assetProvider, screenScale); XCTAssertNotNil(resultImage); XCTAssertEqual(testImage.scale, 1.0); @@ -102,18 +98,17 @@ - (void)testExtractIconFromDataAssetAutoAndSizeWithSameAspectRatio { } - (void)testExtractIconFromDataAssetAutoAndSizeWithDifferentAspectRatio { - NSObject *mockRegistrar = - OCMStrictProtocolMock(@protocol(FlutterPluginRegistrar)); - id mockImageClass = OCMClassMock([UIImage class]); UIImage *testImage = [self createOnePixelImage]; - OCMStub([mockRegistrar lookupKeyForAsset:@"fakeImageNameKey"]).andReturn(@"fakeAssetKey"); - OCMStub(ClassMethod([mockImageClass imageNamed:@"fakeAssetKey"])).andReturn(testImage); + NSString *assetName = @"fakeImageName"; + TestAssetProvider *assetProvider = [[TestAssetProvider alloc] initWithImage:testImage + forAssetName:assetName + package:nil]; const CGFloat width = 15.0; const CGFloat height = 45.0; FGMPlatformBitmapAssetMap *bitmap = - [FGMPlatformBitmapAssetMap makeWithAssetName:@"fakeImageNameKey" + [FGMPlatformBitmapAssetMap makeWithAssetName:assetName bitmapScaling:FGMPlatformMapBitmapScalingAuto imagePixelRatio:1 width:@(width) @@ -122,7 +117,7 @@ - (void)testExtractIconFromDataAssetAutoAndSizeWithDifferentAspectRatio { CGFloat screenScale = 3.0; UIImage *resultImage = - FGMIconFromBitmap([FGMPlatformBitmap makeWithBitmap:bitmap], mockRegistrar, screenScale); + FGMIconFromBitmap([FGMPlatformBitmap makeWithBitmap:bitmap], assetProvider, screenScale); XCTAssertNotNil(resultImage); XCTAssertEqual(resultImage.scale, screenScale); XCTAssertEqual(resultImage.size.width, width); @@ -130,16 +125,15 @@ - (void)testExtractIconFromDataAssetAutoAndSizeWithDifferentAspectRatio { } - (void)testExtractIconFromDataAssetNoScaling { - NSObject *mockRegistrar = - OCMStrictProtocolMock(@protocol(FlutterPluginRegistrar)); - id mockImageClass = OCMClassMock([UIImage class]); UIImage *testImage = [self createOnePixelImage]; - OCMStub([mockRegistrar lookupKeyForAsset:@"fakeImageNameKey"]).andReturn(@"fakeAssetKey"); - OCMStub(ClassMethod([mockImageClass imageNamed:@"fakeAssetKey"])).andReturn(testImage); + NSString *assetName = @"fakeImageName"; + TestAssetProvider *assetProvider = [[TestAssetProvider alloc] initWithImage:testImage + forAssetName:assetName + package:nil]; FGMPlatformBitmapAssetMap *bitmap = - [FGMPlatformBitmapAssetMap makeWithAssetName:@"fakeImageNameKey" + [FGMPlatformBitmapAssetMap makeWithAssetName:assetName bitmapScaling:FGMPlatformMapBitmapScalingNone imagePixelRatio:1 width:nil @@ -148,7 +142,7 @@ - (void)testExtractIconFromDataAssetNoScaling { CGFloat screenScale = 3.0; UIImage *resultImage = - FGMIconFromBitmap([FGMPlatformBitmap makeWithBitmap:bitmap], mockRegistrar, screenScale); + FGMIconFromBitmap([FGMPlatformBitmap makeWithBitmap:bitmap], assetProvider, screenScale); XCTAssertNotNil(resultImage); XCTAssertEqual(resultImage.scale, 1.0); @@ -157,8 +151,6 @@ - (void)testExtractIconFromDataAssetNoScaling { } - (void)testExtractIconFromDataBytesAuto { - NSObject *mockRegistrar = - OCMStrictProtocolMock(@protocol(FlutterPluginRegistrar)); UIImage *testImage = [self createOnePixelImage]; NSData *pngData = UIImagePNGRepresentation(testImage); XCTAssertNotNil(pngData); @@ -173,8 +165,8 @@ - (void)testExtractIconFromDataBytesAuto { CGFloat screenScale = 3.0; - UIImage *resultImage = - FGMIconFromBitmap([FGMPlatformBitmap makeWithBitmap:bitmap], mockRegistrar, screenScale); + UIImage *resultImage = FGMIconFromBitmap([FGMPlatformBitmap makeWithBitmap:bitmap], + [[TestAssetProvider alloc] init], screenScale); XCTAssertNotNil(resultImage); XCTAssertEqual(resultImage.scale, 1.0); @@ -183,8 +175,6 @@ - (void)testExtractIconFromDataBytesAuto { } - (void)testExtractIconFromDataBytesAutoWithScaling { - NSObject *mockRegistrar = - OCMStrictProtocolMock(@protocol(FlutterPluginRegistrar)); UIImage *testImage = [self createOnePixelImage]; NSData *pngData = UIImagePNGRepresentation(testImage); XCTAssertNotNil(pngData); @@ -199,8 +189,8 @@ - (void)testExtractIconFromDataBytesAutoWithScaling { CGFloat screenScale = 3.0; - UIImage *resultImage = - FGMIconFromBitmap([FGMPlatformBitmap makeWithBitmap:bitmap], mockRegistrar, screenScale); + UIImage *resultImage = FGMIconFromBitmap([FGMPlatformBitmap makeWithBitmap:bitmap], + [[TestAssetProvider alloc] init], screenScale); XCTAssertNotNil(resultImage); XCTAssertEqual(resultImage.scale, 10); XCTAssertEqual(resultImage.size.width, 0.1); @@ -208,8 +198,6 @@ - (void)testExtractIconFromDataBytesAutoWithScaling { } - (void)testExtractIconFromDataBytesAutoAndSizeWithSameAspectRatio { - NSObject *mockRegistrar = - OCMStrictProtocolMock(@protocol(FlutterPluginRegistrar)); UIImage *testImage = [self createOnePixelImage]; NSData *pngData = UIImagePNGRepresentation(testImage); XCTAssertNotNil(pngData); @@ -226,8 +214,8 @@ - (void)testExtractIconFromDataBytesAutoAndSizeWithSameAspectRatio { CGFloat screenScale = 3.0; - UIImage *resultImage = - FGMIconFromBitmap([FGMPlatformBitmap makeWithBitmap:bitmap], mockRegistrar, screenScale); + UIImage *resultImage = FGMIconFromBitmap([FGMPlatformBitmap makeWithBitmap:bitmap], + [[TestAssetProvider alloc] init], screenScale); XCTAssertNotNil(resultImage); XCTAssertEqual(testImage.scale, 1.0); @@ -242,8 +230,6 @@ - (void)testExtractIconFromDataBytesAutoAndSizeWithSameAspectRatio { } - (void)testExtractIconFromDataBytesAutoAndSizeWithDifferentAspectRatio { - NSObject *mockRegistrar = - OCMStrictProtocolMock(@protocol(FlutterPluginRegistrar)); UIImage *testImage = [self createOnePixelImage]; NSData *pngData = UIImagePNGRepresentation(testImage); XCTAssertNotNil(pngData); @@ -260,8 +246,8 @@ - (void)testExtractIconFromDataBytesAutoAndSizeWithDifferentAspectRatio { CGFloat screenScale = 3.0; - UIImage *resultImage = - FGMIconFromBitmap([FGMPlatformBitmap makeWithBitmap:bitmap], mockRegistrar, screenScale); + UIImage *resultImage = FGMIconFromBitmap([FGMPlatformBitmap makeWithBitmap:bitmap], + [[TestAssetProvider alloc] init], screenScale); XCTAssertNotNil(resultImage); XCTAssertEqual(resultImage.scale, screenScale); XCTAssertEqual(resultImage.size.width, width); @@ -269,8 +255,6 @@ - (void)testExtractIconFromDataBytesAutoAndSizeWithDifferentAspectRatio { } - (void)testExtractIconFromDataBytesNoScaling { - NSObject *mockRegistrar = - OCMStrictProtocolMock(@protocol(FlutterPluginRegistrar)); UIImage *testImage = [self createOnePixelImage]; NSData *pngData = UIImagePNGRepresentation(testImage); XCTAssertNotNil(pngData); @@ -285,8 +269,8 @@ - (void)testExtractIconFromDataBytesNoScaling { CGFloat screenScale = 3.0; - UIImage *resultImage = - FGMIconFromBitmap([FGMPlatformBitmap makeWithBitmap:bitmap], mockRegistrar, screenScale); + UIImage *resultImage = FGMIconFromBitmap([FGMPlatformBitmap makeWithBitmap:bitmap], + [[TestAssetProvider alloc] init], screenScale); XCTAssertNotNil(resultImage); XCTAssertEqual(resultImage.scale, 1.0); XCTAssertEqual(resultImage.size.width, 1.0); diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/FGMClusterManagersControllerTests.m b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/FGMClusterManagersControllerTests.m index f9baaa10184b..049855b05e4d 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/FGMClusterManagersControllerTests.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/FGMClusterManagersControllerTests.m @@ -3,12 +3,13 @@ // found in the LICENSE file. @import google_maps_flutter_ios; +@import Flutter; @import XCTest; @import GoogleMaps; -#import -#import #import "PartiallyMockedMapView.h" +#import "TestAssetProvider.h" +#import "TestMapEventHandler.h" @interface FGMClusterManagersControllerTests : XCTestCase @end @@ -16,7 +17,6 @@ @interface FGMClusterManagersControllerTests : XCTestCase @implementation FGMClusterManagersControllerTests - (void)testClustering { - NSObject *registrar = OCMProtocolMock(@protocol(FlutterPluginRegistrar)); CGRect frame = CGRectMake(0, 0, 100, 100); GMSMapViewOptions *mapViewOptions = [[GMSMapViewOptions alloc] init]; @@ -24,17 +24,16 @@ - (void)testClustering { mapViewOptions.camera = [[GMSCameraPosition alloc] initWithLatitude:0 longitude:0 zoom:0]; PartiallyMockedMapView *mapView = [[PartiallyMockedMapView alloc] initWithOptions:mapViewOptions]; - - id handler = OCMClassMock([FGMMapsCallbackApi class]); + TestMapEventHandler *eventHandler = [[TestMapEventHandler alloc] init]; FGMClusterManagersController *clusterManagersController = - [[FGMClusterManagersController alloc] initWithMapView:mapView callbackHandler:handler]; + [[FGMClusterManagersController alloc] initWithMapView:mapView eventDelegate:eventHandler]; FLTMarkersController *markersController = [[FLTMarkersController alloc] initWithMapView:mapView - callbackHandler:handler + eventDelegate:eventHandler clusterManagersController:clusterManagersController - registrar:registrar]; + assetProvider:[[TestAssetProvider alloc] init]]; // Add cluster managers. NSString *clusterManagerId = @"cm"; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/FGMConversionsUtilsTests.m b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/FGMConversionsUtilsTests.m index ea39943cf571..5277c81395f2 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/FGMConversionsUtilsTests.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/FGMConversionsUtilsTests.m @@ -6,7 +6,6 @@ @import XCTest; @import GoogleMaps; -#import #import "PartiallyMockedMapView.h" @interface FGMConversionUtilsTests : XCTestCase @@ -193,7 +192,6 @@ - (void)testMapViewTypeFromPigeonType { } - (void)testCameraUpdateFromNewCameraPosition { - id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); FGMPlatformCameraUpdateNewCameraPosition *newPositionUpdate = [FGMPlatformCameraUpdateNewCameraPosition makeWithCameraPosition:[FGMPlatformCameraPosition @@ -204,44 +202,24 @@ - (void)testCameraUpdateFromNewCameraPosition { zoom:3]]; FGMGetCameraUpdateForPigeonCameraUpdate( [FGMPlatformCameraUpdate makeWithCameraUpdate:newPositionUpdate]); - [[classMockCameraUpdate expect] - setCamera:FGMGetCameraPositionForPigeonCameraPosition(newPositionUpdate.cameraPosition)]; - [classMockCameraUpdate stopMocking]; + // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath + // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that + // injecting a wrapper would not meaningfully improve test coverage, since the non-test + // implementation would be about as complex as the conversion function itself. } -// TODO(cyanglaz): Fix the test for cameraUpdateFromArray 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_testCameraUpdateFromNewLatLong { +- (void)testCameraUpdateFromNewLatLong { const CGFloat lat = 1; const CGFloat lng = 2; FGMPlatformCameraUpdateNewLatLng *platformUpdate = [FGMPlatformCameraUpdateNewLatLng makeWithLatLng:[FGMPlatformLatLng makeWithLatitude:lat longitude:lng]]; - GMSCameraUpdate *update = FGMGetCameraUpdateForPigeonCameraUpdate( + FGMGetCameraUpdateForPigeonCameraUpdate( [FGMPlatformCameraUpdate makeWithCameraUpdate:platformUpdate]); - - GMSMapViewOptions *options = [[GMSMapViewOptions alloc] init]; - options.frame = CGRectZero; - options.camera = [GMSCameraPosition cameraWithTarget:CLLocationCoordinate2DMake(5, 6) zoom:1]; - GMSMapView *mapView = [[GMSMapView alloc] initWithOptions:options]; - [mapView moveCamera:update]; - const CGFloat accuracy = 0.001; - XCTAssertEqualWithAccuracy(mapView.camera.target.latitude, lat, - accuracy); // mapView.camera.target.latitude is still 5. - XCTAssertEqualWithAccuracy(mapView.camera.target.longitude, lng, - accuracy); // mapView.camera.target.longitude is still 6. + // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath + // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that + // injecting a wrapper would not meaningfully improve test coverage, since the non-test + // implementation would be about as complex as the conversion function itself. } - (void)testCameraUpdateFromNewLatLngBounds { @@ -254,12 +232,12 @@ - (void)testCameraUpdateFromNewLatLngBounds { FGMPlatformCameraUpdateNewLatLngBounds *platformUpdate = [FGMPlatformCameraUpdateNewLatLngBounds makeWithBounds:FGMGetPigeonLatLngBoundsForCoordinateBounds(bounds) padding:padding]; - id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); FGMGetCameraUpdateForPigeonCameraUpdate( [FGMPlatformCameraUpdate makeWithCameraUpdate:platformUpdate]); - - [[classMockCameraUpdate expect] fitBounds:bounds withPadding:padding]; - [classMockCameraUpdate stopMocking]; + // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath + // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that + // injecting a wrapper would not meaningfully improve test coverage, since the non-test + // implementation would be about as complex as the conversion function itself. } - (void)testCameraUpdateFromNewLatLngZoom { @@ -270,12 +248,12 @@ - (void)testCameraUpdateFromNewLatLngZoom { makeWithLatLng:[FGMPlatformLatLng makeWithLatitude:lat longitude:lng] zoom:zoom]; - id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); FGMGetCameraUpdateForPigeonCameraUpdate( [FGMPlatformCameraUpdate makeWithCameraUpdate:platformUpdate]); - - [[classMockCameraUpdate expect] setTarget:CLLocationCoordinate2DMake(lat, lng) zoom:zoom]; - [classMockCameraUpdate stopMocking]; + // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath + // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that + // injecting a wrapper would not meaningfully improve test coverage, since the non-test + // implementation would be about as complex as the conversion function itself. } - (void)testCameraUpdateFromScrollBy { @@ -284,12 +262,12 @@ - (void)testCameraUpdateFromScrollBy { FGMPlatformCameraUpdateScrollBy *platformUpdate = [FGMPlatformCameraUpdateScrollBy makeWithDx:x dy:y]; - id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); FGMGetCameraUpdateForPigeonCameraUpdate( [FGMPlatformCameraUpdate makeWithCameraUpdate:platformUpdate]); - - [[classMockCameraUpdate expect] scrollByX:x Y:y]; - [classMockCameraUpdate stopMocking]; + // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath + // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that + // injecting a wrapper would not meaningfully improve test coverage, since the non-test + // implementation would be about as complex as the conversion function itself. } - (void)testCameraUpdateFromZoomBy { @@ -297,12 +275,16 @@ - (void)testCameraUpdateFromZoomBy { FGMPlatformCameraUpdateZoomBy *platformUpdateNoPoint = [FGMPlatformCameraUpdateZoomBy makeWithAmount:zoom focus:nil]; - id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); FGMGetCameraUpdateForPigeonCameraUpdate( [FGMPlatformCameraUpdate makeWithCameraUpdate:platformUpdateNoPoint]); + // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath + // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that + // injecting a wrapper would not meaningfully improve test coverage, since the non-test + // implementation would be about as complex as the conversion function itself. +} - [[classMockCameraUpdate expect] zoomBy:zoom]; - +- (void)testCameraUpdateFromZoomByWithFocus { + const CGFloat zoom = 1; const CGFloat x = 2; const CGFloat y = 3; FGMPlatformCameraUpdateZoomBy *platformUpdate = @@ -310,43 +292,44 @@ - (void)testCameraUpdateFromZoomBy { FGMGetCameraUpdateForPigeonCameraUpdate( [FGMPlatformCameraUpdate makeWithCameraUpdate:platformUpdate]); - - [[classMockCameraUpdate expect] zoomBy:zoom atPoint:CGPointMake(x, y)]; - [classMockCameraUpdate stopMocking]; + // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath + // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that + // injecting a wrapper would not meaningfully improve test coverage, since the non-test + // implementation would be about as complex as the conversion function itself. } - (void)testCameraUpdateFromZoomIn { FGMPlatformCameraUpdateZoom *platformUpdate = [FGMPlatformCameraUpdateZoom makeWithOut:NO]; - id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); FGMGetCameraUpdateForPigeonCameraUpdate( [FGMPlatformCameraUpdate makeWithCameraUpdate:platformUpdate]); - - [[classMockCameraUpdate expect] zoomIn]; - [classMockCameraUpdate stopMocking]; + // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath + // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that + // injecting a wrapper would not meaningfully improve test coverage, since the non-test + // implementation would be about as complex as the conversion function itself. } - (void)testCameraUpdateFromZoomOut { FGMPlatformCameraUpdateZoom *platformUpdate = [FGMPlatformCameraUpdateZoom makeWithOut:YES]; - id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); FGMGetCameraUpdateForPigeonCameraUpdate( [FGMPlatformCameraUpdate makeWithCameraUpdate:platformUpdate]); - - [[classMockCameraUpdate expect] zoomOut]; - [classMockCameraUpdate stopMocking]; + // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath + // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that + // injecting a wrapper would not meaningfully improve test coverage, since the non-test + // implementation would be about as complex as the conversion function itself. } - (void)testCameraUpdateFromZoomTo { const CGFloat zoom = 1; FGMPlatformCameraUpdateZoomTo *platformUpdate = [FGMPlatformCameraUpdateZoomTo makeWithZoom:zoom]; - id classMockCameraUpdate = OCMClassMock([GMSCameraUpdate class]); FGMGetCameraUpdateForPigeonCameraUpdate( [FGMPlatformCameraUpdate makeWithCameraUpdate:platformUpdate]); - - [[classMockCameraUpdate expect] zoomTo:zoom]; - [classMockCameraUpdate stopMocking]; + // GMSCameraUpdate is not inspectable, so this test just ensures that the codepath + // doesn't throw. FGMGetCameraUpdateForPigeonCameraUpdate is simple enough that + // injecting a wrapper would not meaningfully improve test coverage, since the non-test + // implementation would be about as complex as the conversion function itself. } - (void)testStrokeStylesFromPatterns { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/FLTTileProviderControllerTests.m b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/FLTTileProviderControllerTests.m index 3c7f43b3c206..0040fce6b44b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/FLTTileProviderControllerTests.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/FLTTileProviderControllerTests.m @@ -6,7 +6,44 @@ @import GoogleMaps; @import google_maps_flutter_ios; -#import +@interface StubTileReceiver : NSObject +@end + +@implementation StubTileReceiver +- (void)receiveTileWithX:(NSUInteger)x + y:(NSUInteger)y + zoom:(NSUInteger)zoom + image:(nullable UIImage *)image { + // No-op. +} +@end + +@interface TestTileProvider : NSObject +@property(nonatomic) XCTestExpectation *expectation; +@end + +// A tile provider that expects a single call to +// tileWithOverlayIdentifier:location:zoom:completion: on the main thread, +// and then fulfills the expectation. +@implementation TestTileProvider +- (instancetype)initWithExpectation:(XCTestExpectation *)expectation { + if (self = [super init]) { + _expectation = expectation; + } + return self; +} + +- (void)tileWithOverlayIdentifier:(NSString *)tileOverlayId + location:(FGMPlatformPoint *)location + zoom:(NSInteger)zoom + completion:(void (^)(FGMPlatformTile *_Nullable, + FlutterError *_Nullable))completion { + XCTAssertTrue([[NSThread currentThread] isMainThread]); + [self.expectation fulfill]; +} +@end + +#pragma mark - @interface FLTTileProviderControllerTests : XCTestCase @end @@ -14,22 +51,13 @@ @interface FLTTileProviderControllerTests : XCTestCase @implementation FLTTileProviderControllerTests - (void)testCallChannelOnPlatformThread { - id handler = OCMClassMock([FGMMapsCallbackApi class]); + XCTestExpectation *expectation = [self expectationWithDescription:@"invokeMethod"]; + TestTileProvider *tileProvider = [[TestTileProvider alloc] initWithExpectation:expectation]; FLTTileProviderController *controller = [[FLTTileProviderController alloc] initWithTileOverlayIdentifier:@"foo" - callbackHandler:handler]; + tileProvider:tileProvider]; XCTAssertNotNil(controller); - XCTestExpectation *expectation = [self expectationWithDescription:@"invokeMethod"]; - OCMStub([handler tileWithOverlayIdentifier:[OCMArg any] - location:[OCMArg any] - zoom:0 - completion:[OCMArg any]]) - .andDo(^(NSInvocation *invocation) { - XCTAssertTrue([[NSThread currentThread] isMainThread]); - [expectation fulfill]; - }); - id receiver = OCMProtocolMock(@protocol(GMSTileReceiver)); - [controller requestTileForX:0 y:0 zoom:0 receiver:receiver]; + [controller requestTileForX:0 y:0 zoom:0 receiver:[[StubTileReceiver alloc] init]]; [self waitForExpectations:@[ expectation ] timeout:10.0]; } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/GoogleMapsGroundOverlayControllerTests.m b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/GoogleMapsGroundOverlayControllerTests.m index 9169d6064956..14a607c8487f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/GoogleMapsGroundOverlayControllerTests.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/GoogleMapsGroundOverlayControllerTests.m @@ -6,8 +6,8 @@ @import XCTest; @import GoogleMaps; -#import #import "PartiallyMockedMapView.h" +#import "TestAssetProvider.h" /// A GMSGroundOverlay that ensures that property updates are made before the map is set. @interface PropertyOrderValidatingGroundOverlay : GMSGroundOverlay { @@ -73,8 +73,6 @@ - (void)testUpdatingGroundOverlayWithPosition { FGMPlatformBitmap *bitmap = [FGMPlatformBitmap makeWithBitmap:[FGMPlatformBitmapDefaultMarker makeWithHue:0]]; - NSObject *mockRegistrar = - OCMStrictProtocolMock(@protocol(FlutterPluginRegistrar)); FGMPlatformGroundOverlay *platformGroundOverlay = [FGMPlatformGroundOverlay makeWithGroundOverlayId:@"id_1" @@ -90,7 +88,7 @@ - (void)testUpdatingGroundOverlayWithPosition { zoomLevel:@14.0]; [groundOverlayController updateFromPlatformGroundOverlay:platformGroundOverlay - registrar:mockRegistrar + assetProvider:[[TestAssetProvider alloc] init] screenScale:1.0]; XCTAssertNotNil(groundOverlayController.groundOverlay.icon); @@ -129,8 +127,6 @@ - (void)testUpdatingGroundOverlayWithBounds { FGMPlatformBitmap *bitmap = [FGMPlatformBitmap makeWithBitmap:[FGMPlatformBitmapDefaultMarker makeWithHue:0]]; - NSObject *mockRegistrar = - OCMStrictProtocolMock(@protocol(FlutterPluginRegistrar)); FGMPlatformGroundOverlay *platformGroundOverlay = [FGMPlatformGroundOverlay makeWithGroundOverlayId:@"id_1" @@ -146,7 +142,7 @@ - (void)testUpdatingGroundOverlayWithBounds { zoomLevel:nil]; [groundOverlayController updateFromPlatformGroundOverlay:platformGroundOverlay - registrar:mockRegistrar + assetProvider:[[TestAssetProvider alloc] init] screenScale:1.0]; XCTAssertNotNil(groundOverlayController.groundOverlay.icon); @@ -209,7 +205,7 @@ - (void)testUpdateGroundOverlaySetsVisibilityLast { clickable:YES zoomLevel:nil] withMapView:[GoogleMapsGroundOverlayControllerTests mapView] - registrar:nil + assetProvider:[[TestAssetProvider alloc] init] screenScale:1.0 usingBounds:YES]; XCTAssertTrue(groundOverlay.hasSetMap); diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/GoogleMapsMarkerControllerTests.m b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/GoogleMapsMarkerControllerTests.m index bac3fb2cc84e..a34b11ae3cc0 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/GoogleMapsMarkerControllerTests.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/GoogleMapsMarkerControllerTests.m @@ -6,9 +6,9 @@ @import XCTest; @import GoogleMaps; -#import - #import "PartiallyMockedMapView.h" +#import "TestAssetProvider.h" +#import "TestMapEventHandler.h" /// A GMSMarker that ensures that property updates are made before the map is set. @interface PropertyOrderValidatingMarker : GMSMarker { @@ -32,13 +32,13 @@ + (GMSMapView *)mapView { /// Returns a FLTMarkersController instance instantiated with the given map view. /// /// The mapView should outlive the controller, as the controller keeps a weak reference to it. -- (FLTMarkersController *)markersControllerWithMapView:(GMSMapView *)mapView { - NSObject *mockRegistrar = - OCMStrictProtocolMock(@protocol(FlutterPluginRegistrar)); +- (FLTMarkersController *)markersControllerWithMapView:(GMSMapView *)mapView + eventDelegate: + (NSObject *)eventDelegate { return [[FLTMarkersController alloc] initWithMapView:mapView - callbackHandler:[[FGMMapsCallbackApi alloc] init] + eventDelegate:eventDelegate clusterManagersController:nil - registrar:mockRegistrar]; + assetProvider:[[TestAssetProvider alloc] init]]; } - (FGMPlatformBitmap *)placeholderBitmap { @@ -47,7 +47,9 @@ - (FGMPlatformBitmap *)placeholderBitmap { - (void)testSetsMarkerNumericProperties { GMSMapView *mapView = [GoogleMapsMarkerControllerTests mapView]; - FLTMarkersController *controller = [self markersControllerWithMapView:mapView]; + TestMapEventHandler *eventHandler = [[TestMapEventHandler alloc] init]; + FLTMarkersController *controller = [self markersControllerWithMapView:mapView + eventDelegate:eventHandler]; NSString *markerIdentifier = @"marker"; double anchorX = 3.14; @@ -94,7 +96,9 @@ - (void)testSetsMarkerNumericProperties { // another property. - (void)testSetsDraggable { GMSMapView *mapView = [GoogleMapsMarkerControllerTests mapView]; - FLTMarkersController *controller = [self markersControllerWithMapView:mapView]; + TestMapEventHandler *eventHandler = [[TestMapEventHandler alloc] init]; + FLTMarkersController *controller = [self markersControllerWithMapView:mapView + eventDelegate:eventHandler]; NSString *markerIdentifier = @"marker"; [controller addMarkers:@[ [FGMPlatformMarker @@ -126,7 +130,9 @@ - (void)testSetsDraggable { // another property. - (void)testSetsFlat { GMSMapView *mapView = [GoogleMapsMarkerControllerTests mapView]; - FLTMarkersController *controller = [self markersControllerWithMapView:mapView]; + TestMapEventHandler *eventHandler = [[TestMapEventHandler alloc] init]; + FLTMarkersController *controller = [self markersControllerWithMapView:mapView + eventDelegate:eventHandler]; NSString *markerIdentifier = @"marker"; [controller addMarkers:@[ [FGMPlatformMarker @@ -158,7 +164,9 @@ - (void)testSetsFlat { // another property. - (void)testSetsVisible { GMSMapView *mapView = [GoogleMapsMarkerControllerTests mapView]; - FLTMarkersController *controller = [self markersControllerWithMapView:mapView]; + TestMapEventHandler *eventHandler = [[TestMapEventHandler alloc] init]; + FLTMarkersController *controller = [self markersControllerWithMapView:mapView + eventDelegate:eventHandler]; NSString *markerIdentifier = @"marker"; [controller addMarkers:@[ [FGMPlatformMarker @@ -189,7 +197,9 @@ - (void)testSetsVisible { - (void)testSetsMarkerInfoWindowProperties { GMSMapView *mapView = [GoogleMapsMarkerControllerTests mapView]; - FLTMarkersController *controller = [self markersControllerWithMapView:mapView]; + TestMapEventHandler *eventHandler = [[TestMapEventHandler alloc] init]; + FLTMarkersController *controller = [self markersControllerWithMapView:mapView + eventDelegate:eventHandler]; NSString *markerIdentifier = @"marker"; NSString *title = @"info title"; @@ -252,7 +262,7 @@ - (void)testUpdateMarkerSetsVisibilityLast { markerId:@"marker" clusterManagerId:nil] withMapView:[GoogleMapsMarkerControllerTests mapView] - registrar:nil + assetProvider:[[TestAssetProvider alloc] init] screenScale:1 usingOpacityForVisibility:NO]; XCTAssertTrue(marker.hasSetMap); diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/GoogleMapsPolylineControllerTests.m b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/GoogleMapsPolylineControllerTests.m index 19ca6e84a266..a018579c3e18 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/GoogleMapsPolylineControllerTests.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/GoogleMapsPolylineControllerTests.m @@ -6,7 +6,6 @@ @import XCTest; @import GoogleMaps; -#import #import "PartiallyMockedMapView.h" /// A GMSPolyline that ensures that property updates are made before the map is set. diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/GoogleMapsTests.m b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/GoogleMapsTests.m index ecbef7b3924e..e51da47062f7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/GoogleMapsTests.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/GoogleMapsTests.m @@ -6,9 +6,49 @@ @import XCTest; @import GoogleMaps; -#import -#import "FGMCATransactionWrapper.h" #import "PartiallyMockedMapView.h" +#import "TestAssetProvider.h" + +@interface MockCATransaction : NSObject +@property(nonatomic, assign) BOOL beginCalled; +@property(nonatomic, assign) BOOL commitCalled; +@property(nonatomic, assign) CFTimeInterval animationDuration; +@end + +@implementation MockCATransaction + +- (void)begin { + self.beginCalled = YES; +} + +- (void)commit { + self.commitCalled = YES; +} + +@end + +// No-op implementation of FlutterBinaryMessenger. +@interface StubBinaryMessenger : NSObject +@end + +@implementation StubBinaryMessenger +- (void)sendOnChannel:(NSString *)channel message:(NSData *)message { +} +- (void)sendOnChannel:(NSString *)channel + message:(NSData *)message + binaryReply:(FlutterBinaryReply)reply { +} +- (void)cleanUpConnection:(FlutterBinaryMessengerConnection)connection { +} +- (FlutterBinaryMessengerConnection)setMessageHandlerOnChannel:(nonnull NSString *)channel + binaryMessageHandler: + (FlutterBinaryMessageHandler _Nullable)handler { + return 0; +} + +@end + +#pragma mark - @interface FLTGoogleMapFactory (Test) @property(strong, nonatomic, readonly) id sharedMapServices; @@ -29,7 +69,6 @@ - (void)testPlugin { } - (void)testFrameObserver { - id registrar = OCMProtocolMock(@protocol(FlutterPluginRegistrar)); CGRect frame = CGRectMake(0, 0, 100, 100); GMSMapViewOptions *options = [[GMSMapViewOptions alloc] init]; options.frame = frame; @@ -39,7 +78,8 @@ - (void)testFrameObserver { [[FLTGoogleMapController alloc] initWithMapView:mapView viewIdentifier:0 creationParameters:[self emptyCreationParameters] - registrar:registrar]; + assetProvider:[[TestAssetProvider alloc] init] + binaryMessenger:[[StubBinaryMessenger alloc] init]]; for (NSInteger i = 0; i < 10; ++i) { [controller view]; @@ -51,7 +91,9 @@ - (void)testFrameObserver { } - (void)testMapsServiceSync { - id registrar = OCMProtocolMock(@protocol(FlutterPluginRegistrar)); + // The API requires a registrar, but this test doesn't actually use it, so just pass in a + // dummy object rather than set up a full mock. + id registrar = [[NSObject alloc] init]; FLTGoogleMapFactory *factory1 = [[FLTGoogleMapFactory alloc] initWithRegistrar:registrar]; XCTAssertNotNil(factory1.sharedMapServices); FLTGoogleMapFactory *factory2 = [[FLTGoogleMapFactory alloc] initWithRegistrar:registrar]; @@ -83,8 +125,6 @@ - (void)testHandleResultTileDownsamplesWideGamutImages { } - (void)testAnimateCameraWithUpdate { - NSObject *registrar = OCMProtocolMock(@protocol(FlutterPluginRegistrar)); - CGRect frame = CGRectMake(0, 0, 100, 100); GMSMapViewOptions *mapViewOptions = [[GMSMapViewOptions alloc] init]; mapViewOptions.frame = frame; @@ -98,27 +138,23 @@ - (void)testAnimateCameraWithUpdate { [[FLTGoogleMapController alloc] initWithMapView:mapView viewIdentifier:0 creationParameters:[self emptyCreationParameters] - registrar:registrar]; + assetProvider:[[TestAssetProvider alloc] init] + binaryMessenger:[[StubBinaryMessenger alloc] init]]; - id mapViewMock = OCMPartialMock(mapView); - id mockTransactionWrapper = OCMProtocolMock(@protocol(FGMCATransactionProtocol)); + MockCATransaction *mockTransactionWrapper = [[MockCATransaction alloc] init]; controller.callHandler.transactionWrapper = mockTransactionWrapper; FGMPlatformCameraUpdateZoomTo *zoomTo = [FGMPlatformCameraUpdateZoomTo makeWithZoom:10.0]; FGMPlatformCameraUpdate *cameraUpdate = [FGMPlatformCameraUpdate makeWithCameraUpdate:zoomTo]; FlutterError *error = nil; - OCMReject([mockTransactionWrapper begin]); - OCMReject([mockTransactionWrapper commit]); - OCMExpect([mapViewMock animateWithCameraUpdate:[OCMArg any]]); [controller.callHandler animateCameraWithUpdate:cameraUpdate duration:nil error:&error]; - OCMVerifyAll(mapViewMock); - OCMVerifyAll(mockTransactionWrapper); + XCTAssertTrue(mapView.didAnimateCamera); + XCTAssertFalse(mockTransactionWrapper.beginCalled); + XCTAssertFalse(mockTransactionWrapper.commitCalled); } - (void)testAnimateCameraWithUpdateAndDuration { - NSObject *registrar = OCMProtocolMock(@protocol(FlutterPluginRegistrar)); - CGRect frame = CGRectMake(0, 0, 100, 100); GMSMapViewOptions *mapViewOptions = [[GMSMapViewOptions alloc] init]; mapViewOptions.frame = frame; @@ -132,10 +168,10 @@ - (void)testAnimateCameraWithUpdateAndDuration { [[FLTGoogleMapController alloc] initWithMapView:mapView viewIdentifier:0 creationParameters:[self emptyCreationParameters] - registrar:registrar]; + assetProvider:[[TestAssetProvider alloc] init] + binaryMessenger:[[StubBinaryMessenger alloc] init]]; - id mapViewMock = OCMPartialMock(mapView); - id mockTransactionWrapper = OCMProtocolMock(@protocol(FGMCATransactionProtocol)); + MockCATransaction *mockTransactionWrapper = [[MockCATransaction alloc] init]; controller.callHandler.transactionWrapper = mockTransactionWrapper; FGMPlatformCameraUpdateZoomTo *zoomTo = [FGMPlatformCameraUpdateZoomTo makeWithZoom:10.0]; @@ -143,21 +179,17 @@ - (void)testAnimateCameraWithUpdateAndDuration { FlutterError *error = nil; NSNumber *durationMilliseconds = @100; - OCMExpect([mockTransactionWrapper begin]); - OCMExpect( - [mockTransactionWrapper setAnimationDuration:[durationMilliseconds doubleValue] / 1000]); - OCMExpect([mockTransactionWrapper commit]); - OCMExpect([mapViewMock animateWithCameraUpdate:[OCMArg any]]); [controller.callHandler animateCameraWithUpdate:cameraUpdate duration:durationMilliseconds error:&error]; - OCMVerifyAll(mapViewMock); - OCMVerifyAll(mockTransactionWrapper); + XCTAssertTrue(mapView.didAnimateCamera); + XCTAssertTrue(mockTransactionWrapper.beginCalled); + XCTAssertTrue(mockTransactionWrapper.commitCalled); + XCTAssertEqual(mockTransactionWrapper.animationDuration, + [durationMilliseconds doubleValue] / 1000); } - (void)testInspectorAPICameraPosition { - NSObject *registrar = OCMProtocolMock(@protocol(FlutterPluginRegistrar)); - CGRect frame = CGRectMake(0, 0, 100, 100); GMSMapViewOptions *mapViewOptions = [[GMSMapViewOptions alloc] init]; mapViewOptions.frame = frame; @@ -170,14 +202,16 @@ - (void)testInspectorAPICameraPosition { PartiallyMockedMapView *mapView = [[PartiallyMockedMapView alloc] initWithOptions:mapViewOptions]; + NSObject *binaryMessenger = [[StubBinaryMessenger alloc] init]; FLTGoogleMapController *controller = [[FLTGoogleMapController alloc] initWithMapView:mapView viewIdentifier:0 creationParameters:[self emptyCreationParameters] - registrar:registrar]; + assetProvider:[[TestAssetProvider alloc] init] + binaryMessenger:binaryMessenger]; FGMMapInspector *inspector = [[FGMMapInspector alloc] initWithMapController:controller - messenger:registrar.messenger + messenger:binaryMessenger pigeonSuffix:@"0"]; FlutterError *error = nil; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/PartiallyMockedMapView.h b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/PartiallyMockedMapView.h index 9a04ae84ab24..7b4665cb6820 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/PartiallyMockedMapView.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/PartiallyMockedMapView.h @@ -4,14 +4,13 @@ @import GoogleMaps; -/** - * Defines a map view used for testing key-value observing. - */ +/// Defines a map view used for testing key-value observing. @interface PartiallyMockedMapView : GMSMapView -/** - * The number of times that the `frame` KVO has been added. - */ +/// The number of times that the `frame` KVO has been added. @property(nonatomic, assign, readonly) NSInteger frameObserverCount; +/// True if animateWithCameraUpdate: was called. +@property(nonatomic, assign) BOOL didAnimateCamera; + @end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/PartiallyMockedMapView.m b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/PartiallyMockedMapView.m index 47d48d2e07fc..84b02710180b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/PartiallyMockedMapView.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/PartiallyMockedMapView.m @@ -31,4 +31,9 @@ - (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath { } } +- (void)animateWithCameraUpdate:(GMSCameraUpdate *)cameraUpdate { + [super animateWithCameraUpdate:cameraUpdate]; + self.didAnimateCamera = YES; +} + @end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/TestAssetProvider.h b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/TestAssetProvider.h new file mode 100644 index 000000000000..dbe80f9a2ef5 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/TestAssetProvider.h @@ -0,0 +1,24 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +@import Foundation; +@import google_maps_flutter_ios; + +NS_ASSUME_NONNULL_BEGIN + +/// Fake implementation of FGMAssetProvider for unit tests. +@interface TestAssetProvider : NSObject +/// Initializes an instance that returns an arbitrary key for the given asset +/// name, and the given image when when using that key for imageNamed:. +/// +/// Returns nil for any other names. +/// +/// This is useful for setting up tests that need to stub out the standard +/// flow of name -> key -> image. +- (instancetype)initWithImage:(UIImage *)image + forAssetName:(NSString *)assetName + package:(nullable NSString *)package; +@end + +NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/TestAssetProvider.m b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/TestAssetProvider.m new file mode 100644 index 000000000000..da74d716c1b6 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/TestAssetProvider.m @@ -0,0 +1,50 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "TestAssetProvider.h" + +static NSString *const kTestAssetKey = @"testAssetKey"; + +@interface TestAssetProvider () +@property(readonly, nonatomic) UIImage *image; +@property(readonly, nonatomic) NSString *assetName; +@property(readonly, nonatomic) NSString *package; +@end + +@implementation TestAssetProvider + +- (instancetype)initWithImage:(UIImage *)image + forAssetName:(NSString *)assetName + package:(nullable NSString *)package { + self = [super init]; + if (self) { + _image = image; + _assetName = assetName; + _package = package; + } + return self; +} + +- (NSString *)lookupKeyForAsset:(NSString *)asset { + if ([asset isEqualToString:self.assetName]) { + return kTestAssetKey; + } + return nil; +} + +- (NSString *)lookupKeyForAsset:(NSString *)asset fromPackage:(NSString *)package { + if ([asset isEqualToString:self.assetName] && [package isEqualToString:self.package]) { + return kTestAssetKey; + } + return nil; +} + +- (UIImage *)imageNamed:(NSString *)name { + if ([name isEqualToString:kTestAssetKey]) { + return self.image; + } + return nil; +} + +@end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/TestMapEventHandler.h b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/TestMapEventHandler.h new file mode 100644 index 000000000000..5babf1efda26 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/TestMapEventHandler.h @@ -0,0 +1,14 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +@import Foundation; +@import google_maps_flutter_ios; + +NS_ASSUME_NONNULL_BEGIN + +/// Fake implementation of FGMMapEventDelegate for unit tests. +@interface TestMapEventHandler : NSObject +@end + +NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/TestMapEventHandler.m b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/TestMapEventHandler.m new file mode 100644 index 000000000000..190d1b1af4fc --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios/RunnerTests/TestMapEventHandler.m @@ -0,0 +1,56 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "TestMapEventHandler.h" + +@implementation TestMapEventHandler + +- (void)didStartCameraMove { +} + +- (void)didMoveCameraToPosition:(FGMPlatformCameraPosition *)cameraPosition { +} + +- (void)didIdleCamera { +} + +- (void)didTapAtPosition:(FGMPlatformLatLng *)position { +} + +- (void)didLongPressAtPosition:(FGMPlatformLatLng *)position { +} + +- (void)didTapMarkerWithIdentifier:(NSString *)markerId { +} + +- (void)didStartDragForMarkerWithIdentifier:(NSString *)markerId + atPosition:(FGMPlatformLatLng *)position { +} + +- (void)didDragMarkerWithIdentifier:(NSString *)markerId atPosition:(FGMPlatformLatLng *)position { +} + +- (void)didEndDragForMarkerWithIdentifier:(NSString *)markerId + atPosition:(FGMPlatformLatLng *)position { +} + +- (void)didTapInfoWindowOfMarkerWithIdentifier:(NSString *)markerId { +} + +- (void)didTapCircleWithIdentifier:(NSString *)circleId { +} + +- (void)didTapCluster:(FGMPlatformCluster *)cluster { +} + +- (void)didTapPolygonWithIdentifier:(NSString *)polygonId { +} + +- (void)didTapPolylineWithIdentifier:(NSString *)polylineId { +} + +- (void)didTapGroundOverlayWithIdentifier:(NSString *)groundOverlayId { +} + +@end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/FGMClusterManagersController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/FGMClusterManagersController.m index 04c3f04c9285..ee8ddc806f13 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/FGMClusterManagersController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/FGMClusterManagersController.m @@ -13,8 +13,8 @@ @interface FGMClusterManagersController () @property(strong, nonatomic) NSMutableDictionary *clusterManagerIdentifierToManagers; -/// The callback handler interface for calls to Flutter. -@property(strong, nonatomic) FGMMapsCallbackApi *callbackHandler; +/// The delegate for handling interactions with clusters. +@property(weak, nonatomic) NSObject *eventDelegate; /// The current map instance on which the cluster managers are operating. @property(strong, nonatomic) GMSMapView *mapView; @@ -23,10 +23,10 @@ @interface FGMClusterManagersController () @implementation FGMClusterManagersController - (instancetype)initWithMapView:(GMSMapView *)mapView - callbackHandler:(FGMMapsCallbackApi *)callbackHandler { + eventDelegate:(NSObject *)eventDelegate { self = [super init]; if (self) { - _callbackHandler = callbackHandler; + _eventDelegate = eventDelegate; _mapView = mapView; _clusterManagerIdentifierToManagers = [[NSMutableDictionary alloc] init]; } @@ -106,9 +106,7 @@ - (void)didTapCluster:(GMUStaticCluster *)cluster { return; } FGMPlatformCluster *platFormCluster = FGMGetPigeonCluster(cluster, clusterManagerId); - [self.callbackHandler didTapCluster:platFormCluster - completion:^(FlutterError *_Nullable _){ - }]; + [self.eventDelegate didTapCluster:platFormCluster]; } #pragma mark - Private methods diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/FGMGroundOverlayController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/FGMGroundOverlayController.m index 624f43032c53..f1fe7281dc09 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/FGMGroundOverlayController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/FGMGroundOverlayController.m @@ -36,12 +36,12 @@ - (void)removeGroundOverlay { } - (void)updateFromPlatformGroundOverlay:(FGMPlatformGroundOverlay *)groundOverlay - registrar:(NSObject *)registrar + assetProvider:(NSObject *)assetProvider screenScale:(CGFloat)screenScale { [FGMGroundOverlayController updateGroundOverlay:self.groundOverlay fromPlatformGroundOverlay:groundOverlay withMapView:self.mapView - registrar:registrar + assetProvider:assetProvider screenScale:screenScale usingBounds:self.createdWithBounds]; } @@ -49,14 +49,14 @@ - (void)updateFromPlatformGroundOverlay:(FGMPlatformGroundOverlay *)groundOverla + (void)updateGroundOverlay:(GMSGroundOverlay *)groundOverlay fromPlatformGroundOverlay:(FGMPlatformGroundOverlay *)platformGroundOverlay withMapView:(GMSMapView *)mapView - registrar:(NSObject *)registrar + assetProvider:(NSObject *)assetProvider screenScale:(CGFloat)screenScale usingBounds:(BOOL)useBounds { groundOverlay.tappable = platformGroundOverlay.clickable; groundOverlay.zIndex = (int)platformGroundOverlay.zIndex; groundOverlay.anchor = CGPointMake(platformGroundOverlay.anchor.x, platformGroundOverlay.anchor.y); - UIImage *image = FGMIconFromBitmap(platformGroundOverlay.image, registrar, screenScale); + UIImage *image = FGMIconFromBitmap(platformGroundOverlay.image, assetProvider, screenScale); groundOverlay.icon = image; groundOverlay.bearing = platformGroundOverlay.bearing; groundOverlay.opacity = 1.0 - platformGroundOverlay.transparency; @@ -86,10 +86,10 @@ @interface FLTGroundOverlaysController () *groundOverlayControllerByIdentifier; /// A callback api for the map interactions. -@property(strong, nonatomic) FGMMapsCallbackApi *callbackHandler; +@property(weak, nonatomic) NSObject *eventDelegate; -/// Flutter Plugin Registrar used to load images. -@property(weak, nonatomic) NSObject *registrar; +/// Asset provider used to load images. +@property(weak, nonatomic) NSObject *assetProvider; /// The map view used to generate the controllers. @property(weak, nonatomic) GMSMapView *mapView; @@ -99,14 +99,14 @@ @interface FLTGroundOverlaysController () @implementation FLTGroundOverlaysController - (instancetype)initWithMapView:(GMSMapView *)mapView - callbackHandler:(FGMMapsCallbackApi *)callbackHandler - registrar:(NSObject *)registrar { + eventDelegate:(NSObject *)eventDelegate + assetProvider:(NSObject *)assetProvider { self = [super init]; if (self) { - _callbackHandler = callbackHandler; + _eventDelegate = eventDelegate; _mapView = mapView; _groundOverlayControllerByIdentifier = [[NSMutableDictionary alloc] init]; - _registrar = registrar; + _assetProvider = assetProvider; } return self; } @@ -129,7 +129,7 @@ - (void)addGroundOverlays:(NSArray *)groundOverlaysT coordinate:CLLocationCoordinate2DMake( groundOverlay.bounds.southwest.latitude, groundOverlay.bounds.southwest.longitude)] - icon:FGMIconFromBitmap(groundOverlay.image, self.registrar, + icon:FGMIconFromBitmap(groundOverlay.image, self.assetProvider, [self getScreenScale])]; } else { NSAssert(groundOverlay.zoomLevel != nil, @@ -137,7 +137,7 @@ - (void)addGroundOverlays:(NSArray *)groundOverlaysT gmsOverlay = [GMSGroundOverlay groundOverlayWithPosition:CLLocationCoordinate2DMake(groundOverlay.position.latitude, groundOverlay.position.longitude) - icon:FGMIconFromBitmap(groundOverlay.image, self.registrar, + icon:FGMIconFromBitmap(groundOverlay.image, self.assetProvider, [self getScreenScale]) zoomLevel:[groundOverlay.zoomLevel doubleValue]]; } @@ -148,7 +148,7 @@ - (void)addGroundOverlays:(NSArray *)groundOverlaysT isCreatedWithBounds:isCreatedWithBounds]; controller.zoomLevel = groundOverlay.zoomLevel; [controller updateFromPlatformGroundOverlay:groundOverlay - registrar:self.registrar + assetProvider:self.assetProvider screenScale:[self getScreenScale]]; self.groundOverlayControllerByIdentifier[identifier] = controller; } @@ -159,7 +159,7 @@ - (void)changeGroundOverlays:(NSArray *)groundOverla NSString *identifier = groundOverlay.groundOverlayId; FGMGroundOverlayController *controller = self.groundOverlayControllerByIdentifier[identifier]; [controller updateFromPlatformGroundOverlay:groundOverlay - registrar:self.registrar + assetProvider:self.assetProvider screenScale:[self getScreenScale]]; } } @@ -180,9 +180,7 @@ - (void)didTapGroundOverlayWithIdentifier:(NSString *)identifier { if (!controller) { return; } - [self.callbackHandler didTapGroundOverlayWithIdentifier:identifier - completion:^(FlutterError *_Nullable _){ - }]; + [self.eventDelegate didTapGroundOverlayWithIdentifier:identifier]; } - (bool)hasGroundOverlaysWithIdentifier:(NSString *)identifier { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/FGMImageUtils.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/FGMImageUtils.m index 7bd5192c2377..8136bfd6f6e9 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/FGMImageUtils.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/FGMImageUtils.m @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +@import Flutter; + #import "FGMImageUtils.h" @import Foundation; @@ -44,7 +46,7 @@ CGFloat screenScale); UIImage *FGMIconFromBitmap(FGMPlatformBitmap *platformBitmap, - NSObject *registrar, CGFloat screenScale) { + NSObject *assetProvider, CGFloat screenScale) { assert(screenScale > 0 && "Screen scale must be greater than 0"); // See comment in messages.dart for why this is so loosely typed. See also // https://github.com/flutter/flutter/issues/117819. @@ -62,16 +64,16 @@ // Refer to the flutter google_maps_flutter_platform_interface package for details. FGMPlatformBitmapAsset *bitmapAsset = bitmap; if (bitmapAsset.pkg) { - image = [UIImage imageNamed:[registrar lookupKeyForAsset:bitmapAsset.name - fromPackage:bitmapAsset.pkg]]; + image = [assetProvider imageNamed:[assetProvider lookupKeyForAsset:bitmapAsset.name + fromPackage:bitmapAsset.pkg]]; } else { - image = [UIImage imageNamed:[registrar lookupKeyForAsset:bitmapAsset.name]]; + image = [assetProvider imageNamed:[assetProvider lookupKeyForAsset:bitmapAsset.name]]; } } else if ([bitmap isKindOfClass:[FGMPlatformBitmapAssetImage class]]) { // Deprecated: This message handling for 'fromAssetImage' has been replaced by 'asset'. // Refer to the flutter google_maps_flutter_platform_interface package for details. FGMPlatformBitmapAssetImage *bitmapAssetImage = bitmap; - image = [UIImage imageNamed:[registrar lookupKeyForAsset:bitmapAssetImage.name]]; + image = [assetProvider imageNamed:[assetProvider lookupKeyForAsset:bitmapAssetImage.name]]; image = scaledImage(image, bitmapAssetImage.scale); } else if ([bitmap isKindOfClass:[FGMPlatformBitmapBytes class]]) { // Deprecated: This message handling for 'fromBytes' has been replaced by 'bytes'. @@ -88,7 +90,7 @@ } else if ([bitmap isKindOfClass:[FGMPlatformBitmapAssetMap class]]) { FGMPlatformBitmapAssetMap *bitmapAssetMap = bitmap; - image = [UIImage imageNamed:[registrar lookupKeyForAsset:bitmapAssetMap.assetName]]; + image = [assetProvider imageNamed:[assetProvider lookupKeyForAsset:bitmapAssetMap.assetName]]; if (bitmapAssetMap.bitmapScaling == FGMPlatformMapBitmapScalingAuto) { NSNumber *width = bitmapAssetMap.width; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/FLTGoogleMapTileOverlayController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/FLTGoogleMapTileOverlayController.m index c4cce14ed247..4116c82e4115 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/FLTGoogleMapTileOverlayController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/FLTGoogleMapTileOverlayController.m @@ -60,17 +60,17 @@ + (void)updateTileLayer:(GMSTileLayer *)tileLayer @interface FLTTileProviderController () -@property(strong, nonatomic) FGMMapsCallbackApi *callbackHandler; +@property(weak, nonatomic) NSObject *tileProviderDelegate; @end @implementation FLTTileProviderController - (instancetype)initWithTileOverlayIdentifier:(NSString *)identifier - callbackHandler:(FGMMapsCallbackApi *)callbackHandler { + tileProvider:(NSObject *)tileProvider { self = [super init]; if (self) { - _callbackHandler = callbackHandler; + _tileProviderDelegate = tileProvider; _tileOverlayIdentifier = identifier; } return self; @@ -107,7 +107,7 @@ - (void)requestTileForX:(NSUInteger)x zoom:(NSUInteger)zoom receiver:(id)receiver { dispatch_async(dispatch_get_main_queue(), ^{ - [self.callbackHandler + [self.tileProviderDelegate tileWithOverlayIdentifier:self.tileOverlayIdentifier location:[FGMPlatformPoint makeWithX:x y:y] zoom:zoom @@ -133,7 +133,7 @@ @interface FLTTileOverlaysController () @property(strong, nonatomic) NSMutableDictionary *tileOverlayIdentifierToController; -@property(strong, nonatomic) FGMMapsCallbackApi *callbackHandler; +@property(weak, nonatomic) NSObject *tileProviderDelegate; @property(weak, nonatomic) GMSMapView *mapView; @end @@ -141,12 +141,11 @@ @interface FLTTileOverlaysController () @implementation FLTTileOverlaysController - (instancetype)initWithMapView:(GMSMapView *)mapView - callbackHandler:(FGMMapsCallbackApi *)callbackHandler - registrar:(NSObject *)registrar { + tileProvider:(NSObject *)tileProvider { self = [super init]; if (self) { - _callbackHandler = callbackHandler; _mapView = mapView; + _tileProviderDelegate = tileProvider; _tileOverlayIdentifierToController = [[NSMutableDictionary alloc] init]; } return self; @@ -157,7 +156,7 @@ - (void)addTileOverlays:(NSArray *)tileOverlaysToAdd { NSString *identifier = tileOverlay.tileOverlayId; FLTTileProviderController *tileProvider = [[FLTTileProviderController alloc] initWithTileOverlayIdentifier:identifier - callbackHandler:self.callbackHandler]; + tileProvider:self.tileProviderDelegate]; FLTGoogleMapTileOverlayController *controller = [[FLTGoogleMapTileOverlayController alloc] initWithTileOverlay:tileOverlay tileLayer:tileProvider diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapCircleController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapCircleController.m index d2d0130dc64a..1348601ce0ff 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapCircleController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapCircleController.m @@ -60,7 +60,7 @@ + (void)updateCircle:(GMSCircle *)circle @interface FLTCirclesController () -@property(strong, nonatomic) FGMMapsCallbackApi *callbackHandler; +@property(weak, nonatomic) NSObject *eventDelegate; @property(weak, nonatomic) GMSMapView *mapView; @property(strong, nonatomic) NSMutableDictionary *circleIdToController; @@ -69,11 +69,10 @@ @interface FLTCirclesController () @implementation FLTCirclesController - (instancetype)initWithMapView:(GMSMapView *)mapView - callbackHandler:(FGMMapsCallbackApi *)callbackHandler - registrar:(NSObject *)registrar { + eventDelegate:(NSObject *)eventDelegate { self = [super init]; if (self) { - _callbackHandler = callbackHandler; + _eventDelegate = eventDelegate; _mapView = mapView; _circleIdToController = [NSMutableDictionary dictionaryWithCapacity:1]; } @@ -122,9 +121,7 @@ - (void)didTapCircleWithIdentifier:(NSString *)identifier { if (!controller) { return; } - [self.callbackHandler didTapCircleWithIdentifier:identifier - completion:^(FlutterError *_Nullable _){ - }]; + [self.eventDelegate didTapCircleWithIdentifier:identifier]; } @end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapController.m index 0537d48ba9ce..c265785d624e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapController.m @@ -7,6 +7,7 @@ #import "GoogleMapController.h" #import "GoogleMapController_Test.h" +#import "FGMAssetProvider.h" #import "FGMConversionUtils.h" #import "FGMGroundOverlayController.h" #import "FGMMarkerUserData.h" @@ -14,8 +15,6 @@ #import "FLTGoogleMapTileOverlayController.h" #import "google_maps_flutter_pigeon_messages.g.h" -#pragma mark - Conversion of JSON-like values sent via platform channels. Forward declarations. - @interface FLTGoogleMapFactory () @property(weak, nonatomic) NSObject *registrar; @@ -66,6 +65,155 @@ - (instancetype)initWithRegistrar:(NSObject *)registrar #pragma mark - +/// Non-test implementation of FGMAssetProvider, wrapping a Flutter plugin +/// registrar. +@interface FGMDefaultAssetProvider : NSObject +@property(weak, nonatomic) NSObject *registrar; + +- (instancetype)initWithRegistrar:(NSObject *)registrar; +@end + +@implementation FGMDefaultAssetProvider + +- (instancetype)initWithRegistrar:(NSObject *)registrar { + self = [super init]; + if (self) { + _registrar = registrar; + } + return self; +} + +- (NSString *)lookupKeyForAsset:(NSString *)asset { + return [self.registrar lookupKeyForAsset:asset]; +} + +- (NSString *)lookupKeyForAsset:(NSString *)asset fromPackage:(NSString *)package { + return [self.registrar lookupKeyForAsset:asset fromPackage:package]; +} + +- (UIImage *)imageNamed:(NSString *)name { + return [UIImage imageNamed:name]; +} + +@end + +#pragma mark - + +/// Non-test implementation of FGMAssetProvider, wrapping a FGMMapsCallbackApi +/// instance. +@interface FGMDefaultMapEventHandler : NSObject +@property(strong, nonatomic) FGMMapsCallbackApi *callbackHandler; + +- (instancetype)initWithCallbackHandler:(FGMMapsCallbackApi *)callbackHandler; +@end + +@implementation FGMDefaultMapEventHandler + +- (instancetype)initWithCallbackHandler:(FGMMapsCallbackApi *)callbackHandler { + self = [super init]; + if (self) { + _callbackHandler = callbackHandler; + } + return self; +} + +- (void)didStartCameraMove { + [self.callbackHandler didStartCameraMoveWithCompletion:^(FlutterError *_){ + }]; +} + +- (void)didMoveCameraToPosition:(FGMPlatformCameraPosition *)cameraPosition { + [self.callbackHandler didMoveCameraToPosition:cameraPosition + completion:^(FlutterError *_){ + }]; +} + +- (void)didIdleCamera { + [self.callbackHandler didIdleCameraWithCompletion:^(FlutterError *_){ + }]; +} + +- (void)didTapAtPosition:(FGMPlatformLatLng *)position { + [self.callbackHandler didTapAtPosition:position + completion:^(FlutterError *_){ + }]; +} + +- (void)didLongPressAtPosition:(FGMPlatformLatLng *)position { + [self.callbackHandler didLongPressAtPosition:position + completion:^(FlutterError *_){ + }]; +} + +- (void)didTapMarkerWithIdentifier:(NSString *)markerId { + [self.callbackHandler didTapMarkerWithIdentifier:markerId + completion:^(FlutterError *_){ + }]; +} + +- (void)didStartDragForMarkerWithIdentifier:(NSString *)markerId + atPosition:(FGMPlatformLatLng *)position { + [self.callbackHandler didStartDragForMarkerWithIdentifier:markerId + atPosition:position + completion:^(FlutterError *_){ + }]; +} + +- (void)didDragMarkerWithIdentifier:(NSString *)markerId atPosition:(FGMPlatformLatLng *)position { + [self.callbackHandler didDragMarkerWithIdentifier:markerId + atPosition:position + completion:^(FlutterError *_){ + }]; +} + +- (void)didEndDragForMarkerWithIdentifier:(NSString *)markerId + atPosition:(FGMPlatformLatLng *)position { + [self.callbackHandler didEndDragForMarkerWithIdentifier:markerId + atPosition:position + completion:^(FlutterError *_){ + }]; +} + +- (void)didTapInfoWindowOfMarkerWithIdentifier:(NSString *)markerId { + [self.callbackHandler didTapInfoWindowOfMarkerWithIdentifier:markerId + completion:^(FlutterError *_){ + }]; +} + +- (void)didTapCircleWithIdentifier:(NSString *)circleId { + [self.callbackHandler didTapCircleWithIdentifier:circleId + completion:^(FlutterError *_){ + }]; +} + +- (void)didTapCluster:(FGMPlatformCluster *)cluster { + [self.callbackHandler didTapCluster:cluster + completion:^(FlutterError *_){ + }]; +} + +- (void)didTapPolygonWithIdentifier:(NSString *)polygonId { + [self.callbackHandler didTapPolygonWithIdentifier:polygonId + completion:^(FlutterError *_){ + }]; +} + +- (void)didTapPolylineWithIdentifier:(NSString *)polylineId { + [self.callbackHandler didTapPolylineWithIdentifier:polylineId + completion:^(FlutterError *_){ + }]; +} + +- (void)didTapGroundOverlayWithIdentifier:(NSString *)groundOverlayId { + [self.callbackHandler didTapGroundOverlayWithIdentifier:groundOverlayId + completion:^(FlutterError *_){ + }]; +} + +@end + +#pragma mark - + /// Private declarations of the FGMMapCallHandler. @interface FGMMapCallHandler () - (instancetype)initWithMapController:(nonnull FLTGoogleMapController *)controller @@ -95,12 +243,12 @@ @interface FGMMapInspector () #pragma mark - -@interface FLTGoogleMapController () +@interface FLTGoogleMapController () @property(nonatomic, strong) GMSMapView *mapView; @property(nonatomic, strong) FGMMapsCallbackApi *dartCallbackHandler; +@property(nonatomic, strong) FGMDefaultMapEventHandler *mapEventHandler; @property(nonatomic, assign) BOOL trackCameraPosition; -@property(nonatomic, weak) NSObject *registrar; @property(nonatomic, strong) FGMClusterManagersController *clusterManagersController; @property(nonatomic, strong) FLTMarkersController *markersController; @property(nonatomic, strong) FLTPolygonsController *polygonsController; @@ -145,13 +293,15 @@ - (instancetype)initWithFrame:(CGRect)frame return [self initWithMapView:mapView viewIdentifier:viewId creationParameters:creationParameters - registrar:registrar]; + assetProvider:[[FGMDefaultAssetProvider alloc] initWithRegistrar:registrar] + binaryMessenger:registrar.messenger]; } - (instancetype)initWithMapView:(GMSMapView *_Nonnull)mapView viewIdentifier:(int64_t)viewId creationParameters:(FGMPlatformMapViewCreationParams *)creationParameters - registrar:(NSObject *_Nonnull)registrar { + assetProvider:(NSObject *)assetProvider + binaryMessenger:(NSObject *)binaryMessenger { if (self = [super init]) { _mapView = mapView; @@ -160,36 +310,32 @@ - (instancetype)initWithMapView:(GMSMapView *_Nonnull)mapView // https://github.com/flutter/flutter/issues/104121 [self interpretMapConfiguration:creationParameters.mapConfiguration]; NSString *pigeonSuffix = [NSString stringWithFormat:@"%lld", viewId]; - _dartCallbackHandler = [[FGMMapsCallbackApi alloc] initWithBinaryMessenger:registrar.messenger + _dartCallbackHandler = [[FGMMapsCallbackApi alloc] initWithBinaryMessenger:binaryMessenger messageChannelSuffix:pigeonSuffix]; + _mapEventHandler = + [[FGMDefaultMapEventHandler alloc] initWithCallbackHandler:_dartCallbackHandler]; _mapView.delegate = self; _mapView.paddingAdjustmentBehavior = kGMSMapViewPaddingAdjustmentBehaviorNever; - _registrar = registrar; _clusterManagersController = [[FGMClusterManagersController alloc] initWithMapView:_mapView - callbackHandler:_dartCallbackHandler]; + eventDelegate:_mapEventHandler]; _markersController = [[FLTMarkersController alloc] initWithMapView:_mapView - callbackHandler:_dartCallbackHandler + eventDelegate:_mapEventHandler clusterManagersController:_clusterManagersController - registrar:registrar]; + assetProvider:assetProvider]; _polygonsController = [[FLTPolygonsController alloc] initWithMapView:_mapView - callbackHandler:_dartCallbackHandler - registrar:registrar]; + eventDelegate:_mapEventHandler]; _polylinesController = [[FLTPolylinesController alloc] initWithMapView:_mapView - callbackHandler:_dartCallbackHandler - registrar:registrar]; + eventDelegate:_mapEventHandler]; _circlesController = [[FLTCirclesController alloc] initWithMapView:_mapView - callbackHandler:_dartCallbackHandler - registrar:registrar]; + eventDelegate:_mapEventHandler]; _heatmapsController = [[FLTHeatmapsController alloc] initWithMapView:_mapView]; - _tileOverlaysController = - [[FLTTileOverlaysController alloc] initWithMapView:_mapView - callbackHandler:_dartCallbackHandler - registrar:registrar]; + _tileOverlaysController = [[FLTTileOverlaysController alloc] initWithMapView:_mapView + tileProvider:self]; _groundOverlaysController = [[FLTGroundOverlaysController alloc] initWithMapView:_mapView - callbackHandler:_dartCallbackHandler - registrar:registrar]; + eventDelegate:_mapEventHandler + assetProvider:assetProvider]; [_clusterManagersController addClusterManagers:creationParameters.initialClusterManagers]; [_markersController addMarkers:creationParameters.initialMarkers]; [_polygonsController addPolygons:creationParameters.initialPolygons]; @@ -205,13 +351,13 @@ - (instancetype)initWithMapView:(GMSMapView *_Nonnull)mapView [_mapView addObserver:self forKeyPath:@"frame" options:0 context:nil]; _callHandler = [[FGMMapCallHandler alloc] initWithMapController:self - messenger:registrar.messenger + messenger:binaryMessenger pigeonSuffix:pigeonSuffix]; - SetUpFGMMapsApiWithSuffix(registrar.messenger, _callHandler, pigeonSuffix); + SetUpFGMMapsApiWithSuffix(binaryMessenger, _callHandler, pigeonSuffix); _inspector = [[FGMMapInspector alloc] initWithMapController:self - messenger:registrar.messenger + messenger:binaryMessenger pigeonSuffix:pigeonSuffix]; - SetUpFGMMapsInspectorApiWithSuffix(registrar.messenger, _inspector, pigeonSuffix); + SetUpFGMMapsInspectorApiWithSuffix(binaryMessenger, _inspector, pigeonSuffix); } return self; } @@ -352,22 +498,17 @@ - (NSString *)setMapStyle:(NSString *)mapStyle { #pragma mark - GMSMapViewDelegate methods - (void)mapView:(GMSMapView *)mapView willMove:(BOOL)gesture { - [self.dartCallbackHandler didStartCameraMoveWithCompletion:^(FlutterError *_Nullable _){ - }]; + [self.mapEventHandler didStartCameraMove]; } - (void)mapView:(GMSMapView *)mapView didChangeCameraPosition:(GMSCameraPosition *)position { if (self.trackCameraPosition) { - [self.dartCallbackHandler - didMoveCameraToPosition:FGMGetPigeonCameraPositionForPosition(position) - completion:^(FlutterError *_Nullable _){ - }]; + [self.mapEventHandler didMoveCameraToPosition:FGMGetPigeonCameraPositionForPosition(position)]; } } - (void)mapView:(GMSMapView *)mapView idleAtCameraPosition:(GMSCameraPosition *)position { - [self.dartCallbackHandler didIdleCameraWithCompletion:^(FlutterError *_Nullable _){ - }]; + [self.mapEventHandler didIdleCamera]; } - (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker { @@ -416,15 +557,11 @@ - (void)mapView:(GMSMapView *)mapView didTapOverlay:(GMSOverlay *)overlay { } - (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate { - [self.dartCallbackHandler didTapAtPosition:FGMGetPigeonLatLngForCoordinate(coordinate) - completion:^(FlutterError *_Nullable _){ - }]; + [self.mapEventHandler didTapAtPosition:FGMGetPigeonLatLngForCoordinate(coordinate)]; } - (void)mapView:(GMSMapView *)mapView didLongPressAtCoordinate:(CLLocationCoordinate2D)coordinate { - [self.dartCallbackHandler didLongPressAtPosition:FGMGetPigeonLatLngForCoordinate(coordinate) - completion:^(FlutterError *_Nullable _){ - }]; + [self.mapEventHandler didLongPressAtPosition:FGMGetPigeonLatLngForCoordinate(coordinate)]; } - (void)interpretMapConfiguration:(FGMPlatformMapConfiguration *)config { @@ -500,6 +637,19 @@ - (void)interpretMapConfiguration:(FGMPlatformMapConfiguration *)config { } } +#pragma mark - FGMTileProviderDelegate + +- (void)tileWithOverlayIdentifier:(NSString *)tileOverlayId + location:(FGMPlatformPoint *)location + zoom:(NSInteger)zoom + completion:(void (^)(FGMPlatformTile *_Nullable, + FlutterError *_Nullable))completion { + [self.dartCallbackHandler tileWithOverlayIdentifier:tileOverlayId + location:location + zoom:zoom + completion:completion]; +} + @end #pragma mark - diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapMarkerController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapMarkerController.m index ed3aabd7fc10..9d061eec8b09 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapMarkerController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapMarkerController.m @@ -54,7 +54,7 @@ - (void)removeMarker { } - (void)updateFromPlatformMarker:(FGMPlatformMarker *)platformMarker - registrar:(NSObject *)registrar + assetProvider:(NSObject *)assetProvider screenScale:(CGFloat)screenScale { self.clusterManagerIdentifier = platformMarker.clusterManagerId; self.consumeTapEvents = platformMarker.consumeTapEvents; @@ -69,7 +69,7 @@ - (void)updateFromPlatformMarker:(FGMPlatformMarker *)platformMarker [FLTGoogleMapMarkerController updateMarker:self.marker fromPlatformMarker:platformMarker withMapView:self.mapView - registrar:registrar + assetProvider:assetProvider screenScale:screenScale usingOpacityForVisibility:useOpacityForVisibility]; } @@ -77,12 +77,12 @@ - (void)updateFromPlatformMarker:(FGMPlatformMarker *)platformMarker + (void)updateMarker:(GMSMarker *)marker fromPlatformMarker:(FGMPlatformMarker *)platformMarker withMapView:(GMSMapView *)mapView - registrar:(NSObject *)registrar + assetProvider:(NSObject *)assetProvider screenScale:(CGFloat)screenScale usingOpacityForVisibility:(BOOL)useOpacityForVisibility { marker.groundAnchor = FGMGetCGPointForPigeonPoint(platformMarker.anchor); marker.draggable = platformMarker.draggable; - UIImage *image = FGMIconFromBitmap(platformMarker.icon, registrar, screenScale); + UIImage *image = FGMIconFromBitmap(platformMarker.icon, assetProvider, screenScale); marker.icon = image; marker.flat = platformMarker.flat; marker.position = FGMGetCoordinateForPigeonLatLng(platformMarker.position); @@ -108,11 +108,12 @@ + (void)updateMarker:(GMSMarker *)marker @interface FLTMarkersController () -@property(strong, nonatomic, readwrite) NSMutableDictionary *markerIdentifierToController; -@property(strong, nonatomic) FGMMapsCallbackApi *callbackHandler; +@property(strong, nonatomic, readwrite) + NSMutableDictionary *markerIdentifierToController; +@property(weak, nonatomic) NSObject *eventDelegate; /// Controller for adding/removing/fetching cluster managers @property(weak, nonatomic, nullable) FGMClusterManagersController *clusterManagersController; -@property(weak, nonatomic) NSObject *registrar; +@property(weak, nonatomic) NSObject *assetProvider; @property(weak, nonatomic) GMSMapView *mapView; @end @@ -120,16 +121,16 @@ @interface FLTMarkersController () @implementation FLTMarkersController - (instancetype)initWithMapView:(GMSMapView *)mapView - callbackHandler:(FGMMapsCallbackApi *)callbackHandler + eventDelegate:(NSObject *)eventDelegate clusterManagersController:(nullable FGMClusterManagersController *)clusterManagersController - registrar:(NSObject *)registrar { + assetProvider:(NSObject *)assetProvider { self = [super init]; if (self) { - _callbackHandler = callbackHandler; + _eventDelegate = eventDelegate; _mapView = mapView; _clusterManagersController = clusterManagersController; _markerIdentifierToController = [[NSMutableDictionary alloc] init]; - _registrar = registrar; + _assetProvider = assetProvider; } return self; } @@ -150,7 +151,7 @@ - (void)addMarker:(FGMPlatformMarker *)markerToAdd { markerIdentifier:markerIdentifier mapView:self.mapView]; [controller updateFromPlatformMarker:markerToAdd - registrar:self.registrar + assetProvider:self.assetProvider screenScale:[self getScreenScale]]; if (clusterManagerIdentifier) { GMUClusterManager *clusterManager = @@ -179,7 +180,7 @@ - (void)changeMarker:(FGMPlatformMarker *)markerToChange { NSString *clusterManagerIdentifier = markerToChange.clusterManagerId; NSString *previousClusterManagerIdentifier = [controller clusterManagerIdentifier]; [controller updateFromPlatformMarker:markerToChange - registrar:self.registrar + assetProvider:self.assetProvider screenScale:[self getScreenScale]]; if ([controller.marker conformsToProtocol:@protocol(GMUClusterItem)]) { @@ -232,9 +233,7 @@ - (BOOL)didTapMarkerWithIdentifier:(NSString *)identifier { if (!controller) { return NO; } - [self.callbackHandler didTapMarkerWithIdentifier:identifier - completion:^(FlutterError *_Nullable _){ - }]; + [self.eventDelegate didTapMarkerWithIdentifier:identifier]; return controller.consumeTapEvents; } @@ -247,11 +246,9 @@ - (void)didStartDraggingMarkerWithIdentifier:(NSString *)identifier if (!controller) { return; } - [self.callbackHandler + [self.eventDelegate didStartDragForMarkerWithIdentifier:identifier - atPosition:FGMGetPigeonLatLngForCoordinate(location) - completion:^(FlutterError *_Nullable _){ - }]; + atPosition:FGMGetPigeonLatLngForCoordinate(location)]; } - (void)didDragMarkerWithIdentifier:(NSString *)identifier @@ -263,10 +260,8 @@ - (void)didDragMarkerWithIdentifier:(NSString *)identifier if (!controller) { return; } - [self.callbackHandler didDragMarkerWithIdentifier:identifier - atPosition:FGMGetPigeonLatLngForCoordinate(location) - completion:^(FlutterError *_Nullable _){ - }]; + [self.eventDelegate didDragMarkerWithIdentifier:identifier + atPosition:FGMGetPigeonLatLngForCoordinate(location)]; } - (void)didEndDraggingMarkerWithIdentifier:(NSString *)identifier @@ -275,17 +270,13 @@ - (void)didEndDraggingMarkerWithIdentifier:(NSString *)identifier if (!controller) { return; } - [self.callbackHandler didEndDragForMarkerWithIdentifier:identifier - atPosition:FGMGetPigeonLatLngForCoordinate(location) - completion:^(FlutterError *_Nullable _){ - }]; + [self.eventDelegate didEndDragForMarkerWithIdentifier:identifier + atPosition:FGMGetPigeonLatLngForCoordinate(location)]; } - (void)didTapInfoWindowOfMarkerWithIdentifier:(NSString *)identifier { if (identifier && self.markerIdentifierToController[identifier]) { - [self.callbackHandler didTapInfoWindowOfMarkerWithIdentifier:identifier - completion:^(FlutterError *_Nullable _){ - }]; + [self.eventDelegate didTapInfoWindowOfMarkerWithIdentifier:identifier]; } } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapPolygonController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapPolygonController.m index 12cbfeefecd7..f5d077bd4ff1 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapPolygonController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapPolygonController.m @@ -70,8 +70,7 @@ + (void)updatePolygon:(GMSPolygon *)polygon @interface FLTPolygonsController () @property(strong, nonatomic) NSMutableDictionary *polygonIdentifierToController; -@property(strong, nonatomic) FGMMapsCallbackApi *callbackHandler; -@property(weak, nonatomic) NSObject *registrar; +@property(weak, nonatomic) NSObject *eventDelegate; @property(weak, nonatomic) GMSMapView *mapView; @end @@ -79,14 +78,12 @@ @interface FLTPolygonsController () @implementation FLTPolygonsController - (instancetype)initWithMapView:(GMSMapView *)mapView - callbackHandler:(FGMMapsCallbackApi *)callbackHandler - registrar:(NSObject *)registrar { + eventDelegate:(NSObject *)eventDelegate { self = [super init]; if (self) { - _callbackHandler = callbackHandler; + _eventDelegate = eventDelegate; _mapView = mapView; _polygonIdentifierToController = [NSMutableDictionary dictionaryWithCapacity:1]; - _registrar = registrar; } return self; } @@ -131,9 +128,7 @@ - (void)didTapPolygonWithIdentifier:(NSString *)identifier { if (!controller) { return; } - [self.callbackHandler didTapPolygonWithIdentifier:identifier - completion:^(FlutterError *_Nullable _){ - }]; + [self.eventDelegate didTapPolygonWithIdentifier:identifier]; } - (bool)hasPolygonWithIdentifier:(NSString *)identifier { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapPolylineController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapPolylineController.m index 63a7f7b7b0fc..ea84a4e5be54 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapPolylineController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/GoogleMapPolylineController.m @@ -63,8 +63,7 @@ + (void)updatePolyline:(GMSPolyline *)polyline @interface FLTPolylinesController () @property(strong, nonatomic) NSMutableDictionary *polylineIdentifierToController; -@property(strong, nonatomic) FGMMapsCallbackApi *callbackHandler; -@property(weak, nonatomic) NSObject *registrar; +@property(weak, nonatomic) NSObject *eventDelegate; @property(weak, nonatomic) GMSMapView *mapView; @end @@ -73,14 +72,12 @@ @interface FLTPolylinesController () @implementation FLTPolylinesController - (instancetype)initWithMapView:(GMSMapView *)mapView - callbackHandler:(FGMMapsCallbackApi *)callbackHandler - registrar:(NSObject *)registrar { + eventDelegate:(NSObject *)eventDelegate { self = [super init]; if (self) { - _callbackHandler = callbackHandler; + _eventDelegate = eventDelegate; _mapView = mapView; _polylineIdentifierToController = [NSMutableDictionary dictionaryWithCapacity:1]; - _registrar = registrar; } return self; } @@ -125,9 +122,7 @@ - (void)didTapPolylineWithIdentifier:(NSString *)identifier { if (!controller) { return; } - [self.callbackHandler didTapPolylineWithIdentifier:identifier - completion:^(FlutterError *_Nullable _){ - }]; + [self.eventDelegate didTapPolylineWithIdentifier:identifier]; } - (bool)hasPolylineWithIdentifier:(NSString *)identifier { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMAssetProvider.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMAssetProvider.h new file mode 100644 index 000000000000..2254ec7287b8 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMAssetProvider.h @@ -0,0 +1,42 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +@import UIKit; + +NS_ASSUME_NONNULL_BEGIN + +/// Protocol for looking up Flutter assets and resolving them to images. +/// +/// This is used to allow testing with mock assets without mocking the entire +/// Flutter plugin registrar and UIImage class. +@protocol FGMAssetProvider + +/// Returns the key for the given asset. +/// +/// Wraps the FlutterPluginRegistrar method of the same name. +/// +/// @param asset The name of the asset. +/// @return The key for the asset, or nil if not found. +- (nullable NSString *)lookupKeyForAsset:(NSString *)asset; + +/// Returns the key for the given asset from the given package. +/// +/// Wraps the FlutterPluginRegistrar method of the same name. +/// +/// @param asset The name of the asset. +/// @param package The name of the package to load the asset from. +/// @return The key for the asset, or nil if not found. +- (nullable NSString *)lookupKeyForAsset:(NSString *)asset fromPackage:(NSString *)package; + +/// Returns the image for the given named asset. +/// +/// Wraps the UIImage method of the same name. +/// +/// @param name The name of the image asset or file. +/// @return The image, or nil if not found. +- (nullable UIImage *)imageNamed:(NSString *)name; + +@end + +NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMClusterManagersController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMClusterManagersController.h index 98afbb34d1f0..b6134c6b9d28 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMClusterManagersController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMClusterManagersController.h @@ -6,6 +6,7 @@ @import GoogleMaps; @import GoogleMapsUtils; +#import "FGMMapEventDelegate.h" #import "google_maps_flutter_pigeon_messages.g.h" NS_ASSUME_NONNULL_BEGIN @@ -15,10 +16,10 @@ NS_ASSUME_NONNULL_BEGIN /// Initializes cluster manager controller. /// -/// @param callbackHandler A callback handler. +/// @param eventDelegate A delegate that will receive events from the cluster managers. /// @param mapView A map view that will be used to display clustered markers. - (instancetype)initWithMapView:(GMSMapView *)mapView - callbackHandler:(FGMMapsCallbackApi *)callbackHandler; + eventDelegate:(NSObject *)eventDelegate; /// Creates cluster managers and initializes them. /// diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMConversionUtils.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMConversionUtils.h index c7821882297c..788c585c6f34 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMConversionUtils.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMConversionUtils.h @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@import Flutter; @import Foundation; @import GoogleMaps; @import GoogleMapsUtils; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMGroundOverlayController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMGroundOverlayController.h index a5297f703b9e..f4a07aa950e5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMGroundOverlayController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMGroundOverlayController.h @@ -3,11 +3,12 @@ // found in the LICENSE file. @import CoreLocation; -@import Flutter; @import Foundation; @import GoogleMaps; @import UIKit; +#import "FGMAssetProvider.h" +#import "FGMMapEventDelegate.h" #import "google_maps_flutter_pigeon_messages.g.h" NS_ASSUME_NONNULL_BEGIN @@ -37,10 +38,10 @@ NS_ASSUME_NONNULL_BEGIN /// Controller of multiple ground overlays on the map. @interface FLTGroundOverlaysController : NSObject -/// Initializes the controller with a GMSMapView, callback handler and registrar. +/// Initializes the controller with a GMSMapView, event delegate, and asset provider. - (instancetype)initWithMapView:(GMSMapView *)mapView - callbackHandler:(FGMMapsCallbackApi *)callbackHandler - registrar:(NSObject *)registrar; + eventDelegate:(NSObject *)eventDelegate + assetProvider:(NSObject *)assetProvider; /// Adds ground overlays to the map. - (void)addGroundOverlays:(NSArray *)groundOverlaysToAdd; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMGroundOverlayController_Test.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMGroundOverlayController_Test.h index 87123539947d..1c4d062348a5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMGroundOverlayController_Test.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMGroundOverlayController_Test.h @@ -12,7 +12,7 @@ /// Function to update the gms ground overlay from platform ground overlay. - (void)updateFromPlatformGroundOverlay:(FGMPlatformGroundOverlay *)groundOverlay - registrar:(NSObject *)registrar + assetProvider:(NSObject *)assetProvider screenScale:(CGFloat)screenScale; /// Updates the underlying GMSGroundOverlay with the properties from the given @@ -22,7 +22,7 @@ + (void)updateGroundOverlay:(GMSGroundOverlay *)groundOverlay fromPlatformGroundOverlay:(FGMPlatformGroundOverlay *)groundOverlay withMapView:(GMSMapView *)mapView - registrar:(NSObject *)registrar + assetProvider:(NSObject *)assetProvider screenScale:(CGFloat)screenScale usingBounds:(BOOL)useBounds; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMImageUtils.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMImageUtils.h index 37a833d79d1e..a8fd0c82c688 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMImageUtils.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMImageUtils.h @@ -2,16 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@import Flutter; @import GoogleMaps; +@import UIKit; +#import "FGMAssetProvider.h" #import "google_maps_flutter_pigeon_messages.g.h" NS_ASSUME_NONNULL_BEGIN /// Creates a UIImage from Pigeon bitmap. UIImage *_Nullable FGMIconFromBitmap(FGMPlatformBitmap *platformBitmap, - NSObject *registrar, + NSObject *assetProvider, CGFloat screenScale); /// Returns a BOOL indicating whether image is considered scalable with the given scale factor from /// size. diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMMapEventDelegate.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMMapEventDelegate.h new file mode 100644 index 000000000000..f93f1adef252 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FGMMapEventDelegate.h @@ -0,0 +1,67 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +@import Foundation; + +#import "google_maps_flutter_pigeon_messages.g.h" + +NS_ASSUME_NONNULL_BEGIN + +/// Delegate for map event notifications. +/// +/// This is abstraction of the map event portions of FGMMapsCallbackApi, to +/// avoid coupling all the individual controllers to the Pigeon implementation +/// of event handling, and to allow for mocks/fakes in unit tests. +@protocol FGMMapEventDelegate + +/// Called when the map camera starts moving. +- (void)didStartCameraMove; + +/// Called when the map camera moves. +- (void)didMoveCameraToPosition:(FGMPlatformCameraPosition *)cameraPosition; + +/// Called when the map camera stops moving. +- (void)didIdleCamera; + +/// Called when the map, not a specifc map object, is tapped. +- (void)didTapAtPosition:(FGMPlatformLatLng *)position; + +/// Called when the map, not a specifc map object, is long pressed. +- (void)didLongPressAtPosition:(FGMPlatformLatLng *)position; + +/// Called when a marker is tapped. +- (void)didTapMarkerWithIdentifier:(NSString *)markerId; + +/// Called when a marker drag starts. +- (void)didStartDragForMarkerWithIdentifier:(NSString *)markerId + atPosition:(FGMPlatformLatLng *)position; + +/// Called when a marker drag updates. +- (void)didDragMarkerWithIdentifier:(NSString *)markerId atPosition:(FGMPlatformLatLng *)position; + +/// Called when a marker drag ends. +- (void)didEndDragForMarkerWithIdentifier:(NSString *)markerId + atPosition:(FGMPlatformLatLng *)position; + +/// Called when a marker's info window is tapped. +- (void)didTapInfoWindowOfMarkerWithIdentifier:(NSString *)markerId; + +/// Called when a circle is tapped. +- (void)didTapCircleWithIdentifier:(NSString *)circleId; + +/// Called when a marker cluster is tapped. +- (void)didTapCluster:(FGMPlatformCluster *)cluster; + +/// Called when a polygon is tapped. +- (void)didTapPolygonWithIdentifier:(NSString *)polygonId; + +/// Called when a polyline is tapped. +- (void)didTapPolylineWithIdentifier:(NSString *)polylineId; + +/// Called when a ground overlay is tapped. +- (void)didTapGroundOverlayWithIdentifier:(NSString *)groundOverlayId; + +@end + +NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FLTGoogleMapHeatmapController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FLTGoogleMapHeatmapController.h index edba379ac0e3..93c2aacf5e57 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FLTGoogleMapHeatmapController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FLTGoogleMapHeatmapController.h @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@import Flutter; @import GoogleMaps; @import GoogleMapsUtils; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FLTGoogleMapTileOverlayController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FLTGoogleMapTileOverlayController.h index 5c1b6e5418e8..b4c707e6d0b4 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FLTGoogleMapTileOverlayController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/FLTGoogleMapTileOverlayController.h @@ -9,6 +9,17 @@ NS_ASSUME_NONNULL_BEGIN +/// Protocol for requesting tiles from the Dart side. +@protocol FGMTileProviderDelegate +- (void)tileWithOverlayIdentifier:(NSString *)tileOverlayId + location:(FGMPlatformPoint *)location + zoom:(NSInteger)zoom + completion:(void (^)(FGMPlatformTile *_Nullable, + FlutterError *_Nullable))completion; +@end + +#pragma mark - + @interface FLTGoogleMapTileOverlayController : NSObject /// The layer managed by this controller instance. @property(readonly, nonatomic) GMSTileLayer *layer; @@ -23,13 +34,12 @@ NS_ASSUME_NONNULL_BEGIN @interface FLTTileProviderController : GMSTileLayer @property(copy, nonatomic, readonly) NSString *tileOverlayIdentifier; - (instancetype)initWithTileOverlayIdentifier:(NSString *)identifier - callbackHandler:(FGMMapsCallbackApi *)callbackHandler; + tileProvider:(NSObject *)tileProvider; @end @interface FLTTileOverlaysController : NSObject - (instancetype)initWithMapView:(GMSMapView *)mapView - callbackHandler:(FGMMapsCallbackApi *)callbackHandler - registrar:(NSObject *)registrar; + tileProvider:(NSObject *)tileProvider; - (void)addTileOverlays:(NSArray *)tileOverlaysToAdd; - (void)changeTileOverlays:(NSArray *)tileOverlaysToChange; - (void)removeTileOverlayWithIdentifiers:(NSArray *)identifiers; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapCircleController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapCircleController.h index 0cb21d926f6a..ac4347551135 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapCircleController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapCircleController.h @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@import Flutter; @import GoogleMaps; +#import "FGMMapEventDelegate.h" #import "google_maps_flutter_pigeon_messages.g.h" NS_ASSUME_NONNULL_BEGIN @@ -18,8 +18,7 @@ NS_ASSUME_NONNULL_BEGIN @interface FLTCirclesController : NSObject - (instancetype)initWithMapView:(GMSMapView *)mapView - callbackHandler:(FGMMapsCallbackApi *)callbackHandler - registrar:(NSObject *)registrar; + eventDelegate:(NSObject *)eventDelegate; - (void)addCircles:(NSArray *)circlesToAdd; - (void)changeCircles:(NSArray *)circlesToChange; - (void)removeCirclesWithIdentifiers:(NSArray *)identifiers; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapController_Test.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapController_Test.h index 219a1ac246e9..bbb61545cc0c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapController_Test.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapController_Test.h @@ -5,6 +5,7 @@ @import Flutter; @import GoogleMaps; +#import "FGMAssetProvider.h" #import "FGMCATransactionWrapper.h" #import "GoogleMapController.h" @@ -45,11 +46,13 @@ NS_ASSUME_NONNULL_BEGIN /// @param mapView A map view that will be displayed by the controller /// @param viewId A unique identifier for the controller. /// @param creationParameters Parameters for initialising the map view. -/// @param registrar The plugin registrar passed from Flutter. +/// @param assetProvider The asset provider to use for looking up assets. +/// @param binaryMessenger The binary messenger to use for sending messages to Dart. - (instancetype)initWithMapView:(GMSMapView *)mapView viewIdentifier:(int64_t)viewId creationParameters:(FGMPlatformMapViewCreationParams *)creationParameters - registrar:(NSObject *)registrar; + assetProvider:(NSObject *)assetProvider + binaryMessenger:(NSObject *)binaryMessenger; // The main Pigeon API implementation. @property(nonatomic, strong, readonly) FGMMapCallHandler *callHandler; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapMarkerController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapMarkerController.h index dcebcb1e2982..57797346639e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapMarkerController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapMarkerController.h @@ -5,12 +5,15 @@ @import Flutter; @import GoogleMaps; +#import "FGMAssetProvider.h" #import "FGMClusterManagersController.h" -#import "GoogleMapController.h" +#import "FGMMapEventDelegate.h" #import "google_maps_flutter_pigeon_messages.g.h" NS_ASSUME_NONNULL_BEGIN +#pragma mark - + // Defines marker controllable by Flutter. @interface FLTGoogleMapMarkerController : NSObject @property(assign, nonatomic, readonly) BOOL consumeTapEvents; @@ -25,9 +28,9 @@ NS_ASSUME_NONNULL_BEGIN @interface FLTMarkersController : NSObject - (instancetype)initWithMapView:(GMSMapView *)mapView - callbackHandler:(FGMMapsCallbackApi *)callbackHandler + eventDelegate:(NSObject *)eventDelegate clusterManagersController:(nullable FGMClusterManagersController *)clusterManagersController - registrar:(NSObject *)registrar; + assetProvider:(NSObject *)assetProvider; - (void)addMarkers:(NSArray *)markersToAdd; - (void)changeMarkers:(NSArray *)markersToChange; - (void)removeMarkersWithIdentifiers:(NSArray *)identifiers; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapMarkerController_Test.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapMarkerController_Test.h index f6ff32e791e1..d7a9c1578432 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapMarkerController_Test.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapMarkerController_Test.h @@ -16,7 +16,7 @@ + (void)updateMarker:(GMSMarker *)marker fromPlatformMarker:(FGMPlatformMarker *)platformMarker withMapView:(GMSMapView *)mapView - registrar:(NSObject *)registrar + assetProvider:(NSObject *)assetProvider screenScale:(CGFloat)screenScale usingOpacityForVisibility:(BOOL)useOpacityForVisibility; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapPolygonController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapPolygonController.h index b26cf2416c5f..a222ca6a4eb0 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapPolygonController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapPolygonController.h @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@import Flutter; @import GoogleMaps; +#import "FGMMapEventDelegate.h" #import "google_maps_flutter_pigeon_messages.g.h" // Defines polygon controllable by Flutter. @@ -17,8 +17,7 @@ @interface FLTPolygonsController : NSObject - (instancetype)initWithMapView:(GMSMapView *)mapView - callbackHandler:(FGMMapsCallbackApi *)callbackHandler - registrar:(NSObject *)registrar; + eventDelegate:(NSObject *)eventDelegate; - (void)addPolygons:(NSArray *)polygonsToAdd; - (void)changePolygons:(NSArray *)polygonsToChange; - (void)removePolygonWithIdentifiers:(NSArray *)identifiers; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapPolylineController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapPolylineController.h index 5505ec54019b..ccf37dae9a35 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapPolylineController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/google_maps_flutter_ios/Sources/google_maps_flutter_ios/include/google_maps_flutter_ios/GoogleMapPolylineController.h @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@import Flutter; @import GoogleMaps; +#import "FGMMapEventDelegate.h" #import "google_maps_flutter_pigeon_messages.g.h" // Defines polyline controllable by Flutter. @@ -17,8 +17,7 @@ @interface FLTPolylinesController : NSObject - (instancetype)initWithMapView:(GMSMapView *)mapView - callbackHandler:(FGMMapsCallbackApi *)callbackHandler - registrar:(NSObject *)registrar; + eventDelegate:(NSObject *)eventDelegate; - (void)addPolylines:(NSArray *)polylinesToAdd; - (void)changePolylines:(NSArray *)polylinesToChange; - (void)removePolylineWithIdentifiers:(NSArray *)identifiers; diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_ios/pubspec.yaml index d2b6449e77e3..f971ae9b5678 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_ios/pubspec.yaml @@ -2,7 +2,7 @@ name: google_maps_flutter_ios description: iOS implementation of the google_maps_flutter plugin. repository: https://github.com/flutter/packages/tree/main/packages/google_maps_flutter/google_maps_flutter_ios issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 -version: 2.17.0 +version: 2.17.1 environment: sdk: ^3.9.0