I am receiving JSON from a service API (Airtable) that returns an object with a single key records which is an array of objects. These objects have most of their information in a nested object called fields . Like so:

    "records": [
            "id": "recC3HgjwICxlg9CE",
            "fields": {
                "Title": "Software engineer",
                "Name": "Cameron Toth",

I wrote a function (currently an extension to Data, will move to i.e. Alamofire) that returns a flattened JSON list, with fields keys moved to the parent object, optionally remapping key names.

I'd especially appreciate feedback on my use of guard/let/throw

extension Data {
    func airtableFlattenedJson(_ mapping: [String: String]? = nil) throws -> [[String : Any]] {
        let json = try JSONSerialization.jsonObject(with: self, options: [])
        guard let casted = json as? [String: [[String: Any]]] else { throw AirtableParsingError.jsonCouldNotCast }
        guard var records = casted["records"] else { throw AirtableParsingError.noRecordsFound }
        for (index, record) in records.enumerated() {
            var updated = record
            guard let fields = record["fields"] as? [String: Any] else { continue }
            for (key, value) in fields {
                if let mapped = mapping?[key] {
                    updated[mapped] = value
                } else {
                    updated[key] = value
            updated.removeValue(forKey: "fields")
            records[index] = updated
        return records

enum AirtableParsingError: Error {
    case jsonCouldNotCast
    case noRecordsFound
  • 1
    \$\begingroup\$ why are you not using jsondecoder class to parse the JSON? \$\endgroup\$
    – Suryakant
    Jan 5 '20 at 18:35
  • \$\begingroup\$ 1. Why you didn't create separate custom class AirtableRecord and parse data to array of AirtableRecord 2. I would vote for parsing all fields to appropriate properties of model \$\endgroup\$ Jan 8 '20 at 19:44
  • \$\begingroup\$ @VitaliyGozhenko @Suryakant the code consuming this result expects an array of [String: Any] dictionaries \$\endgroup\$
    – Martin
    Jan 9 '20 at 21:46
  • \$\begingroup\$ Are the keys in the fields field always the same ? as in, are they always the same object (title, name, ...)? \$\endgroup\$
    – Skwiggs
    Mar 17 '20 at 8:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.