-
Notifications
You must be signed in to change notification settings - Fork 9.7k
[google_maps_flutter] Objective-C code clean up #5780
Conversation
It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat (don't just cc him here, he won't see it! He's on Discord!). If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix? Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
81ca7fc
to
a0e4f33
Compare
test-exempt: code reactor yay cleanup! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly the comments are just nits or suggested follow-ups for later PRs. Lots of great cleanup here!
In a few places where things were substantially moved around I couldn't really tell what changed, but I'm assuming it was either nothing, or pretty mechanical changes.
@interface FLTTileProviderController : GMSTileLayer | ||
@property(copy, nonatomic, readonly) NSString *tileOverlayId; | ||
- (instancetype)init:(FlutterMethodChannel *)methodChannel tileOverlayId:(NSString *)tileOverlayId; | ||
@property(copy, nonatomic, readonly) NSString *tileOverlayIdentifier; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential follow up: all of these (class, property, method) are missing comments. That's true for a lot of code in the plugin.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the issue adding a new item about comment/docs: flutter/flutter#102597
- (instancetype)init:(FlutterMethodChannel *)methodChannel | ||
mapView:(GMSMapView *)mapView | ||
registrar:(NSObject<FlutterPluginRegistrar> *)registrar; | ||
- (void)addTileOverlays:(NSArray *)tileOverlaysToAdd; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential follow up: Do a sweep over the plugin to add generics to all the collections.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the issue adding a new item about adding generics to the collection types: flutter/flutter#102597
tileOverlayIdentifier:(NSString *)identifier; | ||
@end | ||
|
||
@interface FLTTileOverlaysController : NSObject |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential follow up: comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the issue adding a new item about comment/docs: flutter/flutter#102597
- (instancetype)init:(FlutterMethodChannel *)methodChannel tileOverlayId:(NSString *)tileOverlayId; | ||
@property(copy, nonatomic, readonly) NSString *tileOverlayIdentifier; | ||
- (instancetype)init:(FlutterMethodChannel *)methodChannel | ||
tileOverlayIdentifier:(NSString *)identifier; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
withTileOverlayIdentifier:
registrar:(NSObject<FlutterPluginRegistrar> *)registrar { | ||
self = [super init]; | ||
if (self) { | ||
self.methodChannel = methodChannel; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These self
s should all become ivar assignments.
|
||
- (instancetype)initPolylineWithPath:(GMSMutablePath *)path | ||
polylineId:(NSString *)polylineId | ||
polylineIdentifier:(NSString *)polylineIdentifier |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can also just be identifier
+ (NSDictionary<NSString *, NSNumber *> *)getJsonFromPoint:(CGPoint)point; | ||
+ (nullable NSDictionary *)getJsonFromCoordinateBounds:(nullable GMSCoordinateBounds *)bounds; | ||
+ (nullable GMSCameraPosition *)getOptionalCameraPostionFromData:(nullable NSDictionary *)data; | ||
+ (CGPoint)getPointFromDictioanry:(NSDictionary *)dictionary; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: Dictionary
+ (float)getFloatFromData:(NSNumber *)data; | ||
+ (CLLocationCoordinate2D)getLocationFromData:(NSArray *)data; | ||
+ (CGPoint)getPointFromArray:(NSArray *)data; | ||
+ (NSArray *)getJsonFromLocation:(CLLocationCoordinate2D)location; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the getJson
s should be JSON
(nullable GMSCameraPosition *)position; | ||
+ (NSDictionary<NSString *, NSNumber *> *)getJsonFromPoint:(CGPoint)point; | ||
+ (nullable NSDictionary *)getJsonFromCoordinateBounds:(nullable GMSCoordinateBounds *)bounds; | ||
+ (nullable GMSCameraPosition *)getOptionalCameraPostionFromData:(nullable NSDictionary *)data; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've never seen nullability encoded in a name like this. Is this version used enough to need a wrapper, vs callers doing the short-circuit on null (which is more common for a nullable language than having two versions of the API)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed the nullability naming. Also removed the private method.
+ (nullable NSDictionary *)getJsonFromCoordinateBounds:(nullable GMSCoordinateBounds *)bounds; | ||
+ (nullable GMSCameraPosition *)getOptionalCameraPostionFromData:(nullable NSDictionary *)data; | ||
+ (CGPoint)getPointFromDictioanry:(NSDictionary *)dictionary; | ||
+ (nullable GMSCoordinateBounds *)getOptionalCoordinateBoundsFromData:(NSArray *)data; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same nullability variant comment here.
return holes; | ||
} | ||
|
||
+ (nullable NSDictionary<NSString *, id> *)getJsonFromPosition:(GMSCameraPosition *)position { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, one thing I missed: these newly-added-to-this-class methods should get new unit tests since they should now be easily unit-testable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point! This PR will have some tests after all :)
cc @Hixie
Looks like the app is crashing during tests? Also there are format issues. |
5753e7a
to
b376693
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I commented in a few areas, but it looks like we can simplify things by removing the FLTGoogleMapTileOverlayOptionsSink
, FLTGoogleMapOptionsSink
FLTGoogleMapCircleOptionsSink
FLTGoogleMapMarkerOptionsSink
and FLTGoogleMapPolygonOptionsSink
protocols.
...ter/google_maps_flutter/example/ios/RunnerTests/FLTGoogleMapJSONConversionsConversionTests.m
Outdated
Show resolved
Hide resolved
...ages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.h
Outdated
Show resolved
Hide resolved
...ages/google_maps_flutter/google_maps_flutter/ios/Classes/FLTGoogleMapTileOverlayController.m
Outdated
Show resolved
Hide resolved
+ (void)interpretTileOverlayOptions:(NSDictionary *)data | ||
sink:(id<FLTGoogleMapTileOverlayOptionsSink>)sink { | ||
NSNumber *visible = data[@"visible"]; | ||
if (visible != nil && visible != (id)[NSNull null]) { | ||
[sink setVisible:visible.boolValue]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class method is kind of odd, looks like it should be an instance method on FLTGoogleMapTileOverlayController
like:
+ (void)interpretTileOverlayOptions:(NSDictionary *)data | |
sink:(id<FLTGoogleMapTileOverlayOptionsSink>)sink { | |
NSNumber *visible = data[@"visible"]; | |
if (visible != nil && visible != (id)[NSNull null]) { | |
[sink setVisible:visible.boolValue]; | |
} | |
- (void)setTileOverlayOptionsFromData:(NSDictionary *)data { | |
NSNumber *visible = data[@"visible"]; | |
if (visible != nil && visible != (id)[NSNull null]) { | |
self.visible = visible.boolValue; | |
} |
And at that point the data dictionary could be passed into -initWithTileLayer
and populate the backing ivars and FLTGoogleMapTileOverlayOptionsSink
can go away (same comment for all the Sink
protocols).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
I didn't update the init method if the interpret method includes a registrar parameter. I feel like as the registrar is not owned by the controller, it feels odd to have it in an init method.
packages/google_maps_flutter/google_maps_flutter/ios/Classes/JsonConversions.h
Show resolved
Hide resolved
packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapCircleController.h
Outdated
Show resolved
Hide resolved
packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m
Outdated
Show resolved
Hide resolved
packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapPolygonController.m
Outdated
Show resolved
Hide resolved
@stuartmorgan @jmagman I updated the code per your suggestions! PTAL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM once @jmagman signs off. I didn't do a full re-review, just spot-checked around some of my previous comments. I'm sure I could continue to find things to suggest if I keep staring at this code, but it's already a big change and clearly an incremental improvement as-is 🙂
|
||
@interface FLTGoogleMapJSONConversions : NSObject | ||
|
||
+ (CLLocationCoordinate2D)locationFromLatlong:(NSArray *)latlong; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional nit: here and in all the instances below, I think LatLong
would be better, as it's two (abbbreviated) words. I think treating it as one word once abbreviated hurts readability.
+ (NSArray<NSArray<CLLocation *> *> *)toHoles:(NSArray *)data; | ||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@interface FLTGoogleMapJSONConversions : NSObject |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: The file should be named FLTGoogleMapJSONConversions.h
.
(Or even better, the name should stay the same and all of these should become C functions—since "classes" that are just class methods are an abomination IMO—at which point the name should be the same. But I know many ObjC developers like this style so I'm not going to die on that hill today.)
|
||
@interface FLTTileProviderController () | ||
|
||
@property(weak, nonatomic) FlutterMethodChannel *methodChannel; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you remember why you made this weak in the first place?
https://github.com/flutter/plugins/pull/3434/files#diff-7013871fe3ee02101b28aad71693b5ef3d5f48414c744ddef944e57fe886c5f4R100
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same reason I made all method channels to be weak in this PR. The owner of the methodchannel is FLTGoogleMapController
. And FLTGoogleMapController
owns and out lives all the sub controllers, so I thought it is not necessary for the sub controllers to strongly own methodChannel
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then did you mean to make it strong in this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, to match other controllers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So should they all be weak
as you had it before? I'm not trying to argue one way or the other.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think Strong is better. There won't be a retain cycle as method channel is not going to have a strong reference to the controllers.
Having them as weak makes the methodChannel's life cycle confusing. One needs to figure out who strongly owns the methodChannel
(GoogleMapsController) to understand its life cycle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Once format is happy. |
Release bot won't be happy due to some out of band failure. Manually published the change. |
Objective-C code cleanup. See: flutter/flutter#102597
fixes flutter/flutter#102597
It has a lot of re-naming, let me know if it is hard to review. I can try separate it to smaller patches.
Pre-launch Checklist
dart format
.)[shared_preferences]
pubspec.yaml
with an appropriate new version according to the pub versioning philosophy, or this PR is exempt from version changes.CHANGELOG.md
to add a description of the change, following repository CHANGELOG style.///
).If you need help, consider asking for advice on the #hackers-new channel on Discord.