[google_maps_ios] Cache `+[GMSServices sharedServices]` when first map is created (#6211)
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 e4b243a..33d96e9 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.1.11
+
+* Precaches Google Maps services initialization and syncing.
+
## 2.1.10
* Splits iOS implementation out of `google_maps_flutter` as a federated
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 a8768e1..71f1162 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
@@ -5,10 +5,15 @@
@import google_maps_flutter_ios;
@import google_maps_flutter_ios.Test;
@import XCTest;
+@import GoogleMaps;
#import <OCMock/OCMock.h>
#import "PartiallyMockedMapView.h"
+@interface FLTGoogleMapFactory (Test)
+@property(strong, nonatomic, readonly) id<NSObject> sharedMapServices;
+@end
+
@interface GoogleMapsTests : XCTestCase
@end
@@ -39,4 +44,16 @@
XCTAssertEqual(mapView.frameObserverCount, 0);
}
+- (void)testMapsServiceSync {
+ id registrar = OCMProtocolMock(@protocol(FlutterPluginRegistrar));
+ FLTGoogleMapFactory *factory1 = [[FLTGoogleMapFactory alloc] initWithRegistrar:registrar];
+ XCTAssertNotNil(factory1.sharedMapServices);
+ FLTGoogleMapFactory *factory2 = [[FLTGoogleMapFactory alloc] initWithRegistrar:registrar];
+ // Test pointer equality, should be same retained singleton +[GMSServices sharedServices] object.
+ // Retaining the opaque object should be enough to avoid multiple internal initializations,
+ // but don't test the internals of the GoogleMaps API. Assume that it does what is documented.
+ // https://developers.google.com/maps/documentation/ios-sdk/reference/interface_g_m_s_services#a436e03c32b1c0be74e072310a7158831
+ XCTAssertEqual(factory1.sharedMapServices, factory2.sharedMapServices);
+}
+
@end
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 41c5d77..bd50c2d 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
@@ -11,11 +11,14 @@
@interface FLTGoogleMapFactory ()
@property(weak, nonatomic) NSObject<FlutterPluginRegistrar> *registrar;
+@property(strong, nonatomic, readonly) id<NSObject> sharedMapServices;
@end
@implementation FLTGoogleMapFactory
+@synthesize sharedMapServices = _sharedMapServices;
+
- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
self = [super init];
if (self) {
@@ -31,11 +34,26 @@
- (NSObject<FlutterPlatformView> *)createWithFrame:(CGRect)frame
viewIdentifier:(int64_t)viewId
arguments:(id _Nullable)args {
+ // Precache shared map services, if needed.
+ // Retain the shared map services singleton, don't use the result for anything.
+ (void)[self sharedMapServices];
+
return [[FLTGoogleMapController alloc] initWithFrame:frame
viewIdentifier:viewId
arguments:args
registrar:self.registrar];
}
+
+- (id<NSObject>)sharedMapServices {
+ if (_sharedMapServices == nil) {
+ // Calling this prepares GMSServices on a background thread controlled
+ // by the GoogleMaps framework.
+ // Retain the singleton to cache the initialization work across all map views.
+ _sharedMapServices = [GMSServices sharedServices];
+ }
+ return _sharedMapServices;
+}
+
@end
@interface FLTGoogleMapController ()
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 f55da6e..a870962 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 @@
description: iOS implementation of the google_maps_flutter plugin.
repository: https://github.com/flutter/plugins/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.1.10
+version: 2.1.11
environment:
sdk: ">=2.14.0 <3.0.0"