Skip to content

JSON Validator — Swift source

Validate JSON and pinpoint errors with line and column numbers. Clear valid/invalid verdict plus the exact error location - runs entirely in your browser.

This is the Swift implementation — the same logic the interactive tool runs, in a shareable, citable form.

// json-validator — Swift port using Foundation's JSONSerialization, ported from src/lib/jsonValidate.ts.
import Foundation

/// Mirrors the TypeScript result shape; nil line/column = no position.
struct ValidationResult: CustomStringConvertible {
    let valid: Bool
    let error: String?
    let line: Int?
    let column: Int?

    var description: String {
        if valid { return "valid" }
        if let line, let column { return "invalid: \(error ?? "") (line \(line), column \(column))" }
        return "invalid: \(error ?? "")"
    }
}

/// Validate JSON. Never traps.
/// Foundation reports no character offset in its parse errors (the same
/// contract as the JS port on JavaScriptCore), so the location stays nil.
func validateJSON(_ text: String) -> ValidationResult {
    guard !text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else {
        return ValidationResult(valid: false, error: "Input is empty", line: nil, column: nil)
    }
    guard let data = text.data(using: .utf8) else {
        return ValidationResult(valid: false, error: "Input is not valid UTF-8", line: nil, column: nil)
    }
    do {
        _ = try JSONSerialization.jsonObject(with: data) // decoded value not needed
        return ValidationResult(valid: true, error: nil, line: nil, column: nil)
    } catch {
        return ValidationResult(valid: false, error: error.localizedDescription, line: nil, column: nil)
    }
}

// Demo: {"a": [1, 2, {"b": null}]} is valid; a stray comma is not.
for sample in ["{\"a\": [1, 2, {\"b\": null}]}", "{\n  \"a\": ,\n}"] {
    print(validateJSON(sample))
}

Also available in 13 other languages

Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →