Well, for the most part. As of today's writing, iOS 11 is going to be released to the public tomorrow which (should) mean Xcode 9 will be released to the App Store as well. That means a ton of Swift 4 goodness, and the one I'm most excited about it the new protocol Codable.

Apple describes Codable as "a type that can convert itself into and out of an external representation." Basically what this means for us is that we can take JSON and convert it into one of our objects or structs that conform to Codable and then take it and convert it back to JSON with no problem. JSON parsing in Swift has been a pain for awhile now, and our best way of handling it was something like this:


extension HubbleImageData {
    convenience init?(json: [String: Any]) {
        
        struct Key {
            static let id = "artistName"
            static let name = "name"
            static let newsName = "news_name"
            static let collection = "collection"
            static let mission = "mission"
        }
        
        guard let id = json[Key.id] as? Int,
            let name = json[Key.name] as? String,
            let newsName = json[Key.newsName] as? String,
            let collection = json[Key.collection] as? String,
            let mission = json[Key.mission] as? String else {
                return nil
        }
        
        
        self.init(id: id, name: name, newsName: newsName, collection: collection, mission: mission)
    }
}

Major pain. This is just an extension on top of our HubbleImageData struct and doesn't include the actual init method or our struct's properties.

So what would this look like if we used Codable on Swift 4? Let's take a look.

struct HubbleImageData: Codable {
    let id: Int
    let name: String
    let newsName: String
    let collection: String
    let mission: String
    
    enum CodingKeys: String, CodingKey {
        case id
        case name
        case newsName = "news_name"
        case collection
        case mission
    }
}

That's the entirety of our HubbleImageData struct. No need for a convenience initializer or even a custom init method. Our struct is good to go. So how will we use this?

This is an example of how we would handle our JSON and Codable conformant structs in the callback function of a standard URLSession data task:

if let data = data {
	let decoder = JSONDecoder()
    do {
        let hubbleImageData = try! decoder.decode([HubbleImageData].self, from: data)
        DispatchQueue.main.async {
            completion(hubbleImageData, nil)
        }
    } catch (let e) {
        // FIXME: - In real life do actual error handling!
        fatalError(e.localizedDescription)
    }
}

You'll notice that in the decode method I pass the decoder an array of HubbleImageData, and the reasoning behind that is the Hubble Imagery API sends us an array of JSON objects. By passing the array of HubbleImageData as the method's parameter, the decoder will return that back to us with actual data.

This is why I'm so excited about Codable! JSON parsing in Swift has been something I haven't looked forward to in the past. I'm not a fan of pulling packages into my code if I don't absolutely need to, so for me using SwiftyJSON (or even Alamofire for that matter) just isn't something I want to do most of the time. I don't judge anyone who does, it's just not for me. Codable is going to make the lives of all of us much easier, so go give it a shot!

Here's to cleaner codebases. :)

P.S. If you want more information on how to use Codable, I highly recommend this article by Ben Scheirman. This is how I learned how to use Codable in the first place and is a great resource on everything from just starting out to handling edge cases. Good luck, and happy coding!