I was testing out the SwiftyJSON library this weekend, and got the following error when I tried to iterate over my JSONValue object – an array of dictionaries:
The issue is I forgot to call the array computed property on the my minionJSON value. This fixes the problem:
However, the above solution left me unsatisfied. I wanted to be able to iterate over my JSON array the way I naturally did it initially. So I started researching how I can make SwiftyJSON’s JSONValue enum conform to the Sequence protocol. I found two really great blog posts on the subject, parts of which I’m still trying to fully understand if I’m truly honest:
So I set out to write my own extension for the SONValue enum that conforms to the Sequence protocol. The Sequence protocol looks very simple:
Your class or enum just has to implement the generate() function that returns a Generator. If you click on the Generator in the documentation, you get the following protocol:
So the object that conforms to the Generator protocol has to implement a next() function that returns an Element. Simple, right?! (this is sarcastic in case it doesn’t come through).
Thanks to the blog posts I mentioned above, and a lot of failure, I came up with the following Generator:
I check to see if the JSONValue is an array, keep track of where in the sequence I am in the global indexInSequence variable, and return the element in that position in my jsonArray. If the JSONValue is not an array or the indexOfSequence is out of bounds, nil is returned. Pretty simple in retrospect…
So now, the JSONValue just needs to implement the Sequence protocol’s generate() function:
That’s it! I can now iterate over my JSONValue like I originally wanted to:
I’m still playing with Generators and Sequences, but it’s definitely something I’ll be considering implementing in my future classes and enums.
If you’d like to see my full sample project, the source code is on Github here.