-
Notifications
You must be signed in to change notification settings - Fork 48
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
Fix batch geocoding request handling #148
Conversation
/** | ||
The query mode of the forward or reverse geocoding request. | ||
*/ | ||
internal var mode: String = "mapbox.places" |
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: String
can be inferred from the value on the right-hand side, so it can be removed.
MapboxGeocoder/MBGeocoder.swift
Outdated
} | ||
let mode = options.mode | ||
|
||
assert(options.queries.count <= 50, "Too many queries in a single request.") |
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.
Assuming the Geocoding API returns an error when putting over 50 queries in a single batch, we should remove this assertion so that the more graceful error handler can kick in.
Things seem to be operational now, but I'll need to add a good chunk of tests before calling this PR finished. |
DispatchQueue.main.async { | ||
errorHandler(error as NSError) | ||
// Handle single & single batch geocoding queries | ||
do { |
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.
Per chat with @1ec5 we may want to consider doing a refactor of this gnarly do/try/catch block.
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.
Great work! We’ll be ready to merge once there are tests of forward and reverse batch geocoding, including of small-batch geocoding. The diff for this PR will be a little nicer once I merge #149 and this PR is rebased atop that one.
MapboxGeocoder/MBGeocoder.swift
Outdated
do { | ||
let result = try decoder.decode(GeocodeAPIResult.self, from: data) | ||
// Check if geocoding query failed | ||
guard result.message == nil else { |
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: We can also turn this guard
statement into an if let
so that the line below doesn’t have to force-unwrap result.message
.
result = try decoder.decode([GeocodeResult].self, from: data) | ||
} catch { | ||
// Decode single batch geocding queries | ||
result = [try decoder.decode(GeocodeResult.self, from: 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.
As tail work, maybe we should consider refactoring Geocoder’s public methods so that we distinguish between single-serving and batched requests at different places in the call stack.
} | ||
} | ||
|
||
func testInvalidForwardSingleBatchGeocode() { |
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.
@1ec5 both testInvalidForwardSingleBatchGeocode
/ testInvalidForwardMultipleBatchGeocode
tests are commented out because they are failing. I'm actually seeing the same error the original issue described - Expected to decode Array<Any> but found a dictionary instead.
🤔
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.
Which decode step is failing? If the step that tries to look for a message
in a dictionary in an array ([GeocoderAPIResult]
) is failing, then we need to make sure the fallback that looks for message
in a dictionary (GeocoderAPIResult
) is working. If the step that tries to decode an array of individual results ([GeocoderResult]
) is failing, then we should make sure the fallback that looks for a bare result (GeocoderResult
) is working.
@1ec5 thanks for helping me get unstuck on the failing invalid batch geocoding test. For those following along, it seems like OHHTTP already encodes queries so there was no need to encode it before passing it in. I was able to add the rest of the tests for batch geocoding and also tested token validity. As a next step, I'll start the reverse batch geocoding tests, which should be fairly similar. I've also rebased this on master now that #149 has merged. |
725a1c2
to
ddda4f5
Compare
_ = stub(condition: isHost("api.mapbox.com") | ||
|
||
// && isPath("/geocoding/v5/mapbox.places-permanent/100,100.json") | ||
// The above line is causing the test fo fail for unknown reasons |
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.
@1ec5 I've added the reverse batch geocoding tests but I'm seeing the weird behavior with OHTTPS isPath
again - I get test failures if I include the line above for both reverse batch geocoding tests that return no results. The tests pass if I remove this line though 🤕
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.
Does the URL match exactly? Or does urlForGeocoding(_:)
translate CLLocationCoordinate2DMake(100, 100)
into something else, such as 100.0,100.0
?
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.
Oh! Yeah, it looks like urlForGeocoding(_:)
is turning this into 100.00000,100.00000
.
@1ec5 I feel good about this now, would you mind doing a final review? |
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.
Looks good, assuming the build failures are only due to the missing file reference.
_ = stub(condition: isHost("api.mapbox.com") | ||
&& isPath("/geocoding/v5/mapbox.places-permanent/85+2nd+st+san+francisco.json") | ||
&& containsQueryParams(["access_token": invalidToken])) { _ in | ||
let path = Bundle(for: type(of: self)).path(forResource: "permanent_invalid_token", ofType: "json") |
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.
Tests are failing:
Testing failed:
error: /Users/Desktop/permanent_invalid_token.json: No such file or directory
error: /Users/Desktop/permanent_reverse_multiple_no_results.json: No such file or directory
Did you add these files to the iOS and tvOS test targets as well? (There’s no watchOS test target.)
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.
Looks like I forgot to Copy items if needed
when adding these fixtures to the project 😬
@@ -170,6 +206,18 @@ | |||
/* End PBXCopyFilesBuildPhase section */ | |||
|
|||
/* Begin PBXFileReference section */ | |||
0711239220E59DE90043CB51 /* permanent_forward_single_valid.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = permanent_forward_single_valid.json; path = ../../../../.Trash/permanent_forward_single_valid.json; sourceTree = "<group>"; }; |
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 file is located in the Trash on your Mac, which Bitrise has no access to.
Fixes #147.
Improves handling of logic around setting the desired Mapbox Geocoding API endpoint when using MBGeocodeOptions.
cc @kbauhaus