JSON Structure is a data structure definition language that enforces strict typing, modularity, and determinism.
A Swift SDK for JSON Structure schema and instance validation. JSON Structure is a type-oriented schema language for JSON, designed for defining data structures that can be validated and mapped to programming language types.
The validators (InstanceValidator and SchemaValidator) are thread-safe and conform to Sendable, making them safe for concurrent use with Swift concurrency and multiple threads.
Both validators are value types (structs) containing only immutable configuration. Each validation operation creates a fresh internal engine with its own mutable state, ensuring complete isolation between concurrent validations.
let validator = InstanceValidator()
// Safe to use from multiple threads
DispatchQueue.concurrentPerform(iterations: 100) { i in
let result = validator.validate(instances[i], schema: schema)
// Each validation gets its own isolated state
}
The validators work seamlessly with Swift’s structured concurrency:
let validator = InstanceValidator()
// Safe concurrent validation with Task groups
await withTaskGroup(of: ValidationResult.self) { group in
for (instance, schema) in validationPairs {
group.addTask {
validator.validate(instance, schema: schema)
}
}
for await result in group {
// Process results as they complete
if !result.isValid {
print("Validation failed: \(result.errors)")
}
}
}
Add the following to your Package.swift file:
dependencies: [
.package(url: "https://github.com/json-structure/sdk", from: "1.0.0")
]
Then add JSONStructure to your target dependencies:
.target(
name: "YourTarget",
dependencies: ["JSONStructure"]
)
The Swift SDK uses git tags for versioning, which is the standard approach for Swift Package Manager (SPM). No separate publish step is required.
When you specify a version dependency in your Package.swift:
.package(url: "https://github.com/json-structure/sdk", from: "1.0.0")
Swift Package Manager:
v1.0.0 or 1.0.0)Package.swiftReleases are tagged following semantic versioning:
v1.0.0 - Major releasev1.1.0 - Minor release with new featuresv1.1.1 - Patch release with bug fixes// Minimum version (recommended)
.package(url: "https://github.com/json-structure/sdk", from: "1.0.0")
// Exact version
.package(url: "https://github.com/json-structure/sdk", exact: "1.2.3")
// Version range
.package(url: "https://github.com/json-structure/sdk", "1.0.0"..<"2.0.0")
// Branch (for development)
.package(url: "https://github.com/json-structure/sdk", branch: "main")
Validate that a JSON Structure schema document is syntactically and semantically correct:
import JSONStructure
let validator = SchemaValidator()
let schema: [String: Any] = [
"$id": "urn:example:person",
"name": "Person",
"type": "object",
"properties": [
"name": ["type": "string"],
"age": ["type": "int32"]
],
"required": ["name"]
]
let result = validator.validate(schema)
if result.isValid {
print("Schema is valid!")
} else {
for error in result.errors {
print("Error at \(error.path): \(error.message)")
}
}
Validate JSON data instances against a JSON Structure schema:
import JSONStructure
let schema: [String: Any] = [
"$id": "urn:example:person",
"name": "Person",
"type": "object",
"properties": [
"name": ["type": "string"],
"age": ["type": "int32"]
],
"required": ["name"]
]
let instance: [String: Any] = [
"name": "John Doe",
"age": 30
]
let validator = InstanceValidator()
let result = validator.validate(instance, schema: schema)
if result.isValid {
print("Instance is valid!")
} else {
for error in result.errors {
print("Error at \(error.path): \(error.message)")
}
}
You can also validate from JSON strings or data:
import JSONStructure
let schemaJSON = """
{
"$id": "urn:example:greeting",
"name": "Greeting",
"type": "string"
}
"""
let schemaValidator = SchemaValidator()
let schemaResult = try schemaValidator.validateJSONString(schemaJSON)
let instanceValidator = InstanceValidator()
let instanceResult = try instanceValidator.validateJSONStrings(
"\"Hello, World!\"",
schemaString: schemaJSON
)
Enable extended validation features for constraint keywords:
import JSONStructure
let schema: [String: Any] = [
"$id": "urn:example:username",
"$uses": ["JSONStructureValidation"],
"name": "Username",
"type": "string",
"minLength": 3,
"maxLength": 20,
"pattern": "^[a-zA-Z][a-zA-Z0-9_]*$"
]
let validator = InstanceValidator(options: InstanceValidatorOptions(extended: true))
let result = validator.validate("user123", schema: schema)
Use allOf, anyOf, oneOf, not, and if/then/else:
import JSONStructure
let schema: [String: Any] = [
"$id": "urn:example:stringOrNumber",
"$uses": ["JSONStructureConditionalComposition"],
"name": "StringOrNumber",
"anyOf": [
["type": "string"],
["type": "int32"]
]
]
let validator = InstanceValidator(options: InstanceValidatorOptions(extended: true))
// Both are valid
let result1 = validator.validate("hello", schema: schema) // valid
let result2 = validator.validate(42, schema: schema) // valid
let result3 = validator.validate(true, schema: schema) // invalid
| Type | Description |
|---|---|
string |
UTF-8 string |
boolean |
true or false |
null |
Null value |
number |
Any JSON number |
integer |
Alias for int32 |
int8, int16, int32, int64, int128 |
Signed integers |
uint8, uint16, uint32, uint64, uint128 |
Unsigned integers |
float, float8, double, decimal |
Floating-point numbers |
date |
Date in YYYY-MM-DD format |
time |
Time in HH:MM:SS format |
datetime |
ISO 8601 datetime |
duration |
ISO 8601 duration |
uuid |
RFC 9562 UUID |
uri |
RFC 3986 URI |
binary |
Base64-encoded bytes |
jsonpointer |
RFC 6901 JSON Pointer |
| Type | Description |
|---|---|
object |
JSON object with typed properties |
array |
Homogeneous list |
set |
Unique homogeneous list |
map |
Dictionary with string keys |
tuple |
Fixed-length typed array |
choice |
Discriminated union |
any |
Any JSON value |
The SDK uses standardized error codes for consistent error reporting. Common error codes include:
SCHEMA_TYPE_INVALID - Invalid type nameSCHEMA_REF_NOT_FOUND - $ref target does not existSCHEMA_ARRAY_MISSING_ITEMS - Array requires ‘items’ schemaSCHEMA_MAP_MISSING_VALUES - Map requires ‘values’ schemaINSTANCE_TYPE_MISMATCH - Value does not match expected typeINSTANCE_REQUIRED_PROPERTY_MISSING - Required property is missingINSTANCE_ENUM_MISMATCH - Value not in enumINSTANCE_CONST_MISMATCH - Value does not match constpublic class SchemaValidator {
public init(options: SchemaValidatorOptions = SchemaValidatorOptions())
public func validate(_ schema: Any) -> ValidationResult
public func validateJSON(_ jsonData: Data) throws -> ValidationResult
public func validateJSONString(_ jsonString: String) throws -> ValidationResult
}
public class InstanceValidator {
public init(options: InstanceValidatorOptions = InstanceValidatorOptions())
public func validate(_ instance: Any, schema: Any) -> ValidationResult
public func validateJSON(_ instanceData: Data, schemaData: Data) throws -> ValidationResult
public func validateJSONStrings(_ instanceString: String, schemaString: String) throws -> ValidationResult
}
public struct ValidationResult {
public let isValid: Bool
public let errors: [ValidationError]
public let warnings: [ValidationError]
}
public struct ValidationError {
public let code: String
public let message: String
public let path: String
public let severity: ValidationSeverity
public let location: JsonLocation
}
MIT License - see LICENSE for details.