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
Feature - Parameter Encoding Protocol #1465
Conversation
} catch { | ||
encodingError = error | ||
if let method = HTTPMethod(rawValue: urlRequest.httpMethod!), encodesParametersInURL(with: method) { | ||
if var URLComponents = URLComponents(url: urlRequest.url!, resolvingAgainstBaseURL: false), !parameters.isEmpty { |
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 didn't think if var
was still in Swift 3. Are we sure all of the IUOs here are safe? Or should it be part of the error handling?
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.
Not sure offhand. I didn't change any of this logic directly. Will take another deep look. 👍🏼
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.
Addressed in 8ce9088.
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, and if var thing
is still allowed in if
statements. I think it's only been removed from function signatures.
@cnoon Looks great, just a few comments. Also, how would this interact with the |
I agree @jshier, but unfortunately it's not possible to pass it down through the request cycle. I posted a big description of the limitations in our Slack channel. We should probably have that discussion over a call. Long story short is that we can't because the only way to push the error down is to actually make (and execute) some request. That causes all sorts of issues. |
I remember, just didn't realize the same thing applied here as well. I'll give it more thought and we can make the improvement later. |
… structs. This ends up making a much more flexible set of APIs overall that are much easier to extend.
26190ed
to
6a1e267
Compare
All comments have been addressed here @jshier...thanks for the good catches! I'm going to go ahead and merge this. |
This PR is an alternative to #1464 that goes WAY further in refactoring the
ParameterEncoding
logic into a protocol instead of an enumeration.Motivation
The
ParameterEncoding
enum hasn't been flexible enough to allow us to customize the behavior of a particular encoding type. For example, we had to introduce the new.urlEncodedInURL
case just to allow users to be able to force the parameters into the query string when their backends required them to do so on aPOST
orPUT
.The enum also doesn't allow us to open up different writing options for the JSON and plist serializers. We can't customize plist formats, etc. The list goes on and on since we're locked to the enum that can't add extra cases or associated values in a backwards compatible manner.
Solution
Get rid of the enumeration altogether! Now the
ParameterEncoding
type of a protocol backed by concreteURL
,JSON
andPropertyList
conforming structs.It was amazing after I split everything up how much sense it really makes.
ParameterEncoding
implementations are now free of the enumeration bounds and are free to customize to their own needs.URLEncoding
The
.url
and.urlEncodedInURL
cases have now been combined in theURLEncoding
struct with some new enumerations and properties of it's own.I added convenience properties for accessing instances without having to go through the initializer. This was a nice touch. We could actually hide the initializer if we wanted, but I figured that was a step too far.
JSONEncoding
The
JSONEncoding
struct is much less complicated than theURLEncoding
struct for obvious reasons.PropertyListEncoding
The
PropertyListEncoding
struct is very similar to theJSONEncoding
struct, just with a few more properties.Wrapping Up Parameters with Encoding
So I tried for probably 2 hours to work the parameters and the encoding into a single type. I had
Parameters
as the protocol andURLParameters
,JSONParameters
, etc. and you'd create the object likeURLParameters(parameters)
and call it like so:Part of this was great because it got rid of the
encoding
parameter altogether which I was all for. However, it greatly increased the majority of our calls because it can't rely on the default parameter value of.url
anymore. So we end up having to writeURLParameters(parameters)
everywhere instead of justparameters
. Not to mention it just feels a little off.Because of all of this, I finally decided enough was enough and it was just a square peg, round hole scenario. Once I backed away, I was able to finally land on the solution you see here.
Throwing vs. Double Tuple
This also includes all the changes to the
encode
method itself which was part of the previous PR. These changes should definitely be adopted in AF 4. It's time to eliminate the last odd double optional case we have left! 🙌🏼🏆Summary
Overall, I think this is an awesome set of changes for AF 4. It makes it so much easier to create your own custom
ParameterEncoding
type. It also rids the world of the.urlEncodedInURL
case that I sadly had to introduce a year ago.