From c07efbf288e4ac7b6a258165f800732b9dbb29dc Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Fri, 14 Jun 2024 14:12:43 -0400 Subject: [PATCH 1/5] Initial API definition --- .../ios/Classes/messages.g.h | 77 ++++ .../ios/Classes/messages.g.m | 386 ++++++++++++++++ .../lib/src/messages.g.dart | 413 ++++++++++++++++++ .../pigeons/copyright.txt | 3 + .../pigeons/messages.dart | 53 +++ .../google_maps_flutter_ios/pubspec.yaml | 1 + 6 files changed, 933 insertions(+) create mode 100644 packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/messages.g.h create mode 100644 packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/messages.g.m create mode 100644 packages/google_maps_flutter/google_maps_flutter_ios/lib/src/messages.g.dart create mode 100644 packages/google_maps_flutter/google_maps_flutter_ios/pigeons/copyright.txt create mode 100644 packages/google_maps_flutter/google_maps_flutter_ios/pigeons/messages.dart diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/messages.g.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/messages.g.h new file mode 100644 index 00000000000..80a9279add8 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/messages.g.h @@ -0,0 +1,77 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// Autogenerated from Pigeon (v20.0.1), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +#import + +@protocol FlutterBinaryMessenger; +@protocol FlutterMessageCodec; +@class FlutterError; +@class FlutterStandardTypedData; + +NS_ASSUME_NONNULL_BEGIN + +@class FGMPlatformTileLayer; +@class FGMPlatformZoomRange; + +/// Pigeon equivalent of GMSTileLayer properties. +@interface FGMPlatformTileLayer : NSObject +/// `init` unavailable to enforce nonnull fields, see the `make` class method. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)makeWithVisible:(BOOL)visible + fadeIn:(BOOL)fadeIn + opacity:(double)opacity + zIndex:(NSInteger)zIndex; +@property(nonatomic, assign) BOOL visible; +@property(nonatomic, assign) BOOL fadeIn; +@property(nonatomic, assign) double opacity; +@property(nonatomic, assign) NSInteger zIndex; +@end + +/// Possible outcomes of launching a URL. +@interface FGMPlatformZoomRange : NSObject +/// `init` unavailable to enforce nonnull fields, see the `make` class method. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)makeWithMin:(double)min max:(double)max; +@property(nonatomic, assign) double min; +@property(nonatomic, assign) double max; +@end + +/// The codec used by all APIs. +NSObject *FGMGetMessagesCodec(void); + +/// Inspector API only intended for use in integration tests. +@protocol FGMMapsInspectorApi +/// @return `nil` only when `error != nil`. +- (nullable NSNumber *)areBuildingsEnabledWithError:(FlutterError *_Nullable *_Nonnull)error; +/// @return `nil` only when `error != nil`. +- (nullable NSNumber *)areRotateGesturesEnabledWithError:(FlutterError *_Nullable *_Nonnull)error; +/// @return `nil` only when `error != nil`. +- (nullable NSNumber *)areScrollGesturesEnabledWithError:(FlutterError *_Nullable *_Nonnull)error; +/// @return `nil` only when `error != nil`. +- (nullable NSNumber *)areTiltGesturesEnabledWithError:(FlutterError *_Nullable *_Nonnull)error; +/// @return `nil` only when `error != nil`. +- (nullable NSNumber *)areZoomGesturesEnabledWithError:(FlutterError *_Nullable *_Nonnull)error; +/// @return `nil` only when `error != nil`. +- (nullable NSNumber *)isCompassEnabledWithError:(FlutterError *_Nullable *_Nonnull)error; +/// @return `nil` only when `error != nil`. +- (nullable NSNumber *)isMyLocationButtonEnabledWithError:(FlutterError *_Nullable *_Nonnull)error; +/// @return `nil` only when `error != nil`. +- (nullable NSNumber *)isTrafficEnabledWithError:(FlutterError *_Nullable *_Nonnull)error; +- (nullable FGMPlatformTileLayer *) + getInfoForTileOverlayWithIdentifier:(NSString *)tileOverlayId + error:(FlutterError *_Nullable *_Nonnull)error; +/// @return `nil` only when `error != nil`. +- (nullable FGMPlatformZoomRange *)zoomRange:(FlutterError *_Nullable *_Nonnull)error; +@end + +extern void SetUpFGMMapsInspectorApi(id binaryMessenger, + NSObject *_Nullable api); + +extern void SetUpFGMMapsInspectorApiWithSuffix(id binaryMessenger, + NSObject *_Nullable api, + NSString *messageChannelSuffix); + +NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/messages.g.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/messages.g.m new file mode 100644 index 00000000000..eb7ab77ffac --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/messages.g.m @@ -0,0 +1,386 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// Autogenerated from Pigeon (v20.0.1), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +#import "messages.g.h" + +#if TARGET_OS_OSX +#import +#else +#import +#endif + +#if !__has_feature(objc_arc) +#error File requires ARC to be enabled. +#endif + +static NSArray *wrapResult(id result, FlutterError *error) { + if (error) { + return @[ + error.code ?: [NSNull null], error.message ?: [NSNull null], error.details ?: [NSNull null] + ]; + } + return @[ result ?: [NSNull null] ]; +} + +static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) { + id result = array[key]; + return (result == [NSNull null]) ? nil : result; +} + +@interface FGMPlatformTileLayer () ++ (FGMPlatformTileLayer *)fromList:(NSArray *)list; ++ (nullable FGMPlatformTileLayer *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@interface FGMPlatformZoomRange () ++ (FGMPlatformZoomRange *)fromList:(NSArray *)list; ++ (nullable FGMPlatformZoomRange *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + +@implementation FGMPlatformTileLayer ++ (instancetype)makeWithVisible:(BOOL)visible + fadeIn:(BOOL)fadeIn + opacity:(double)opacity + zIndex:(NSInteger)zIndex { + FGMPlatformTileLayer *pigeonResult = [[FGMPlatformTileLayer alloc] init]; + pigeonResult.visible = visible; + pigeonResult.fadeIn = fadeIn; + pigeonResult.opacity = opacity; + pigeonResult.zIndex = zIndex; + return pigeonResult; +} ++ (FGMPlatformTileLayer *)fromList:(NSArray *)list { + FGMPlatformTileLayer *pigeonResult = [[FGMPlatformTileLayer alloc] init]; + pigeonResult.visible = [GetNullableObjectAtIndex(list, 0) boolValue]; + pigeonResult.fadeIn = [GetNullableObjectAtIndex(list, 1) boolValue]; + pigeonResult.opacity = [GetNullableObjectAtIndex(list, 2) doubleValue]; + pigeonResult.zIndex = [GetNullableObjectAtIndex(list, 3) integerValue]; + return pigeonResult; +} ++ (nullable FGMPlatformTileLayer *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformTileLayer fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + @(self.visible), + @(self.fadeIn), + @(self.opacity), + @(self.zIndex), + ]; +} +@end + +@implementation FGMPlatformZoomRange ++ (instancetype)makeWithMin:(double)min max:(double)max { + FGMPlatformZoomRange *pigeonResult = [[FGMPlatformZoomRange alloc] init]; + pigeonResult.min = min; + pigeonResult.max = max; + return pigeonResult; +} ++ (FGMPlatformZoomRange *)fromList:(NSArray *)list { + FGMPlatformZoomRange *pigeonResult = [[FGMPlatformZoomRange alloc] init]; + pigeonResult.min = [GetNullableObjectAtIndex(list, 0) doubleValue]; + pigeonResult.max = [GetNullableObjectAtIndex(list, 1) doubleValue]; + return pigeonResult; +} ++ (nullable FGMPlatformZoomRange *)nullableFromList:(NSArray *)list { + return (list) ? [FGMPlatformZoomRange fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + @(self.min), + @(self.max), + ]; +} +@end + +@interface FGMMessagesPigeonCodecReader : FlutterStandardReader +@end +@implementation FGMMessagesPigeonCodecReader +- (nullable id)readValueOfType:(UInt8)type { + switch (type) { + case 129: + return [FGMPlatformTileLayer fromList:[self readValue]]; + case 130: + return [FGMPlatformZoomRange fromList:[self readValue]]; + default: + return [super readValueOfType:type]; + } +} +@end + +@interface FGMMessagesPigeonCodecWriter : FlutterStandardWriter +@end +@implementation FGMMessagesPigeonCodecWriter +- (void)writeValue:(id)value { + if ([value isKindOfClass:[FGMPlatformTileLayer class]]) { + [self writeByte:129]; + [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FGMPlatformZoomRange class]]) { + [self writeByte:130]; + [self writeValue:[value toList]]; + } else { + [super writeValue:value]; + } +} +@end + +@interface FGMMessagesPigeonCodecReaderWriter : FlutterStandardReaderWriter +@end +@implementation FGMMessagesPigeonCodecReaderWriter +- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data { + return [[FGMMessagesPigeonCodecWriter alloc] initWithData:data]; +} +- (FlutterStandardReader *)readerWithData:(NSData *)data { + return [[FGMMessagesPigeonCodecReader alloc] initWithData:data]; +} +@end + +NSObject *FGMGetMessagesCodec(void) { + static FlutterStandardMessageCodec *sSharedObject = nil; + static dispatch_once_t sPred = 0; + dispatch_once(&sPred, ^{ + FGMMessagesPigeonCodecReaderWriter *readerWriter = + [[FGMMessagesPigeonCodecReaderWriter alloc] init]; + sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter]; + }); + return sSharedObject; +} +void SetUpFGMMapsInspectorApi(id binaryMessenger, + NSObject *api) { + SetUpFGMMapsInspectorApiWithSuffix(binaryMessenger, api, @""); +} + +void SetUpFGMMapsInspectorApiWithSuffix(id binaryMessenger, + NSObject *api, + NSString *messageChannelSuffix) { + messageChannelSuffix = messageChannelSuffix.length > 0 + ? [NSString stringWithFormat:@".%@", messageChannelSuffix] + : @""; + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsInspectorApi.areBuildingsEnabled", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(areBuildingsEnabledWithError:)], + @"FGMMapsInspectorApi api (%@) doesn't respond to " + @"@selector(areBuildingsEnabledWithError:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + FlutterError *error; + NSNumber *output = [api areBuildingsEnabledWithError:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsInspectorApi.areRotateGesturesEnabled", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(areRotateGesturesEnabledWithError:)], + @"FGMMapsInspectorApi api (%@) doesn't respond to " + @"@selector(areRotateGesturesEnabledWithError:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + FlutterError *error; + NSNumber *output = [api areRotateGesturesEnabledWithError:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsInspectorApi.areScrollGesturesEnabled", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(areScrollGesturesEnabledWithError:)], + @"FGMMapsInspectorApi api (%@) doesn't respond to " + @"@selector(areScrollGesturesEnabledWithError:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + FlutterError *error; + NSNumber *output = [api areScrollGesturesEnabledWithError:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsInspectorApi.areTiltGesturesEnabled", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(areTiltGesturesEnabledWithError:)], + @"FGMMapsInspectorApi api (%@) doesn't respond to " + @"@selector(areTiltGesturesEnabledWithError:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + FlutterError *error; + NSNumber *output = [api areTiltGesturesEnabledWithError:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsInspectorApi.areZoomGesturesEnabled", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(areZoomGesturesEnabledWithError:)], + @"FGMMapsInspectorApi api (%@) doesn't respond to " + @"@selector(areZoomGesturesEnabledWithError:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + FlutterError *error; + NSNumber *output = [api areZoomGesturesEnabledWithError:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsInspectorApi.isCompassEnabled", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert( + [api respondsToSelector:@selector(isCompassEnabledWithError:)], + @"FGMMapsInspectorApi api (%@) doesn't respond to @selector(isCompassEnabledWithError:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + FlutterError *error; + NSNumber *output = [api isCompassEnabledWithError:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsInspectorApi.isMyLocationButtonEnabled", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(isMyLocationButtonEnabledWithError:)], + @"FGMMapsInspectorApi api (%@) doesn't respond to " + @"@selector(isMyLocationButtonEnabledWithError:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + FlutterError *error; + NSNumber *output = [api isMyLocationButtonEnabledWithError:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsInspectorApi.isTrafficEnabled", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert( + [api respondsToSelector:@selector(isTrafficEnabledWithError:)], + @"FGMMapsInspectorApi api (%@) doesn't respond to @selector(isTrafficEnabledWithError:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + FlutterError *error; + NSNumber *output = [api isTrafficEnabledWithError:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsInspectorApi.getTileOverlayInfo", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(getInfoForTileOverlayWithIdentifier:error:)], + @"FGMMapsInspectorApi api (%@) doesn't respond to " + @"@selector(getInfoForTileOverlayWithIdentifier:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSString *arg_tileOverlayId = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + FGMPlatformTileLayer *output = [api getInfoForTileOverlayWithIdentifier:arg_tileOverlayId + error:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:[NSString stringWithFormat:@"%@%@", + @"dev.flutter.pigeon.google_maps_flutter_ios." + @"MapsInspectorApi.getZoomRange", + messageChannelSuffix] + binaryMessenger:binaryMessenger + codec:FGMGetMessagesCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(zoomRange:)], + @"FGMMapsInspectorApi api (%@) doesn't respond to @selector(zoomRange:)", api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + FlutterError *error; + FGMPlatformZoomRange *output = [api zoomRange:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/messages.g.dart b/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/messages.g.dart new file mode 100644 index 00000000000..0f54169c937 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/messages.g.dart @@ -0,0 +1,413 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// Autogenerated from Pigeon (v20.0.1), do not edit directly. +// See also: https://pub.dev/packages/pigeon +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; + +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; + +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + +/// Pigeon equivalent of GMSTileLayer properties. +class PlatformTileLayer { + PlatformTileLayer({ + required this.visible, + required this.fadeIn, + required this.opacity, + required this.zIndex, + }); + + bool visible; + + bool fadeIn; + + double opacity; + + int zIndex; + + Object encode() { + return [ + visible, + fadeIn, + opacity, + zIndex, + ]; + } + + static PlatformTileLayer decode(Object result) { + result as List; + return PlatformTileLayer( + visible: result[0]! as bool, + fadeIn: result[1]! as bool, + opacity: result[2]! as double, + zIndex: result[3]! as int, + ); + } +} + +/// Possible outcomes of launching a URL. +class PlatformZoomRange { + PlatformZoomRange({ + required this.min, + required this.max, + }); + + double min; + + double max; + + Object encode() { + return [ + min, + max, + ]; + } + + static PlatformZoomRange decode(Object result) { + result as List; + return PlatformZoomRange( + min: result[0]! as double, + max: result[1]! as double, + ); + } +} + +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is PlatformTileLayer) { + buffer.putUint8(129); + writeValue(buffer, value.encode()); + } else if (value is PlatformZoomRange) { + buffer.putUint8(130); + writeValue(buffer, value.encode()); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 129: + return PlatformTileLayer.decode(readValue(buffer)!); + case 130: + return PlatformZoomRange.decode(readValue(buffer)!); + default: + return super.readValueOfType(type, buffer); + } + } +} + +/// Inspector API only intended for use in integration tests. +class MapsInspectorApi { + /// Constructor for [MapsInspectorApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + MapsInspectorApi( + {BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : __pigeon_binaryMessenger = binaryMessenger, + __pigeon_messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? __pigeon_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String __pigeon_messageChannelSuffix; + + Future areBuildingsEnabled() async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsInspectorApi.areBuildingsEnabled$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send(null) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as bool?)!; + } + } + + Future areRotateGesturesEnabled() async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsInspectorApi.areRotateGesturesEnabled$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send(null) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as bool?)!; + } + } + + Future areScrollGesturesEnabled() async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsInspectorApi.areScrollGesturesEnabled$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send(null) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as bool?)!; + } + } + + Future areTiltGesturesEnabled() async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsInspectorApi.areTiltGesturesEnabled$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send(null) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as bool?)!; + } + } + + Future areZoomGesturesEnabled() async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsInspectorApi.areZoomGesturesEnabled$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send(null) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as bool?)!; + } + } + + Future isCompassEnabled() async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsInspectorApi.isCompassEnabled$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send(null) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as bool?)!; + } + } + + Future isMyLocationButtonEnabled() async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsInspectorApi.isMyLocationButtonEnabled$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send(null) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as bool?)!; + } + } + + Future isTrafficEnabled() async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsInspectorApi.isTrafficEnabled$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send(null) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as bool?)!; + } + } + + Future getTileOverlayInfo(String tileOverlayId) async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsInspectorApi.getTileOverlayInfo$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([tileOverlayId]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as PlatformTileLayer?); + } + } + + Future getZoomRange() async { + final String __pigeon_channelName = + 'dev.flutter.pigeon.google_maps_flutter_ios.MapsInspectorApi.getZoomRange$__pigeon_messageChannelSuffix'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send(null) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as PlatformZoomRange?)!; + } + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/pigeons/copyright.txt b/packages/google_maps_flutter/google_maps_flutter_ios/pigeons/copyright.txt new file mode 100644 index 00000000000..1236b63caf3 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/pigeons/copyright.txt @@ -0,0 +1,3 @@ +Copyright 2013 The Flutter Authors. All rights reserved. +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/pigeons/messages.dart b/packages/google_maps_flutter/google_maps_flutter_ios/pigeons/messages.dart new file mode 100644 index 00000000000..5e394763400 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_ios/pigeons/messages.dart @@ -0,0 +1,53 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:pigeon/pigeon.dart'; + +@ConfigurePigeon(PigeonOptions( + dartOut: 'lib/src/messages.g.dart', + objcHeaderOut: 'ios/Classes/messages.g.h', + objcSourceOut: 'ios/Classes/messages.g.m', + objcOptions: ObjcOptions(prefix: 'FGM'), + copyrightHeader: 'pigeons/copyright.txt', +)) + +/// Pigeon equivalent of GMSTileLayer properties. +class PlatformTileLayer { + PlatformTileLayer({ + required this.visible, + required this.fadeIn, + required this.opacity, + required this.zIndex, + }); + + final bool visible; + final bool fadeIn; + final double opacity; + final int zIndex; +} + +/// Possible outcomes of launching a URL. +class PlatformZoomRange { + PlatformZoomRange({required this.min, required this.max}); + + final double min; + final double max; +} + +/// Inspector API only intended for use in integration tests. +@HostApi() +abstract class MapsInspectorApi { + bool areBuildingsEnabled(); + bool areRotateGesturesEnabled(); + bool areScrollGesturesEnabled(); + bool areTiltGesturesEnabled(); + bool areZoomGesturesEnabled(); + bool isCompassEnabled(); + bool isMyLocationButtonEnabled(); + bool isTrafficEnabled(); + @ObjCSelector('getInfoForTileOverlayWithIdentifier:') + PlatformTileLayer? getTileOverlayInfo(String tileOverlayId); + @ObjCSelector('zoomRange') + PlatformZoomRange getZoomRange(); +} 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 e8411514629..15807e3c25e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_ios/pubspec.yaml @@ -26,6 +26,7 @@ dev_dependencies: async: ^2.5.0 flutter_test: sdk: flutter + pigeon: ^20.0.1 plugin_platform_interface: ^2.1.7 topics: From 48dc1ae3634e2f37d33ea9327b8a2fbcde7e8135 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Fri, 14 Jun 2024 16:33:45 -0400 Subject: [PATCH 2/5] Convert inspector to Pigeon --- .../FLTGoogleMapTileOverlayController.h | 6 +- .../FLTGoogleMapTileOverlayController.m | 21 +--- .../ios/Classes/GoogleMapController.h | 4 +- .../ios/Classes/GoogleMapController.m | 97 ++++++++++++------- .../lib/src/google_map_inspector_ios.dart | 73 ++++++-------- .../lib/src/google_maps_flutter_ios.dart | 5 +- 6 files changed, 106 insertions(+), 100 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.h index 5dcc66594f1..23f00c9af15 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.h @@ -8,12 +8,14 @@ NS_ASSUME_NONNULL_BEGIN @interface FLTGoogleMapTileOverlayController : NSObject +/// The layer managed by this controller instance. +@property(readonly, nonatomic) GMSTileLayer *layer; + - (instancetype)initWithTileLayer:(GMSTileLayer *)tileLayer mapView:(GMSMapView *)mapView options:(NSDictionary *)optionsData; - (void)removeTileOverlay; - (void)clearTileCache; -- (NSDictionary *)getTileOverlayInfo; @end @interface FLTTileProviderController : GMSTileLayer @@ -30,7 +32,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)changeTileOverlays:(NSArray *)tileOverlaysToChange; - (void)removeTileOverlayWithIdentifiers:(NSArray *)identifiers; - (void)clearTileCacheWithIdentifier:(NSString *)identifier; -- (nullable NSDictionary *)tileOverlayInfoWithIdentifier:(NSString *)identifier; +- (nullable FLTGoogleMapTileOverlayController *)tileOverlayWithIdentifier:(NSString *)identifier; @end NS_ASSUME_NONNULL_END diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.m index 73eab6c1ead..4bf440ab444 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.m @@ -34,17 +34,6 @@ - (void)clearTileCache { [self.layer clearTileCache]; } -- (NSDictionary *)getTileOverlayInfo { - NSMutableDictionary *info = [[NSMutableDictionary alloc] init]; - BOOL visible = self.layer.map != nil; - info[@"visible"] = @(visible); - info[@"fadeIn"] = @(self.layer.fadeIn); - float transparency = 1.0 - self.layer.opacity; - info[@"transparency"] = @(transparency); - info[@"zIndex"] = @(self.layer.zIndex); - return info; -} - - (void)setFadeIn:(BOOL)fadeIn { self.layer.fadeIn = fadeIn; } @@ -182,7 +171,8 @@ - (void)requestTileForX:(NSUInteger)x @interface FLTTileOverlaysController () -@property(strong, nonatomic) NSMutableDictionary *tileOverlayIdentifierToController; +@property(strong, nonatomic) NSMutableDictionary + *tileOverlayIdentifierToController; @property(strong, nonatomic) FlutterMethodChannel *methodChannel; @property(weak, nonatomic) GMSMapView *mapView; @@ -248,11 +238,8 @@ - (void)clearTileCacheWithIdentifier:(NSString *)identifier { [controller clearTileCache]; } -- (nullable NSDictionary *)tileOverlayInfoWithIdentifier:(NSString *)identifier { - if (self.tileOverlayIdentifierToController[identifier] == nil) { - return nil; - } - return [self.tileOverlayIdentifierToController[identifier] getTileOverlayInfo]; +- (nullable FLTGoogleMapTileOverlayController *)tileOverlayWithIdentifier:(NSString *)identifier { + return self.tileOverlayIdentifierToController[identifier]; } + (NSString *)identifierForTileOverlay:(NSDictionary *)tileOverlay { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.h index d1069ac16b3..9e723c0ef25 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.h @@ -8,11 +8,13 @@ #import "GoogleMapMarkerController.h" #import "GoogleMapPolygonController.h" #import "GoogleMapPolylineController.h" +#import "messages.g.h" NS_ASSUME_NONNULL_BEGIN // Defines map overlay controllable from Flutter. -@interface FLTGoogleMapController : NSObject +@interface FLTGoogleMapController + : NSObject - (instancetype)initWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(nullable id)args diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m index 4c747f3eeba..ca019624bb8 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m @@ -5,6 +5,7 @@ #import "GoogleMapController.h" #import "FLTGoogleMapJSONConversions.h" #import "FLTGoogleMapTileOverlayController.h" +#import "messages.g.h" #pragma mark - Conversion of JSON-like values sent via platform channels. Forward declarations. @@ -356,41 +357,8 @@ - (void)onMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { id rawTileOverlayId = call.arguments[@"tileOverlayId"]; [self.tileOverlaysController clearTileCacheWithIdentifier:rawTileOverlayId]; result(nil); - } else if ([call.method isEqualToString:@"map#isCompassEnabled"]) { - NSNumber *isCompassEnabled = @(self.mapView.settings.compassButton); - result(isCompassEnabled); - } else if ([call.method isEqualToString:@"map#isMapToolbarEnabled"]) { - NSNumber *isMapToolbarEnabled = @NO; - result(isMapToolbarEnabled); - } else if ([call.method isEqualToString:@"map#getMinMaxZoomLevels"]) { - NSArray *zoomLevels = @[ @(self.mapView.minZoom), @(self.mapView.maxZoom) ]; - result(zoomLevels); } else if ([call.method isEqualToString:@"map#getZoomLevel"]) { result(@(self.mapView.camera.zoom)); - } else if ([call.method isEqualToString:@"map#isZoomGesturesEnabled"]) { - NSNumber *isZoomGesturesEnabled = @(self.mapView.settings.zoomGestures); - result(isZoomGesturesEnabled); - } else if ([call.method isEqualToString:@"map#isZoomControlsEnabled"]) { - NSNumber *isZoomControlsEnabled = @NO; - result(isZoomControlsEnabled); - } else if ([call.method isEqualToString:@"map#isTiltGesturesEnabled"]) { - NSNumber *isTiltGesturesEnabled = @(self.mapView.settings.tiltGestures); - result(isTiltGesturesEnabled); - } else if ([call.method isEqualToString:@"map#isRotateGesturesEnabled"]) { - NSNumber *isRotateGesturesEnabled = @(self.mapView.settings.rotateGestures); - result(isRotateGesturesEnabled); - } else if ([call.method isEqualToString:@"map#isScrollGesturesEnabled"]) { - NSNumber *isScrollGesturesEnabled = @(self.mapView.settings.scrollGestures); - result(isScrollGesturesEnabled); - } else if ([call.method isEqualToString:@"map#isMyLocationButtonEnabled"]) { - NSNumber *isMyLocationButtonEnabled = @(self.mapView.settings.myLocationButton); - result(isMyLocationButtonEnabled); - } else if ([call.method isEqualToString:@"map#isTrafficEnabled"]) { - NSNumber *isTrafficEnabled = @(self.mapView.trafficEnabled); - result(isTrafficEnabled); - } else if ([call.method isEqualToString:@"map#isBuildingsEnabled"]) { - NSNumber *isBuildingsEnabled = @(self.mapView.buildingsEnabled); - result(isBuildingsEnabled); } else if ([call.method isEqualToString:@"map#setStyle"]) { id mapStyle = [call arguments]; self.styleError = [self setMapStyle:(mapStyle == [NSNull null] ? nil : mapStyle)]; @@ -401,9 +369,6 @@ - (void)onMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { } } else if ([call.method isEqualToString:@"map#getStyleError"]) { result(self.styleError); - } else if ([call.method isEqualToString:@"map#getTileOverlayInfo"]) { - NSString *rawTileOverlayId = call.arguments[@"tileOverlayId"]; - result([self.tileOverlaysController tileOverlayInfoWithIdentifier:rawTileOverlayId]); } else { result(FlutterMethodNotImplemented); } @@ -658,4 +623,64 @@ - (void)interpretMapOptions:(NSDictionary *)data { } } +#pragma mark GMSMapsInspectorApi + +- (nullable NSNumber *)areBuildingsEnabledWithError: + (FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return @(self.mapView.buildingsEnabled); +} + +- (nullable NSNumber *)areRotateGesturesEnabledWithError: + (FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return @(self.mapView.settings.rotateGestures); +} + +- (nullable NSNumber *)areScrollGesturesEnabledWithError: + (FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return @(self.mapView.settings.scrollGestures); +} + +- (nullable NSNumber *)areTiltGesturesEnabledWithError: + (FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return @(self.mapView.settings.tiltGestures); +} + +- (nullable NSNumber *)areZoomGesturesEnabledWithError: + (FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return @(self.mapView.settings.zoomGestures); +} + +- (nullable FGMPlatformTileLayer *) + getInfoForTileOverlayWithIdentifier:(nonnull NSString *)tileOverlayId + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + GMSTileLayer *layer = [self.tileOverlaysController tileOverlayWithIdentifier:tileOverlayId].layer; + if (!layer) { + return nil; + } + return [FGMPlatformTileLayer makeWithVisible:(layer.map != nil) + fadeIn:layer.fadeIn + opacity:layer.opacity + zIndex:layer.zIndex]; +} + +- (nullable NSNumber *)isCompassEnabledWithError: + (FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return @(self.mapView.settings.compassButton); +} + +- (nullable NSNumber *)isMyLocationButtonEnabledWithError: + (FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return @(self.mapView.settings.myLocationButton); +} + +- (nullable NSNumber *)isTrafficEnabledWithError: + (FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return @(self.mapView.trafficEnabled); +} + +- (nullable FGMPlatformZoomRange *)zoomRange: + (FlutterError *_Nullable __autoreleasing *_Nonnull)error { + return [FGMPlatformZoomRange makeWithMin:self.mapView.minZoom max:self.mapView.maxZoom]; +} + @end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_map_inspector_ios.dart b/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_map_inspector_ios.dart index 8fae1a35e31..990505bcb13 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_map_inspector_ios.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_map_inspector_ios.dart @@ -3,111 +3,100 @@ // found in the LICENSE file. import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; +import 'messages.g.dart'; + /// An Android of implementation of [GoogleMapsInspectorPlatform]. @visibleForTesting class GoogleMapsInspectorIOS extends GoogleMapsInspectorPlatform { - /// Creates a method-channel-based inspector instance that gets the channel - /// for a given map ID from [channelProvider]. - GoogleMapsInspectorIOS(MethodChannel? Function(int mapId) channelProvider) - : _channelProvider = channelProvider; + /// Creates an inspector API instance for a given map ID from + /// [inspectorProvider]. + GoogleMapsInspectorIOS( + MapsInspectorApi? Function(int mapId) inspectorProvider) + : _inspectorProvider = inspectorProvider; - final MethodChannel? Function(int mapId) _channelProvider; + final MapsInspectorApi? Function(int mapId) _inspectorProvider; @override Future areBuildingsEnabled({required int mapId}) async { - return (await _channelProvider(mapId)! - .invokeMethod('map#isBuildingsEnabled'))!; + return _inspectorProvider(mapId)!.areBuildingsEnabled(); } @override Future areRotateGesturesEnabled({required int mapId}) async { - return (await _channelProvider(mapId)! - .invokeMethod('map#isRotateGesturesEnabled'))!; + return _inspectorProvider(mapId)!.areRotateGesturesEnabled(); } @override Future areScrollGesturesEnabled({required int mapId}) async { - return (await _channelProvider(mapId)! - .invokeMethod('map#isScrollGesturesEnabled'))!; + return _inspectorProvider(mapId)!.areScrollGesturesEnabled(); } @override Future areTiltGesturesEnabled({required int mapId}) async { - return (await _channelProvider(mapId)! - .invokeMethod('map#isTiltGesturesEnabled'))!; + return _inspectorProvider(mapId)!.areTiltGesturesEnabled(); } @override Future areZoomControlsEnabled({required int mapId}) async { - return (await _channelProvider(mapId)! - .invokeMethod('map#isZoomControlsEnabled'))!; + // Does not exist on iOS. + return false; } @override Future areZoomGesturesEnabled({required int mapId}) async { - return (await _channelProvider(mapId)! - .invokeMethod('map#isZoomGesturesEnabled'))!; + return _inspectorProvider(mapId)!.areZoomGesturesEnabled(); } @override Future getMinMaxZoomLevels({required int mapId}) async { - final List zoomLevels = (await _channelProvider(mapId)! - .invokeMethod>('map#getMinMaxZoomLevels'))! - .cast(); - return MinMaxZoomPreference(zoomLevels[0], zoomLevels[1]); + final PlatformZoomRange zoomLevels = + await _inspectorProvider(mapId)!.getZoomRange(); + return MinMaxZoomPreference(zoomLevels.min, zoomLevels.max); } @override Future getTileOverlayInfo(TileOverlayId tileOverlayId, {required int mapId}) async { - final Map? tileInfo = await _channelProvider(mapId)! - .invokeMapMethod( - 'map#getTileOverlayInfo', { - 'tileOverlayId': tileOverlayId.value, - }); + final PlatformTileLayer? tileInfo = await _inspectorProvider(mapId)! + .getTileOverlayInfo(tileOverlayId.value); if (tileInfo == null) { return null; } return TileOverlay( tileOverlayId: tileOverlayId, - fadeIn: tileInfo['fadeIn']! as bool, - transparency: tileInfo['transparency']! as double, - visible: tileInfo['visible']! as bool, - // Android and iOS return different types. - zIndex: (tileInfo['zIndex']! as num).toInt(), + fadeIn: tileInfo.fadeIn, + transparency: 1.0 - tileInfo.opacity, + visible: tileInfo.visible, + zIndex: tileInfo.zIndex, ); } @override Future isCompassEnabled({required int mapId}) async { - return (await _channelProvider(mapId)! - .invokeMethod('map#isCompassEnabled'))!; + return _inspectorProvider(mapId)!.isCompassEnabled(); } @override Future isLiteModeEnabled({required int mapId}) async { - return (await _channelProvider(mapId)! - .invokeMethod('map#isLiteModeEnabled'))!; + // Does not exist on iOS. + return false; } @override Future isMapToolbarEnabled({required int mapId}) async { - return (await _channelProvider(mapId)! - .invokeMethod('map#isMapToolbarEnabled'))!; + // Does not exist on iOS. + return false; } @override Future isMyLocationButtonEnabled({required int mapId}) async { - return (await _channelProvider(mapId)! - .invokeMethod('map#isMyLocationButtonEnabled'))!; + return _inspectorProvider(mapId)!.isMyLocationButtonEnabled(); } @override Future isTrafficEnabled({required int mapId}) async { - return (await _channelProvider(mapId)! - .invokeMethod('map#isTrafficEnabled'))!; + return _inspectorProvider(mapId)!.isTrafficEnabled(); } } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_maps_flutter_ios.dart b/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_maps_flutter_ios.dart index 56f3cc5a079..f0db5e99b12 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_maps_flutter_ios.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_maps_flutter_ios.dart @@ -12,6 +12,7 @@ import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platf import 'package:stream_transform/stream_transform.dart'; import 'google_map_inspector_ios.dart'; +import 'messages.g.dart'; // TODO(stuartmorgan): Remove the dependency on platform interface toJson // methods. Channel serialization details should all be package-internal. @@ -577,8 +578,8 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { @override @visibleForTesting void enableDebugInspection() { - GoogleMapsInspectorPlatform.instance = - GoogleMapsInspectorIOS((int mapId) => _channel(mapId)); + GoogleMapsInspectorPlatform.instance = GoogleMapsInspectorIOS((int mapId) => + MapsInspectorApi(messageChannelSuffix: mapId.toString())); } } From 762fa1c6db1a5aa4eb16dc7dad8ceec8a125ee71 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Mon, 17 Jun 2024 11:39:09 -0400 Subject: [PATCH 3/5] Move implementation to a new object, and add registration --- .../ios/Classes/GoogleMapController.h | 2 +- .../ios/Classes/GoogleMapController.m | 81 +++++++++++++++---- 2 files changed, 68 insertions(+), 15 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.h index 9e723c0ef25..e3ad2e7fcfe 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.h @@ -14,7 +14,7 @@ NS_ASSUME_NONNULL_BEGIN // Defines map overlay controllable from Flutter. @interface FLTGoogleMapController - : NSObject + : NSObject - (instancetype)initWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(nullable id)args diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m index ca019624bb8..42fe101c923 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m @@ -57,6 +57,33 @@ - (instancetype)initWithRegistrar:(NSObject *)registrar @end +#pragma mark - + +/// Implementation of the Pigeon maps inspector API. +/// +/// This is a separate object from the maps controller because the Pigeon API registration keeps a +/// strong reference to the implementor, but as the FlutterPlatformView, the lifetime of the +/// FLTGoogleMapController instance is what needs to trigger Pigeon unregistration, so can't be +/// the target of the registration. +@interface FGMMapInspector : NSObject +- (instancetype)initWithMapController:(nonnull FLTGoogleMapController *)controller + messenger:(NSObject *)messenger + pigeonSuffix:(NSString *)suffix; +@end + +/// Private declarations. +// This is separate in case the above is made public in the future (e.g., for unit testing). +@interface FGMMapInspector() +/// The map controller this inspector corresponds to. +@property(nonatomic, weak) FLTGoogleMapController *controller; +/// The messenger this instance was registered with by Pigeon. +@property(nonatomic, copy) NSObject *messenger; +/// The suffix this instance was registered under with Pigeon. +@property(nonatomic, copy) NSString *pigeonSuffix; +@end + +#pragma mark - + @interface FLTGoogleMapController () @property(nonatomic, strong) GMSMapView *mapView; @@ -73,6 +100,8 @@ @interface FLTGoogleMapController () // creation time and there's no mechanism to return non-fatal error details during platform view // initialization. @property(nonatomic, copy) NSString *styleError; +// The inspector API implementation, separate to avoid lifetime extension. +@property(nonatomic, strong) FGMMapInspector *inspector; @end @@ -115,9 +144,7 @@ - (instancetype)initWithMapView:(GMSMapView *_Nonnull)mapView binaryMessenger:registrar.messenger]; __weak __typeof__(self) weakSelf = self; [_channel setMethodCallHandler:^(FlutterMethodCall *call, FlutterResult result) { - if (weakSelf) { - [weakSelf onMethodCall:call result:result]; - } + [weakSelf onMethodCall:call result:result]; }]; _mapView.delegate = weakSelf; _mapView.paddingAdjustmentBehavior = kGMSMapViewPaddingAdjustmentBehaviorNever; @@ -159,10 +186,20 @@ - (instancetype)initWithMapView:(GMSMapView *_Nonnull)mapView } [_mapView addObserver:self forKeyPath:@"frame" options:0 context:nil]; + + NSString *suffix = [NSString stringWithFormat:@"%lld", viewId]; + _inspector = [[FGMMapInspector alloc] initWithMapController:self messenger:registrar.messenger pigeonSuffix:suffix]; + SetUpFGMMapsInspectorApiWithSuffix(registrar.messenger, _inspector, suffix); } return self; } +- (void)dealloc { + // Unregister the API implementations so that they can be released; the registration created an + // owning reference. + SetUpFGMMapsInspectorApiWithSuffix(_inspector.messenger, nil, _inspector.pigeonSuffix); +} + - (UIView *)view { return self.mapView; } @@ -623,37 +660,53 @@ - (void)interpretMapOptions:(NSDictionary *)data { } } -#pragma mark GMSMapsInspectorApi +@end + +#pragma mark - + +@implementation FGMMapInspector + +- (instancetype)initWithMapController:(nonnull FLTGoogleMapController *)controller + messenger:(NSObject *)messenger + pigeonSuffix:(NSString *)suffix { + self = [super init]; + if (self) { + _controller = controller; + _messenger = messenger; + _pigeonSuffix = suffix; + } + return self; +} - (nullable NSNumber *)areBuildingsEnabledWithError: (FlutterError *_Nullable __autoreleasing *_Nonnull)error { - return @(self.mapView.buildingsEnabled); + return @(self.controller.mapView.buildingsEnabled); } - (nullable NSNumber *)areRotateGesturesEnabledWithError: (FlutterError *_Nullable __autoreleasing *_Nonnull)error { - return @(self.mapView.settings.rotateGestures); + return @(self.controller.mapView.settings.rotateGestures); } - (nullable NSNumber *)areScrollGesturesEnabledWithError: (FlutterError *_Nullable __autoreleasing *_Nonnull)error { - return @(self.mapView.settings.scrollGestures); + return @(self.controller.mapView.settings.scrollGestures); } - (nullable NSNumber *)areTiltGesturesEnabledWithError: (FlutterError *_Nullable __autoreleasing *_Nonnull)error { - return @(self.mapView.settings.tiltGestures); + return @(self.controller.mapView.settings.tiltGestures); } - (nullable NSNumber *)areZoomGesturesEnabledWithError: (FlutterError *_Nullable __autoreleasing *_Nonnull)error { - return @(self.mapView.settings.zoomGestures); + return @(self.controller.mapView.settings.zoomGestures); } - (nullable FGMPlatformTileLayer *) getInfoForTileOverlayWithIdentifier:(nonnull NSString *)tileOverlayId error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { - GMSTileLayer *layer = [self.tileOverlaysController tileOverlayWithIdentifier:tileOverlayId].layer; + GMSTileLayer *layer = [self.controller.tileOverlaysController tileOverlayWithIdentifier:tileOverlayId].layer; if (!layer) { return nil; } @@ -665,22 +718,22 @@ - (nullable NSNumber *)areZoomGesturesEnabledWithError: - (nullable NSNumber *)isCompassEnabledWithError: (FlutterError *_Nullable __autoreleasing *_Nonnull)error { - return @(self.mapView.settings.compassButton); + return @(self.controller.mapView.settings.compassButton); } - (nullable NSNumber *)isMyLocationButtonEnabledWithError: (FlutterError *_Nullable __autoreleasing *_Nonnull)error { - return @(self.mapView.settings.myLocationButton); + return @(self.controller.mapView.settings.myLocationButton); } - (nullable NSNumber *)isTrafficEnabledWithError: (FlutterError *_Nullable __autoreleasing *_Nonnull)error { - return @(self.mapView.trafficEnabled); + return @(self.controller.mapView.trafficEnabled); } - (nullable FGMPlatformZoomRange *)zoomRange: (FlutterError *_Nullable __autoreleasing *_Nonnull)error { - return [FGMPlatformZoomRange makeWithMin:self.mapView.minZoom max:self.mapView.maxZoom]; + return [FGMPlatformZoomRange makeWithMin:self.controller.mapView.minZoom max:self.controller.mapView.maxZoom]; } @end From 0960911dd23b6fc91810dae9673e8b142d07aa88 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Mon, 17 Jun 2024 11:42:53 -0400 Subject: [PATCH 4/5] Version bump --- .../google_maps_flutter/google_maps_flutter_ios/CHANGELOG.md | 4 ++++ .../google_maps_flutter/google_maps_flutter_ios/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) 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 a43cf9c5d5f..41ae9a62ed7 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.7.1 + +* Converts inspector interface platform calls to Pigeon. + ## 2.7.0 * Adds support for BitmapDescriptor classes `AssetMapBitmap` and `BytesMapBitmap`. 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 15807e3c25e..3424e67e3e2 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.7.0 +version: 2.7.1 environment: sdk: ^3.2.3 From 4c18496aa8684d8336896b179d7f18ec9bdd60d7 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Thu, 20 Jun 2024 13:40:53 -0400 Subject: [PATCH 5/5] Fix formatting --- .../ios/Classes/GoogleMapController.h | 3 +-- .../ios/Classes/GoogleMapController.m | 14 +++++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.h b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.h index e3ad2e7fcfe..2b7b1182b6b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.h +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.h @@ -13,8 +13,7 @@ NS_ASSUME_NONNULL_BEGIN // Defines map overlay controllable from Flutter. -@interface FLTGoogleMapController - : NSObject +@interface FLTGoogleMapController : NSObject - (instancetype)initWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(nullable id)args diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m index 42fe101c923..67e95f03d9e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m @@ -65,7 +65,7 @@ - (instancetype)initWithRegistrar:(NSObject *)registrar /// strong reference to the implementor, but as the FlutterPlatformView, the lifetime of the /// FLTGoogleMapController instance is what needs to trigger Pigeon unregistration, so can't be /// the target of the registration. -@interface FGMMapInspector : NSObject +@interface FGMMapInspector : NSObject - (instancetype)initWithMapController:(nonnull FLTGoogleMapController *)controller messenger:(NSObject *)messenger pigeonSuffix:(NSString *)suffix; @@ -73,7 +73,7 @@ - (instancetype)initWithMapController:(nonnull FLTGoogleMapController *)controll /// Private declarations. // This is separate in case the above is made public in the future (e.g., for unit testing). -@interface FGMMapInspector() +@interface FGMMapInspector () /// The map controller this inspector corresponds to. @property(nonatomic, weak) FLTGoogleMapController *controller; /// The messenger this instance was registered with by Pigeon. @@ -188,7 +188,9 @@ - (instancetype)initWithMapView:(GMSMapView *_Nonnull)mapView [_mapView addObserver:self forKeyPath:@"frame" options:0 context:nil]; NSString *suffix = [NSString stringWithFormat:@"%lld", viewId]; - _inspector = [[FGMMapInspector alloc] initWithMapController:self messenger:registrar.messenger pigeonSuffix:suffix]; + _inspector = [[FGMMapInspector alloc] initWithMapController:self + messenger:registrar.messenger + pigeonSuffix:suffix]; SetUpFGMMapsInspectorApiWithSuffix(registrar.messenger, _inspector, suffix); } return self; @@ -706,7 +708,8 @@ - (nullable NSNumber *)areZoomGesturesEnabledWithError: - (nullable FGMPlatformTileLayer *) getInfoForTileOverlayWithIdentifier:(nonnull NSString *)tileOverlayId error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { - GMSTileLayer *layer = [self.controller.tileOverlaysController tileOverlayWithIdentifier:tileOverlayId].layer; + GMSTileLayer *layer = + [self.controller.tileOverlaysController tileOverlayWithIdentifier:tileOverlayId].layer; if (!layer) { return nil; } @@ -733,7 +736,8 @@ - (nullable NSNumber *)isTrafficEnabledWithError: - (nullable FGMPlatformZoomRange *)zoomRange: (FlutterError *_Nullable __autoreleasing *_Nonnull)error { - return [FGMPlatformZoomRange makeWithMin:self.controller.mapView.minZoom max:self.controller.mapView.maxZoom]; + return [FGMPlatformZoomRange makeWithMin:self.controller.mapView.minZoom + max:self.controller.mapView.maxZoom]; } @end