JSON to Swift Codable Converter
Generate Swift structs conforming to Codable from JSON, with convenience initializers for decoding.
Generate Swift Codable structs from JSON
Codable is the standard way to decode JSON in Swift, but writing the model structs for a large payload is tedious. This converter generates a struct conforming to Codable for each object, with let properties typed as Int, Double, String, Bool, nested structs and arrays. It adds a CodingKeys enum when a JSON key differs from the Swift property name, plus extensions with initializers that decode from Data, a JSON String or a URL, a with(...) method for making modified copies, and jsonData()/jsonString() for encoding back.
How to use
- Paste a JSON sample, such as the response your iOS or macOS app receives.
- Enter the root type name, for example Article.
- Add the file to your Xcode project and decode with try Article(jsonString) or JSONDecoder().decode(Article.self, from: data).
Frequently asked questions
- Does it work with SwiftUI and URLSession?
- Yes. The structs are plain Codable value types, so you can decode the Data returned by URLSession and pass the result to SwiftUI views like any other model.
- How are snake_case keys handled?
- Properties get Swift-style camelCase names (is_featured becomes isFeatured), and a CodingKeys enum maps each one to the original JSON key, so you do not need to set keyDecodingStrategy.
- Can I remove the convenience extensions?
- Yes. Only the struct declarations and CodingKeys are needed for Codable. The extensions and the newJSONDecoder/newJSONEncoder helpers are optional conveniences you can delete.
Example: JSON to Swift
Input JSON
{
"id": 3,
"title": "Hello Swift",
"author": { "name": "Taylor", "followers": 1200 },
"is_featured": true
}Generated Swift (Article)
// This file was generated from JSON Schema using quicktype, do not modify it directly.
// To parse the JSON, add this file to your project and do:
//
// let article = try Article(json)
import Foundation
// MARK: - Article
struct Article: Codable {
let id: Int
let title: String
let author: Author
let isFeatured: Bool
enum CodingKeys: String, CodingKey {
case id, title, author
case isFeatured = "is_featured"
}
}
// MARK: Article convenience initializers and mutators
extension Article {
init(data: Data) throws {
self = try newJSONDecoder().decode(Article.self, from: data)
}
init(_ json: String, using encoding: String.Encoding = .utf8) throws {
guard let data = json.data(using: encoding) else {
throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)
}
try self.init(data: data)
}
init(fromURL url: URL) throws {
try self.init(data: try Data(contentsOf: url))
}
func with(
id: Int? = nil,
title: String? = nil,
author: Author? = nil,
isFeatured: Bool? = nil
) -> Article {
return Article(
id: id ?? self.id,
title: title ?? self.title,
author: author ?? self.author,
isFeatured: isFeatured ?? self.isFeatured
)
}
func jsonData() throws -> Data {
return try newJSONEncoder().encode(self)
}
func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
return String(data: try self.jsonData(), encoding: encoding)
}
}
// MARK: - Author
struct Author: Codable {
let name: String
let followers: Int
}
// MARK: Author convenience initializers and mutators
extension Author {
init(data: Data) throws {
self = try newJSONDecoder().decode(Author.self, from: data)
}
init(_ json: String, using encoding: String.Encoding = .utf8) throws {
guard let data = json.data(using: encoding) else {
throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)
}
try self.init(data: data)
}
init(fromURL url: URL) throws {
try self.init(data: try Data(contentsOf: url))
}
func with(
name: String? = nil,
followers: Int? = nil
) -> Author {
return Author(
name: name ?? self.name,
followers: followers ?? self.followers
)
}
func jsonData() throws -> Data {
return try newJSONEncoder().encode(self)
}
func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
return String(data: try self.jsonData(), encoding: encoding)
}
}
// MARK: - Helper functions for creating encoders and decoders
func newJSONDecoder() -> JSONDecoder {
let decoder = JSONDecoder()
if #available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *) {
decoder.dateDecodingStrategy = .iso8601
}
return decoder
}
func newJSONEncoder() -> JSONEncoder {
let encoder = JSONEncoder()
if #available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *) {
encoder.dateEncodingStrategy = .iso8601
}
return encoder
}