JSON
CloneableJSON Documentation
The CloneableJSON
struct provides a flexible way to work with JSON-like data structures in Swift, allowing for schema validation and easy manipulation of nested data. This documentation will focus on using CloneableJSON with the provided schema for a measure pole task list.
JSON Schema Guide
Schema GuideSchema
The schema we'll be working with is as follows:
{
"measure_pole_task_list": {
"type": "array",
"description": "Array of tasks associated with the pole",
"array_type": "object",
"properties": {
"id": {
"type": "string",
"description": "Id of the task or attachment"
},
"name": {
"type": "string",
"description": "Name of the task to be performed on the pole"
},
"inspection_phase": {
"type": "string",
"description": "Phase of the inspection this task will be presented. ar or photo"
},
"design_height": {
"type": "number",
"description": "Expected height for the task in meters"
},
"actual_height": {
"type": "number",
"description": "The actual measured height in meters"
},
"status": {
"type": "string",
"description": "Status of the item"
}
}
}
}
Creating a CloneableJSON instance
To create a CloneableJSON instance with this schema:
let schema = """
{
"measure_pole_task_list": {
"type": "array",
"description": "Array of tasks associated with the pole",
"array_type": "object",
"properties": {
"id": {
"type": "string",
"description": "Id of the task or attachment"
},
"name": {
"type": "string",
"description": "Name of the task to be performed on the pole"
},
"inspection_phase": {
"type": "string",
"description": "Phase of the inspection this task will be presented. ar or photo"
},
"design_height": {
"type": "number",
"description": "Expected height for the task in meters"
},
"actual_height": {
"type": "number",
"description": "The actual measured height in meters"
},
"status": {
"type": "string",
"description": "Status of the item"
}
}
}
}
"""
do {
let cloneableJSON = try CloneableJSON(schema: schema)
print("CloneableJSON instance created successfully")
} catch {
print("Error creating CloneableJSON: \(error)")
}
Working with CloneableJSON
Creating the Measure Pole Task List
To create the measure pole task list according to the schema:
let cloneableJSON = try CloneableJSON(schema: schema)
// Initialize the measure_pole_task_list as an empty array
cloneableJSON.value = .object(["measure_pole_task_list": .array([])])
// Create a task
let task: [String: CloneableJSONValue] = [
"id": .value(AnyCloneableData(data: CloneableString("task1"))),
"name": .value(AnyCloneableData(data: CloneableString("Measure pole height"))),
"inspection_phase": .value(AnyCloneableData(data: CloneableString("ar"))),
"design_height": .value(AnyCloneableData(data: CloneableNumber(10.5))),
"actual_height": .value(AnyCloneableData(data: CloneableNumber(10.2))),
"status": .value(AnyCloneableData(data: CloneableString("completed")))
]
// Add the task to the measure_pole_task_list
if case .object(var rootObject) = cloneableJSON.value,
case .array(var taskList) = rootObject["measure_pole_task_list"] {
taskList.append(.object(task))
rootObject["measure_pole_task_list"] = .array(taskList)
cloneableJSON.value = .object(rootObject)
}
Adding Multiple Tasks
To add multiple tasks:
let tasks: [[String: CloneableJSONValue]] = [
[
"id": .value(AnyCloneableData(data: CloneableString("task1"))),
"name": .value(AnyCloneableData(data: CloneableString("Measure pole height"))),
"inspection_phase": .value(AnyCloneableData(data: CloneableString("ar"))),
"design_height": .value(AnyCloneableData(data: CloneableNumber(10.5))),
"actual_height": .value(AnyCloneableData(data: CloneableNumber(10.2))),
"status": .value(AnyCloneableData(data: CloneableString("completed")))
],
[
"id": .value(AnyCloneableData(data: CloneableString("task2"))),
"name": .value(AnyCloneableData(data: CloneableString("Check pole condition"))),
"inspection_phase": .value(AnyCloneableData(data: CloneableString("photo"))),
"design_height": .value(AnyCloneableData(data: CloneableNumber(5.0))),
"actual_height": .value(AnyCloneableData(data: CloneableNumber(5.1))),
"status": .value(AnyCloneableData(data: CloneableString("in_progress")))
]
]
if case .object(var rootObject) = cloneableJSON.value,
case .array(var taskList) = rootObject["measure_pole_task_list"] {
for task in tasks {
taskList.append(.object(task))
}
rootObject["measure_pole_task_list"] = .array(taskList)
cloneableJSON.value = .object(rootObject)
}
Accessing and Modifying Data
To access and modify data in the CloneableJSON structure:
// Accessing data
if case .object(let rootObject) = cloneableJSON.value,
case .array(let tasks) = rootObject["measure_pole_task_list"] {
for task in tasks {
if case .object(let taskData) = task,
case .value(let nameData) = taskData["name"],
let name = nameData.data as? CloneableString {
print("Task name: \(name.value)")
}
}
}
// Modifying data
if case .object(var rootObject) = cloneableJSON.value,
case .array(var tasks) = rootObject["measure_pole_task_list"] {
if case .object(var firstTask) = tasks[0] {
firstTask["status"] = .value(AnyCloneableData(data: CloneableString("completed")))
tasks[0] = .object(firstTask)
}
rootObject["measure_pole_task_list"] = .array(tasks)
cloneableJSON.value = .object(rootObject)
}
Validating the Data
To validate the data against the schema:
if cloneableJSON.validate() {
print("Data is valid according to the schema")
} else {
print("Data does not match the schema")
}
Best Practices
Always use the appropriate
CloneableDataType
for each field (CloneableString
for strings,CloneableNumber
for numbers).Validate the data against the schema after making changes to ensure consistency.
Use optional binding and type checking when accessing data to handle potential mismatches safely.
When modifying nested structures, make sure to reassign the modified value at each level of the hierarchy.
Use descriptive variable names that match the schema structure for clarity.
By following these guidelines and examples, you can effectively use the CloneableJSON
struct to work with the measure pole task list data structure in a type-safe and schema-validated manner.
Last updated