📜 ⬆️ ⬇️

Simple JSON Schema validator for Objective-C

Or a tale about how the development of a JSON validator has become another JSON binding


While normal developers write applications, I reinvent the wheel.

Probably many developers are faced with a situation where a mobile application is developed in parallel with the backend. In this case, often the data structures that come in response to a request from the server may change. For example, on the side of the backend they decide to change the naming of one of the JSON keys, forgetting to warn the mobile team about this. I'm not talking about the situation when CamelCase decided to “suddenly” change the notation to underscore or vice versa. You can say that there is a bad organization of the process and a lack of communication between the teams, and you will be absolutely right. But when the application on the customer’s smartphone stops working on the demo, all eyes are on mobile workers.


One of the ways out is to validate the submitted JSON in accordance with the JSON scheme ( overview article on JSON schemes ).
')
For example, if the JSON sent to us
{ "numberKey" : 100500, "arrayKey" : [ { "number" : 1 , "string" : "1" }, { "number" : 2 , "string" : "2" }, { "number" : 3 , "string" : "3" } ] } 

The minimum JSON scheme describing it will be
 { "type" : "object", "properties" : { "numberKey" : { "type" : "number" }, "arrayKey" : { "type" : "array", "items" : { "type" : "object", "properties" : { "number" : { "type" : "number" }, "string" : { "type" : "string" } } } } } } 

All that we ideally need is to take the JSON sent and validate it with the help of the scheme. It seemed, the problem is solved. JSON-schema is a standard way of describing JSON and there are validators for many programming languages. But the search for a validator for the Objective-C language did not yield any sane result, so it was decided to follow the path of cycling.

As a result, a division called JsonSchemaValidator (bitbucket) was born. For those who want to try:
 pod 'SVJsonSchemaValidator' 

So, with the help of this library, we can make a scheme:
id schema = [ [ SVType object ] properties : @ {
@ "numberKey" : [ SVType number ] ,
@ "arrayKey" : [ [ SVType array ] items : [ [ SVType object ] properties : @ {
@ "number" : [ SVType number ] ,
@ "string" : [ SVType string ]
} ] ]
} ] ;

As you can see, the scheme almost one to one repeats itself JSON. Now we check it out:
NSError * error = nil ;
id validatedJson = [ schema validateJson : json error : & error ] ;
Here are the variables:
json is parsed by any JSON parser (for example, using NSJSONSerialization).
validatedJson - only those objects that have been validated.
error - more or less imputed description of which objects failed validation. nil - if everything is OK.

Suppose you already have a model class
@ interface MyModelObject : NSObject

@property ( strong, nonatomic ) NSString * string ;
@property ( strong, nonatomic ) NSNumber * number;

@ end

I don’t want to do double work and describe existing classes in the scheme. You can create a schema directly from this class:
id schema = [ [ SVType object ] properties : @ {
@ "numberKey" : [ SVType number ] ,
@ "arrayKey" : [ [ SVType array ] items : [ MyModelObject jsonSchema ] ]
} ] ;

Using objc-runtime, the -jsonSchema method for the MyModelObject class will go through all the properties that can be represented in JSON and will generate exactly the same scheme. Using the same scheme, you can instantiate objects of the MyModelObject type and fill in their properties with the appropriate values ​​via KVC:
NSDictionary * instanciated = [ schema instantiateValidatedJson : validated ] ;

( lldb ) po instanciated
$ 1 = 0x0755fe70 {
numberKey = 100500 ,
arrayKey = (
"<MyModelObject: 0x7554a30>" ,
"<MyModelObject: 0x7554610>" ,
"<MyModelObject: 0x75543b0>" ,
"<MyModelObject: 0x75619b0>"
) ;
}

That's all that is implemented at the moment.
And now the question for the sake of which this short topic was written: does anyone need this bike, and if so, what else is required of it? Waiting for answers in camments.

Source: https://habr.com/ru/post/180923/


All Articles