JSON Schema is a powerful tool for defining the structure of JSON documents. Swift JSON Schema aims to make it easier to generate JSON schema documents directly in Swift.
Swift JSON Schema enables type-safe JSON schema generation directly in Swift.
Here's a simple example of a person schema.
{
"$id": "https://example.com/person.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Person",
"type": "object",
"properties": {
"firstName": {
"type": "string",
"description": "The person's first name."
},
"lastName": {
"type": "string",
"description": "The person's last name."
},
"age": {
"description": "Age in years which must be equal to or greater than zero.",
"type": "integer",
"minimum": 0
}
}
}
Let's create this schema directly in Swift. RootSchema
and Schema
types are used to define the schema structure. The RootSchema
type represents the root of the schema document, and the Schema
type represents a JSON schema object.
let schema = RootSchema(
id: "https://example.com/person.schema.json",
schema: "https://json-schema.org/draft/2020-12/schema",
subschema: .object(
.annotations(title: "Person"),
.options(
properties: [
"firstName": .string(
.annotations(description: "The person's first name.")
),
"lastName": .string(
.annotations(description: "The person's last name.")
),
"age": .integer(
.annotations(description: "Age in years which must be equal to or greater than zero."),
.options(minimum: 0)
)
]
)
)
)
Both Schema
and RootSchema
conform to Codable
for easy serialization
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try encoder.encode(self)
let string = String(decoding: data, as: UTF8.self)
or deserialization
let decoder = JSONDecoder()
let data = Data(json.utf8)
let schema = try decoder.decode(Schema.self, from: data)
Import the JSONSchemaBuilder
target and improve schema generation ergonomics with Swift's result builders.
@JSONSchemaBuilder var jsonSchema: JSONSchemaComponent {
JSONObject {
JSONProperty(key: "firstName") {
JSONString()
.description("The person's first name.")
}
JSONProperty(key: "lastName") {
JSONString()
.description("The person's last name.")
}
JSONProperty(key: "age") {
JSONInteger()
.description("Age in years which must be equal to or greater than zero.")
.minimum(0)
}
}
.title("Person")
}
let schema: Schema = jsonSchema.defintion
Use the @Schemable
macro from JSONSchemaBuilder
to automatically expand Swift types into JSON schema components.
@Schemable
struct Person {
let firstName: String
let lastName: String?
@NumberOptions(minimum: 0, maximum: 120)
let age: Int
}
The @Schemable
attribute automatically expands the Person
type into a JSON schema component.
struct Person {
let firstName: String
let lastName: String?
let age: Int
// Auto-generated schema ↴
static var schema: some JSONSchemaComponent<Person> {
JSONSchema(Person.init) {
JSONObject {
JSONProperty(key: "firstName") {
JSONString()
}
.required()
JSONProperty(key: "lastName") {
JSONString()
}
JSONProperty(key: "age") {
JSONInteger()
.minimum(0)
.maximum(120)
}
.required()
}
}
}
}
extension Person: Schemable {}
Additionally, @Schemable
can be applied to Swift enums.
@Schemable
enum Status {
case active
case inactive
// Auto-generated schema ↴
static var schema: JSONSchemaComponent {
JSONEnum {
"active"
"inactive"
}
}
}
Enums with associated values are also supported using anyOf
schema composition. See the JSONSchemaBuilder documentation for more information.
The full documentation for this library is available through the Swift Package Index.
You can add the SwiftJSONSchema package to your project using Swift Package Manager (SPM) or Xcode.
To add SwiftJSONSchema to your project using Swift Package Manager, add the following dependency to your Package.swift file:
dependencies: [
.package(url: "https://github.com/ajevans99/swift-json-schema", from: "0.2.1")
]
Then, include JSONSchema
and/or JSONSchemaBuilder
as a dependency for your target:
targets: [
.target(
name: "YourTarget",
dependencies: [
.product(name: "JSONSchema", package: "swift-json-schema"),
.product(name: "JSONSchemaBuilder", package: "swift-json-schema"),
]
)
]
- Open your project in Xcode.
- Navigate to File > Swift Packages > Add Package Dependency...
- Enter the repository URL: https://github.com/ajevans99/swift-json-schema
- Follow the prompts to add the package to your project.
Once added, you can import JSONSchema
in your Swift files and start using it in your project.
This library is in active development. If you have any feedback or suggestions, please open an issue or pull request.
Goals for future releases include:
- Support applying subschemas conditionally
- Support
$ref
and$defs
keywords - Root schema in result builders
- Support multiple types like
{ "type": ["number", "string"] }
- Validate JSON instances against schemas
- Parse JSON instances into Swift types and functions
This library is released under the MIT license. See LICENSE for details.