Search code examples
swiftalamofire

Decoding an API response in Swift


I'm using Alamofire to decode objects, and my JSON looks like this

{
  "wallet": {
    "public_key": "ADDRESS",
    "name": "My test wallet",
    "id": "-MQ9NdAyMaK3WQfSOYZW",
    "owner": "Kca8BNHy8FemIxPO7FWBSLE8XKN2",
    "currency": "ME",
    "metadata": {
      "legacy_address": "WHAT",
      "x_pub_address": "SOMETHING COOL"
    }
  },
  "secrets": {
    "wif": "SOMETHING",
    "private_key": "SOMETHING ELSE",
    "mnemonic": "YOU WISH"
  }
}

My Swift looks like this:

class Response: Codable {

   var wallet: Wallet
   var secrets: [String: String]
}

class Wallet: Codable {
   var publicKey: String
   var name: String
   var id: String
   var owner: String
   var currency: String
   var metadata: [String: String]

   enum WalletKeys: String, CodingKey{
      case publicKey = "public_key",
      case name, 
      case id 
      case owner, 
      case currency,
      case metadata
   }
}

I'm getting a keyNotFound(CodingKeys(stringValue: "publicKey")) error, and I dont know why. Can someone help me figure this out?


Solution

  • You need to set your decoder keyDecodingStrategy property value to .convertFromSnakeCase:


    struct Response: Codable {
        let wallet: Wallet
        let secrets: Secrets
    }
    

    struct Secrets: Codable {
        let wif: String
        let privateKey: String
        let mnemonic: String
    }
    

    struct Wallet: Codable {
        let publicKey: String
        let name: String
        let id: String
        let owner: String
        let currency: String
        let metadata: Metadata
    }
    

    struct Metadata: Codable {
        let legacyAddress: String
        let xPubAddress: String
    }
    


    let json = """
    {
      "wallet": {
        "public_key": "ADDRESS",
        "name": "My test wallet",
        "id": "-MQ9NdAyMaK3WQfSOYZW",
        "owner": "Kca8BNHy8FemIxPO7FWBSLE8XKN2",
        "currency": "ME",
        "metadata": {
          "legacy_address": "WHAT",
          "x_pub_address": "SOMETHING COOL"
        }
      },
      "secrets": {
        "wif": "SOMETHING",
        "private_key": "SOMETHING ELSE",
        "mnemonic": "YOU WISH"
      }
    }
    """
    

    do {
        let decoder = JSONDecoder()
        decoder.keyDecodingStrategy = .convertFromSnakeCase
        let root = try decoder.decode(Response.self, from: Data(json.utf8))
        print(root)
    } catch {
        print(error)
    }
    

    This will print:

    Response(wallet: Wallet(publicKey: "ADDRESS", name: "My test wallet", id: "-MQ9NdAyMaK3WQfSOYZW", owner: "Kca8BNHy8FemIxPO7FWBSLE8XKN2", currency: "ME", metadata: Metadata(legacyAddress: "WHAT", xPubAddress: "SOMETHING COOL")), secrets: __lldb_expr_1.Secrets(wif: "SOMETHING", privateKey: "SOMETHING ELSE", mnemonic: "YOU WISH"))