1. Home
  2. Developer tools
  3. JSON to Swift Codable

JSON to Swift Codable

Paste an API response and get Codable structs for an iOS or macOS app, with CodingKeys written for you.

Free, no sign-up. Runs in your browser: nothing is uploaded.

How to use JSON to Swift Codable

  1. Paste JSON.
  2. Name the root struct.
  3. Copy the structs into Xcode.

Features

  • Codable and Equatable structs, one per shape
  • CodingKeys enum only where a key is renamed
  • Optionals for optional and null fields
  • Int, Double, Bool, String and arrays
  • Date with an .iso8601 decoding note when date types are on

Supported formats

You can open

  • JSON
  • JSON Lines
  • Typed or pasted text

You get

  • SWIFT
  • Copied text

Private by design

Your files are opened and processed by your browser on this device. They are never uploaded to openWorkstand or anyone else, so the JSON to Swift Codable is safe for contracts, IDs, photos and work documents. After you have used it once while online, it also works without an internet connection. How local processing works

Good to know

  • Types are inferred from the samples given; paste several varied samples for accurate optional fields.

Guide

Swift Codable structs from an API response

Swift’s Codable turns JSON into typed values with a single call, but only once you have written structs that match the data exactly — every key, every optional, every nested type. This generator writes them from a sample, including the CodingKeys that map Swift-style names onto snake_case or hyphenated keys.

How Codable decoding works

A type that conforms to Codable can be created by JSONDecoder: let user = try JSONDecoder().decode(User.self, from: data). Swift synthesises the decoding code from the stored properties, so the property names, types and optionality must match the JSON. If they do not, decoding throws a DecodingError that names the key path, which is far more useful than a crash later.

CodingKeys only where needed

Swift style is camelCase, so order_id becomes orderId. Codable needs to know about that difference, and the generator writes a CodingKeys enum mapping each property to its key — but only in structs where some key actually differs, keeping simple structs short. If every key in your API is snake_case, you can delete the enums and set decoder.keyDecodingStrategy = .convertFromSnakeCase instead; hyphenated keys still need explicit keys.

Optionals

Keys missing from some samples and values that were sometimes null become optionals, such as let coupon: String?. Synthesised decoding treats a missing key and a null value the same for optionals, so either case decodes to nil. Non-optional properties make decoding fail when the key is missing, which is what you want for fields your app cannot work without.

Mixed types and JSONValue

Swift has no built-in “any JSON” type. When a field was always null or had different types in different samples, the generator uses JSONValue, a small enum that decodes strings, numbers, booleans, arrays, objects and null, and appends its implementation to the output. Switch over it to read the value once you know what it contains.

Dates

With date types on, ISO 8601 timestamps become Date, and a comment reminds you to set decoder.dateDecodingStrategy = .iso8601. Fractional seconds need a custom formatter, because the built-in ISO 8601 strategy rejects them.

A worked example

The sample user produces User, Order, Item and Address. Order gets a CodingKeys enum with case orderId = "order_id", its coupon is String?, and because the address’s unit is null in the sample, the output includes the JSONValue helper for it.

Using the models

With async URLSession: let (data, _) = try await URLSession.shared.data(from: url) then decode. In SwiftUI, load the value in a .task modifier and store it in @State; Equatable conformance lets SwiftUI avoid redundant redraws.

Root arrays and wrapped responses

When the JSON is an array, the root struct describes one element; decode with [User].self. When results are wrapped, as in { "data": [...], "meta": {...} }, paste the whole response: the wrapper becomes the root struct and the inner objects get their own, so paging metadata is decoded too.

Keeping models in sync

APIs change. Keep a sample response in your test bundle and decode it in a unit test; when the provider renames a key or changes a type, the failing test points to the exact key path long before users see a broken screen.

Create the Android models with JSON to Kotlin, Flutter classes with JSON to Dart, web types with JSON to TypeScript, or format the sample with the JSON Formatter.

Checked against the current version of the JSON to Swift Codable on .

Troubleshooting

The file does not open

Check that it is one of the supported formats above and opens in another app. Damaged files and password-protected PDFs cannot be read until they are repaired or unlocked.

It is slow or stops on a very large file

Everything runs on your device, so speed depends on its memory. Close other tabs, use a computer rather than a phone, or split the file into smaller parts first.

The download did not start

Look for your browser’s download bar or icon. Some browsers ask once before a site may download files; allow it and click the button again.

Frequently asked questions

Why are the properties let and not var?

Decoded API data is usually read, not edited, and constants make structs safer to share between views and threads. Change a property to var if your app edits that value locally.

What happens if the API sends a number as a string?

Decoding fails with a typeMismatch error naming the key. Either change the property to String, or write a custom init(from:) for that struct that tries both types.

Do I need Equatable?

It is optional but useful: SwiftUI can skip redrawing views when an Equatable value has not changed, and tests can compare decoded values directly. Remove it if a property type is not Equatable.

Can I avoid writing CodingKeys?

If every key is snake_case, set decoder.keyDecodingStrategy = .convertFromSnakeCase and delete the CodingKeys enums. Keys with hyphens or unusual names still need explicit CodingKeys.

What is the JSONValue enum for?

Swift needs a concrete type for every property. When a field holds different types in different samples, JSONValue can decode any JSON value safely; switch on it to read the value.

Keep working with the result

openWorkstand also includes a free workspace with documents, spreadsheets, tasks, projects and a calendar that save to a folder on your computer.