Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[google_maps_flutter] Implement polyline patterns in google maps ios #5757

Open
wants to merge 35 commits into
base: main
Choose a base branch
from

Conversation

Hari-07
Copy link

@Hari-07 Hari-07 commented Dec 26, 2023

This PR Implements patterns in google maps ios polylines. Currently the patterns param is simply ignored on ios, despite the official google maps SDK for ios having instructions on how to achieve repeated patterns: https://developers.google.com/maps/documentation/ios-sdk/shapes#add-a-repeating-color-pattern-to-a-polyline

List which issues are fixed by this PR. You must list at least one issue.
flutter/flutter#60083

If you had to change anything in the flutter/tests repo, include a link to the migration guide as per the breaking change policy.
Nil

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the relevant style guides and ran the auto-formatter. (Unlike the flutter/flutter repo, the flutter/packages repo does use dart format.)
  • I signed the CLA.
  • The title of the PR starts with the name of the package surrounded by square brackets, e.g. [shared_preferences]
  • I listed at least one issue that this PR fixes in the description above.
  • I updated pubspec.yaml with an appropriate new version according to the pub versioning philosophy, or this PR is exempt from version changes.
  • I updated CHANGELOG.md to add a description of the change, following repository CHANGELOG style.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is test-exempt.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@flutter-dashboard
Copy link

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 "@test-exemption-reviewer" in the #hackers channel in Chat (don't just cc them here, they won't see it! Use 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.

@Hari-07
Copy link
Author

Hari-07 commented Dec 26, 2023

I don't currently have any tests, however that is because looking at the existing tests, since I only made changes to the ios package, it didn't seem right to author tests in the google_maps_flutter package.

But looking at tests in google_maps_flutter_ios it seemed like they do not test things like what this PR covers

Open to authoring tests, if someone could let me know what the tests should test

@stuartmorgan
Copy link
Contributor

Marking as a draft for now since this needs native unit tests before it will be ready for review (per discussion in Discord).

@stuartmorgan stuartmorgan marked this pull request as draft January 2, 2024 14:32
@Hari-07
Copy link
Author

Hari-07 commented Jan 4, 2024

I implemented tests for 2 out of 3 functions I wrote. For the 3rd function, the test should look something like

- (void)testStrokeStylesFromPatterns {
    NSArray* patterns = @ [@[@"gap", @10], @[@"dash", @10]];
    UIColor* strokeColor = [UIColor redColor];
    
    NSArray<GMSStrokeStyle*> *patternStrokeStyle = [FLTGoogleMapJSONConversions strokeStylesFromPatterns:patterns strokeColor:strokeColor];
    
    XCTAssertEqual([patternStrokeStyle count], 2);
    
    GMSStrokeStyle* firstStrokeStyle = patternStrokeStyle[0];
    GMSStrokeStyle* secondStrokeStyle = patternStrokeStyle[1];
    
    // XCTAssertEqualObjects(firstStrokeStyle, [GMSStrokeStyle solidColor:[UIColor clearColor]]);
    // XCTAssertEqualObjects(secondStrokeStyle, [GMSStrokeStyle solidColor:strokeColor]);
}

However, the color property is not readable so I couldn't get this to work.

@vashworth
Copy link
Contributor

@Hari-07 Is this ready for re-review?

@Hari-07
Copy link
Author

Hari-07 commented Apr 28, 2024

@Hari-07 Is this ready for re-review?

Yeah it should be good to go, I had a couple of questions that I've commented above. I believe I've addressed all the comments @stuartmorgan had made, except for the type generics. I have update that too but had a question which I've commented above on that thread

Copy link

@yaakovschectman yaakovschectman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM for Android changes

Copy link
Contributor

@stuartmorgan stuartmorgan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've collapsed the iOS 12 example into the iOS 14 example due to dropping iOS 12 and iOS 13 support, so you'll need to migrate the test changes to that example. Sorry for the churn!

@@ -1,3 +1,7 @@
## 2.3.6

* Adds support for patterns in polylines on iOS.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still says "on iOS". Please make sure you are not marking things as resolved when the requested change has not been made, as it makes review much harder.


