Skip to content

Commit

Permalink
[google_maps_flutter] Convert Obj-C->Dart calls to Pigeon (#7086)
Browse files Browse the repository at this point in the history
Converts all of the Obj-C->Dart calls from raw method channels to Pigeon. This finishes conversion of all of the invocations in `google_maps_flutter_ios`

This is the iOS equivalent of #7040, and much of the Dart code is based on that PR.

Part of flutter/flutter#117907
  • Loading branch information
stuartmorgan authored Jul 9, 2024
1 parent 1faccfe commit 4063b20
Show file tree
Hide file tree
Showing 24 changed files with 1,682 additions and 418 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.10.0

* Converts Obj-C->Dart calls to Pigeon.

## 2.9.0

* Converts additional platform calls to Pigeon.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,19 @@ - (void)testHolesFromPointsArray {
XCTAssertEqual(holes[1][1].coordinate.longitude, 8);
}

- (void)testDictionaryFromPosition {
id mockPosition = OCMClassMock([GMSCameraPosition class]);
NSValue *locationValue = [NSValue valueWithMKCoordinate:CLLocationCoordinate2DMake(1, 2)];
[(GMSCameraPosition *)[[mockPosition stub] andReturnValue:locationValue] target];
[[[mockPosition stub] andReturnValue:@(2.0)] zoom];
[[[mockPosition stub] andReturnValue:@(3.0)] bearing];
[[[mockPosition stub] andReturnValue:@(75.0)] viewingAngle];
NSDictionary *dictionary = [FLTGoogleMapJSONConversions dictionaryFromPosition:mockPosition];
NSArray *targetArray = @[ @1, @2 ];
XCTAssertEqualObjects(dictionary[@"target"], targetArray);
XCTAssertEqualObjects(dictionary[@"zoom"], @2.0);
XCTAssertEqualObjects(dictionary[@"bearing"], @3.0);
XCTAssertEqualObjects(dictionary[@"tilt"], @75.0);
- (void)testGetPigeonCameraPositionForPosition {
GMSCameraPosition *position =
[[GMSCameraPosition alloc] initWithTarget:CLLocationCoordinate2DMake(1, 2)
zoom:2.0
bearing:3.0
viewingAngle:75.0];
FGMPlatformCameraPosition *pigeonPosition = FGMGetPigeonCameraPositionForPosition(position);
XCTAssertEqualWithAccuracy(pigeonPosition.target.latitude, position.target.latitude, DBL_EPSILON);
XCTAssertEqualWithAccuracy(pigeonPosition.target.longitude, position.target.longitude,
DBL_EPSILON);
XCTAssertEqualWithAccuracy(pigeonPosition.zoom, position.zoom, DBL_EPSILON);
XCTAssertEqualWithAccuracy(pigeonPosition.bearing, position.bearing, DBL_EPSILON);
XCTAssertEqualWithAccuracy(pigeonPosition.tilt, position.viewingAngle, DBL_EPSILON);
}

- (void)testPigeonPointForGCPoint {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,24 @@

#import <OCMock/OCMock.h>

#import "messages.g.h"

@interface FLTTileProviderControllerTests : XCTestCase
@end

@implementation FLTTileProviderControllerTests

- (void)testCallChannelOnPlatformThread {
id channel = OCMClassMock(FlutterMethodChannel.class);
FLTTileProviderController *controller = [[FLTTileProviderController alloc] init:channel
withTileOverlayIdentifier:@"foo"];
id handler = OCMClassMock([FGMMapsCallbackApi class]);
FLTTileProviderController *controller =
[[FLTTileProviderController alloc] initWithTileOverlayIdentifier:@"foo"
callbackHandler:handler];
XCTAssertNotNil(controller);
XCTestExpectation *expectation = [self expectationWithDescription:@"invokeMethod"];
OCMStub([channel invokeMethod:[OCMArg any] arguments:[OCMArg any] result:[OCMArg any]])
OCMStub([handler tileWithOverlayIdentifier:[OCMArg any]
location:[OCMArg any]
zoom:0
completion:[OCMArg any]])
.andDo(^(NSInvocation *invocation) {
XCTAssertTrue([[NSThread currentThread] isMainThread]);
[expectation fulfill];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ - (FLTGoogleMapPolylineController *)polylineControllerWithMockedMap {
NSString *identifier = polyline[@"polylineId"];

FLTGoogleMapPolylineController *polylineControllerWithMockedMap =
[[FLTGoogleMapPolylineController alloc] initPolylineWithPath:path
identifier:identifier
mapView:mapView];
[[FLTGoogleMapPolylineController alloc] initWithPath:path
identifier:identifier
mapView:mapView];

return polylineControllerWithMockedMap;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ extern FGMPlatformLatLng *FGMGetPigeonLatLngForCoordinate(CLLocationCoordinate2D
extern FGMPlatformLatLngBounds *FGMGetPigeonLatLngBoundsForCoordinateBounds(
GMSCoordinateBounds *bounds);

/// Converts a GMSCameraPosition to its Pigeon representation.
extern FGMPlatformCameraPosition *FGMGetPigeonCameraPositionForPosition(
GMSCameraPosition *position);

@interface FLTGoogleMapJSONConversions : NSObject

+ (CLLocationCoordinate2D)locationFromLatLong:(NSArray *)latlong;
Expand All @@ -36,8 +40,6 @@ extern FGMPlatformLatLngBounds *FGMGetPigeonLatLngBoundsForCoordinateBounds(
+ (UIColor *)colorFromRGBA:(NSNumber *)data;
+ (NSArray<CLLocation *> *)pointsFromLatLongs:(NSArray *)data;
+ (NSArray<NSArray<CLLocation *> *> *)holesFromPointsArray:(NSArray *)data;
+ (nullable NSDictionary<NSString *, id> *)dictionaryFromPosition:
(nullable GMSCameraPosition *)position;
+ (nullable GMSCameraPosition *)cameraPostionFromDictionary:(nullable NSDictionary *)channelValue;
+ (GMSCoordinateBounds *)coordinateBoundsFromLatLongs:(NSArray *)latlongs;
+ (GMSMapViewType)mapViewTypeFromTypeValue:(NSNumber *)value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ CLLocationCoordinate2D FGMGetCoordinateForPigeonLatLng(FGMPlatformLatLng *latLng
southwest:FGMGetPigeonLatLngForCoordinate(bounds.southWest)];
}

FGMPlatformCameraPosition *FGMGetPigeonCameraPositionForPosition(GMSCameraPosition *position) {
return [FGMPlatformCameraPosition makeWithBearing:position.bearing
target:FGMGetPigeonLatLngForCoordinate(position.target)
tilt:position.viewingAngle
zoom:position.zoom];
}

@implementation FLTGoogleMapJSONConversions

+ (CLLocationCoordinate2D)locationFromLatLong:(NSArray *)latlong {
Expand Down Expand Up @@ -77,18 +84,6 @@ + (UIColor *)colorFromRGBA:(NSNumber *)numberColor {
return holes;
}

+ (nullable NSDictionary<NSString *, id> *)dictionaryFromPosition:(GMSCameraPosition *)position {
if (!position) {
return nil;
}
return @{
@"target" : [FLTGoogleMapJSONConversions arrayFromLocation:[position target]],
@"zoom" : @([position zoom]),
@"bearing" : @([position bearing]),
@"tilt" : @([position viewingAngle]),
};
}

+ (nullable GMSCameraPosition *)cameraPostionFromDictionary:(nullable NSDictionary *)data {
if (!data) {
return nil;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ NS_ASSUME_NONNULL_BEGIN

@interface FLTTileProviderController : GMSTileLayer
@property(copy, nonatomic, readonly) NSString *tileOverlayIdentifier;
- (instancetype)init:(FlutterMethodChannel *)methodChannel
withTileOverlayIdentifier:(NSString *)identifier;
- (instancetype)initWithTileOverlayIdentifier:(NSString *)identifier
callbackHandler:(FGMMapsCallbackApi *)callbackHandler;
@end

@interface FLTTileOverlaysController : NSObject
- (instancetype)init:(FlutterMethodChannel *)methodChannel
mapView:(GMSMapView *)mapView
registrar:(NSObject<FlutterPluginRegistrar> *)registrar;
- (instancetype)initWithMapView:(GMSMapView *)mapView
callbackHandler:(FGMMapsCallbackApi *)callbackHandler
registrar:(NSObject<FlutterPluginRegistrar> *)registrar;
- (void)addJSONTileOverlays:(NSArray<NSDictionary<NSString *, id> *> *)tileOverlaysToAdd;
- (void)addTileOverlays:(NSArray<FGMPlatformTileOverlay *> *)tileOverlaysToAdd;
- (void)changeTileOverlays:(NSArray<FGMPlatformTileOverlay *> *)tileOverlaysToChange;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,17 +89,17 @@ - (void)interpretTileOverlayOptions:(NSDictionary *)data {

@interface FLTTileProviderController ()

@property(strong, nonatomic) FlutterMethodChannel *methodChannel;
@property(strong, nonatomic) FGMMapsCallbackApi *callbackHandler;

@end

@implementation FLTTileProviderController

- (instancetype)init:(FlutterMethodChannel *)methodChannel
withTileOverlayIdentifier:(NSString *)identifier {
- (instancetype)initWithTileOverlayIdentifier:(NSString *)identifier
callbackHandler:(FGMMapsCallbackApi *)callbackHandler {
self = [super init];
if (self) {
_methodChannel = methodChannel;
_callbackHandler = callbackHandler;
_tileOverlayIdentifier = identifier;
}
return self;
Expand Down Expand Up @@ -135,35 +135,23 @@ - (void)requestTileForX:(NSUInteger)x
zoom:(NSUInteger)zoom
receiver:(id<GMSTileReceiver>)receiver {
dispatch_async(dispatch_get_main_queue(), ^{
[self.methodChannel invokeMethod:@"tileOverlay#getTile"
arguments:@{
@"tileOverlayId" : self.tileOverlayIdentifier,
@"x" : @(x),
@"y" : @(y),
@"zoom" : @(zoom)
}
result:^(id _Nullable result) {
UIImage *tileImage;
if ([result isKindOfClass:[NSDictionary class]]) {
FlutterStandardTypedData *typedData = (FlutterStandardTypedData *)result[@"data"];
if (typedData == nil) {
tileImage = kGMSTileLayerNoTile;
} else {
tileImage = [self handleResultTile:[UIImage imageWithData:typedData.data]];
}
} else {
if ([result isKindOfClass:[FlutterError class]]) {
FlutterError *error = (FlutterError *)result;
NSLog(@"Can't get tile: errorCode = %@, errorMessage = %@, details = %@",
[error code], [error message], [error details]);
}
if ([result isKindOfClass:[FlutterMethodNotImplemented class]]) {
NSLog(@"Can't get tile: notImplemented");
}
tileImage = kGMSTileLayerNoTile;
}
[receiver receiveTileWithX:x y:y zoom:zoom image:tileImage];
}];
[self.callbackHandler
tileWithOverlayIdentifier:self.tileOverlayIdentifier
location:[FGMPlatformPoint makeWithX:x y:y]
zoom:zoom
completion:^(FGMPlatformTile *_Nullable tile,
FlutterError *_Nullable error) {
FlutterStandardTypedData *typedData = tile.data;
UIImage *tileImage =
typedData
? [self handleResultTile:[UIImage imageWithData:typedData.data]]
: kGMSTileLayerNoTile;
if (error) {
NSLog(@"Can't get tile: errorCode = %@, errorMessage = %@, details = %@",
[error code], [error message], [error details]);
}
[receiver receiveTileWithX:x y:y zoom:zoom image:tileImage];
}];
});
}

Expand All @@ -173,19 +161,19 @@ @interface FLTTileOverlaysController ()

@property(strong, nonatomic) NSMutableDictionary<NSString *, FLTGoogleMapTileOverlayController *>
*tileOverlayIdentifierToController;
@property(strong, nonatomic) FlutterMethodChannel *methodChannel;
@property(strong, nonatomic) FGMMapsCallbackApi *callbackHandler;
@property(weak, nonatomic) GMSMapView *mapView;

@end

@implementation FLTTileOverlaysController

- (instancetype)init:(FlutterMethodChannel *)methodChannel
mapView:(GMSMapView *)mapView
registrar:(NSObject<FlutterPluginRegistrar> *)registrar {
- (instancetype)initWithMapView:(GMSMapView *)mapView
callbackHandler:(FGMMapsCallbackApi *)callbackHandler
registrar:(NSObject<FlutterPluginRegistrar> *)registrar {
self = [super init];
if (self) {
_methodChannel = methodChannel;
_callbackHandler = callbackHandler;
_mapView = mapView;
_tileOverlayIdentifierToController = [[NSMutableDictionary alloc] init];
}
Expand All @@ -196,8 +184,8 @@ - (void)addJSONTileOverlays:(NSArray<NSDictionary<NSString *, id> *> *)tileOverl
for (NSDictionary<NSString *, id> *tileOverlay in tileOverlaysToAdd) {
NSString *identifier = [FLTTileOverlaysController identifierForTileOverlay:tileOverlay];
FLTTileProviderController *tileProvider =
[[FLTTileProviderController alloc] init:self.methodChannel
withTileOverlayIdentifier:identifier];
[[FLTTileProviderController alloc] initWithTileOverlayIdentifier:identifier
callbackHandler:self.callbackHandler];
FLTGoogleMapTileOverlayController *controller =
[[FLTGoogleMapTileOverlayController alloc] initWithTileLayer:tileProvider
mapView:self.mapView
Expand All @@ -210,8 +198,8 @@ - (void)addTileOverlays:(NSArray<FGMPlatformTileOverlay *> *)tileOverlaysToAdd {
for (FGMPlatformTileOverlay *tileOverlay in tileOverlaysToAdd) {
NSString *identifier = [FLTTileOverlaysController identifierForTileOverlay:tileOverlay.json];
FLTTileProviderController *tileProvider =
[[FLTTileProviderController alloc] init:self.methodChannel
withTileOverlayIdentifier:identifier];
[[FLTTileProviderController alloc] initWithTileOverlayIdentifier:identifier
callbackHandler:self.callbackHandler];
FLTGoogleMapTileOverlayController *controller =
[[FLTGoogleMapTileOverlayController alloc] initWithTileLayer:tileProvider
mapView:self.mapView
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
@end

@interface FLTCirclesController : NSObject
- (instancetype)init:(FlutterMethodChannel *)methodChannel
mapView:(GMSMapView *)mapView
registrar:(NSObject<FlutterPluginRegistrar> *)registrar;
- (instancetype)initWithMapView:(GMSMapView *)mapView
callbackHandler:(FGMMapsCallbackApi *)callbackHandler
registrar:(NSObject<FlutterPluginRegistrar> *)registrar;
- (void)addJSONCircles:(NSArray<NSDictionary<NSString *, id> *> *)circlesToAdd;
- (void)addCircles:(NSArray<FGMPlatformCircle *> *)circlesToAdd;
- (void)changeCircles:(NSArray<FGMPlatformCircle *> *)circlesToChange;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,20 +105,20 @@ - (void)interpretCircleOptions:(NSDictionary *)data {

@interface FLTCirclesController ()

@property(strong, nonatomic) FlutterMethodChannel *methodChannel;
@property(strong, nonatomic) FGMMapsCallbackApi *callbackHandler;
@property(weak, nonatomic) GMSMapView *mapView;
@property(strong, nonatomic) NSMutableDictionary *circleIdToController;

@end

@implementation FLTCirclesController

- (instancetype)init:(FlutterMethodChannel *)methodChannel
mapView:(GMSMapView *)mapView
registrar:(NSObject<FlutterPluginRegistrar> *)registrar {
- (instancetype)initWithMapView:(GMSMapView *)mapView
callbackHandler:(FGMMapsCallbackApi *)callbackHandler
registrar:(NSObject<FlutterPluginRegistrar> *)registrar {
self = [super init];
if (self) {
_methodChannel = methodChannel;
_callbackHandler = callbackHandler;
_mapView = mapView;
_circleIdToController = [NSMutableDictionary dictionaryWithCapacity:1];
}
Expand Down Expand Up @@ -189,7 +189,9 @@ - (void)didTapCircleWithIdentifier:(NSString *)identifier {
if (!controller) {
return;
}
[self.methodChannel invokeMethod:@"circle#onTap" arguments:@{@"circleId" : identifier}];
[self.callbackHandler didTapCircleWithIdentifier:identifier
completion:^(FlutterError *_Nullable _){
}];
}

+ (CLLocationCoordinate2D)getPosition:(NSDictionary *)circle {
Expand Down
Loading

0 comments on commit 4063b20

Please sign in to comment.