In our previous versions of parser, there is no support for optionals. If any key transformation fails or if any key is missing or if the response contains
nil values for keys, the whole parsing fails. This is not desired in most of the situations.
Posts in this series:
To handle the above cases, we need to add support for Optionals.
Following is the JSON that we want to parse:
If you observe carefully, there are 2 small (yet breaking) changes from our previous version:
- For the 1st person,
addressdoesn’t have a
streetand as per our requirements, this is an invalid address
- For the 2nd person,
namekey is missing, which again leads to an invalid person
In both the cases, parsing will fail by returning
nil objects. Let’s modify our
Customer model to handle this
nil value by making
address property optional. Also, change the curried function so that it now takes an optional
We’ve used our custom operator
<*> till now to push values into our curried model initializers. Unfortunately, it doesn’t support optional values (see the definition, it performs
f(x) only if both
x are present).
<*> with optional support didn’t help, Swift compiler got stuck for a very long duration during compilation. So I had to define a new operator
<?> for this.
Please let me know if you can get this to work without creating a new operator.
This new operator
<?> does almost same job as
x can be an optional now. Because our function
f accepts an optional value, the operator just passes the optional value
x directly to
Now that we’ve defined our new operator to handle Optional values, lets parse the model:
The above code will parse the JSON into
Customer model and if it couldn’t create
Address model, it simply assigns
nil value to address property of
There is one slight problem with this approach. This will only work if the whole property is optional ie.,
T?. You cannot have a property of type
[T?] ie., array of Optional values. I’m experimenting few ideas (mostly not involving custom operators).
Please feel free to comment below, if you have suggestions and questions.
You can find the whole source code as Gist on GitHub