/**
* Internal APIs exposed for unit testing
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've recently standardized on /// for declaration comments in Obj-C code, so these should all be updated to use that.

(Applies throughout the PR.)

*/
@interface FLTPolylinesController (Test)
/**
* Returns the path for polyline based on the points(locations) the polyline has.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space before (.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_Test headers go next to the actual headers, not in the test directory.


@implementation GoogleMapsPolylinesControllerTests

- (FLTGoogleMapPolylineController *)setUpPolyLineControllerWithMockedMap {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs a declaration comment, per style guide. Test helper code is still code that humans have to understand and maintain, which is what comments are to help with.


@implementation GoogleMapsPolylinesControllerTests

- (FLTGoogleMapPolylineController *)setUpPolyLineControllerWithMockedMap {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should just be called polylineControllerWithMockedMap since it returns one; setUp... doesn't sound like a method that returns anything.


+ (NSArray<NSNumber *> *)spanLengthsFromPatterns:(NSArray<NSArray *> *)patterns {
NSMutableArray *lengths = [[NSMutableArray alloc] initWithCapacity:[patterns count]];
for (unsigned int i = 0; i < [patterns count]; i++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should use fast enumeration rather than indexing, and addObject: to lengths.

+ (NSArray<GMSStrokeStyle *> *)strokeStylesFromPatterns:(NSArray<NSArray *> *)patterns
strokeColor:(UIColor *)strokeColor {
NSMutableArray *strokeStyles = [[NSMutableArray alloc] initWithCapacity:[patterns count]];
for (unsigned int i = 0; i < [patterns count]; i++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should use fast enumeration rather than indexing, and addObject: to strokeStyles.

@@ -171,7 +191,7 @@ - (bool)hasPolylineWithIdentifier:(NSString *)identifier {
}
return self.polylineIdentifierToController[identifier] != nil;
}
+ (GMSMutablePath *)getPath:(NSDictionary *)polyline {
- (GMSMutablePath *)pathForPolyline:(NSDictionary *)polyline {
NSArray *pointArray = polyline[@"points"];
NSArray<CLLocation *> *points = [FLTGoogleMapJSONConversions pointsFromLatLongs:pointArray];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a response or change related to this comment.

Comment on lines +19 to +22
id GetValueOrNilFromDict(NSDictionary * dict, NSString *key) {
id value = dict[key];
return value == [NSNull null] ? nil : value;
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What'a s good place to put this function? Feels kinda out of place here, maybe a new utils file?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's fine to leave this in the file that needs it, although it should be declared static.

(It will go way soon, when we convert to Pigeon, so making a new file will just add extra work to undo later.)

@@ -171,7 +191,7 @@ - (bool)hasPolylineWithIdentifier:(NSString *)identifier {
}
return self.polylineIdentifierToController[identifier] != nil;
}
+ (GMSMutablePath *)getPath:(NSDictionary *)polyline {
- (GMSMutablePath *)pathForPolyline:(NSDictionary *)polyline {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't remember off the top of my head. Reverting back to static

Correct me if im wrong, since it's not listed in the .h file, I understand that this method isn't available publically to import. If that's the case, why make it static if not needed?

@@ -171,7 +191,7 @@ - (bool)hasPolylineWithIdentifier:(NSString *)identifier {
}
return self.polylineIdentifierToController[identifier] != nil;
}
+ (GMSMutablePath *)getPath:(NSDictionary *)polyline {
- (GMSMutablePath *)pathForPolyline:(NSDictionary *)polyline {
NSArray *pointArray = polyline[@"points"];
NSArray<CLLocation *> *points = [FLTGoogleMapJSONConversions pointsFromLatLongs:pointArray];
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only being used internally so I think it makes sense to have it in here. I'd assume the FLTJSONConversion file ought to be dumb and just convert and needn't know about the structure of the polyline object (polyline[@"points"])

@@ -171,7 +191,7 @@ - (bool)hasPolylineWithIdentifier:(NSString *)identifier {
}
return self.polylineIdentifierToController[identifier] != nil;
}
+ (GMSMutablePath *)getPath:(NSDictionary *)polyline {
- (GMSMutablePath *)pathForPolyline:(NSDictionary *)polyline {
NSArray *pointArray = polyline[@"points"];
NSArray<CLLocation *> *points = [FLTGoogleMapJSONConversions pointsFromLatLongs:pointArray];
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or we could move this to the polylineController instead of polylinesController. Then it'd have access to the polyline instance instead of passing that in

@@ -141,4 +141,34 @@ + (nullable GMSCameraUpdate *)cameraUpdateFromChannelValue:(NSArray *)channelVal
}
return nil;
}

+ (NSArray<GMSStrokeStyle *> *)strokeStylesFromPatterns:(NSArray *)patterns
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I specified that its an array of arrays like so

(NSArray<GMSStrokeStyle *> *)strokeStylesFromPatterns:(NSArray<NSArray *> *)patterns
                                            strokeColor:(UIColor *)strokeColor

As for the inner array, it has 2 members the first one being a string, and the second a number so I wasn't sure how that ought to be defined. Would be better as a map, but this is how the data is passed in to the channel

@@ -141,4 +141,34 @@ + (nullable GMSCameraUpdate *)cameraUpdateFromChannelValue:(NSArray *)channelVal
}
return nil;
}

+ (NSArray<GMSStrokeStyle *> *)strokeStylesFromPatterns:(NSArray *)patterns
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could also specify the internal array as an NSObject and then cast it explicitly. Not sure if that's any better though

+ (NSArray<GMSStrokeStyle *> *)strokeStylesFromPatterns:(NSArray<NSArray<NSObject *> *> *)patterns
                                            strokeColor:(UIColor *)strokeColor {
  NSMutableArray *strokeStyles = [[NSMutableArray alloc] initWithCapacity:[patterns count]];
  for (unsigned int i = 0; i < [patterns count]; i++) {
    NSString *patternType = (NSString *)patterns[i][0];

@@ -171,7 +191,7 @@ - (bool)hasPolylineWithIdentifier:(NSString *)identifier {
}
return self.polylineIdentifierToController[identifier] != nil;
}
+ (GMSMutablePath *)getPath:(NSDictionary *)polyline {
- (GMSMutablePath *)pathForPolyline:(NSDictionary *)polyline {
NSArray *pointArray = polyline[@"points"];
NSArray<CLLocation *> *points = [FLTGoogleMapJSONConversions pointsFromLatLongs:pointArray];
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was meant to be a question. I think it makes sense to leave it here or move it to polylines contoller neither of which are as per your suggestion of moving it to JsonConversions. Was asking what'd be better

@@ -1,3 +1,7 @@
## 2.3.6

* Adds support for patterns in polylines on iOS.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed 100%. Definitely resolved it accidentally, have made that change now

@stuartmorgan
Copy link
Contributor

I could also specify the internal array as an NSObject and then cast it explicitly. Not sure if that's any better though

For some reason GitHub won't let me respond inline to this, but yes, that would be better. It makes it explicit in the code that the array is heterogenous, which is unusual and thus better to have be as explicit as possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
6 participants