JSONParserSwift: Parse JSON like Pro!

Parsing:

Parsing is a process of converting data coming from server in any form like JSON, data, dictionary etc to your model class object. This task is complicated and time consuming because we have to traverse each and every data and convert it into an object manually. While parsing JSON  there may be issues which arrive & we need to handle because if we don’t, the application might be terminated or crashed. For example, NSNull object, typecasting of data,

Problem with manual parsing:

There are some problems with manual parsing:

  1. Manual parsing is complicated because for that we need to understand the hierarchy of data and parse it.
  2. You need to write a lengthy code for parsing.
  3. You need to handle NSNull object. If You don’t, your application might crash.
  4. This is a time consuming process.

To avoid these problems and reduce efforts, here is a Library `JSONParserSwift` which can handle all the scenarios automatically.

JSONParserSwift:

This library used to parse the data into model object. You just need to make a model class and declare your variable in which you want to receive data and subclass it to `ParsableModel`. You need  not to write extra lines to parse your data. Now you just need to call a method and pass your data into it. This method will return you the object of your Model class.

Mainly this library is used for three tasks:

  1. Marshalling of the data ( JSON string, Data, Dictionary or Array to object)
  2. Reverse Marshalling of object (object to JSON)
  3. Defining custom keys for Parsable model

1.Data Parsing (JSON to object): 

This library is used to parse data from one JSON string/ data/ dictionary to `ParsableModel` or array of `ParsableModel`. Some conversion types are define here:

  1. JSON string to Parsable Model: You can convert your JSON String to any Parsable model object.
    Here is the JSON String:

    {
      "responseStatus": {
        "statusCode": 101,
        "message": "Error Message"
      },
      "responseData": {
        "employeeId": 1002,
        "employeeName": "Demo Employee",
        "employeeEmail": "abc@def.com",
        "employeeDepartment": "IT"
      }
    }

    Model For JSON String:

    class BaseResponse: ParsableModel {
      var responseStatus: ResponseStatus?
      var responseData: Employee?
    }
    
    class ResponseStatus: ParsableModel {
      var statusCode: NSNumber?
      var message: String?
    }
    
    class Employee: ParsableModel {
      var employeeId: NSNumber?
      var employeeName: String?
      var employeeEmail: String?
      var employeeDepartment: String?
    }

    Method calling for this model:

    do {
      let jsonString = "given above"
      let responseModel: BaseResponse = try JSONParserSwift.parse(string: jsonString)
      print(responseModel)
    } catch {
      print(error)
    }
  2. JSON String to Array of numbers / String / Parsable model:
    You can convert the JSON String in an Array of any type. For ex:
    JSON String:

    [
        {
            "howtoUseUrl": "",
            "iconUrl": "listening/listening_understand_format.png",
            "objective": "Check out some examples of the different types of questions you can expect to see in the listening test",
            "topicDescriptionUrl": "content/listening/listening_understanding_format.html",
            "topicId": 1,
            "topicName": "Understand the test format"
        },
        {
            "howtoUseUrl": "",
            "iconUrl": "listening/topics_marking.png",
            "objective": "Understand how the test is marked and what topics might come up",
            "topicDescriptionUrl": "content/listening/listening_topics_marking.html",
            "topicId": 2,
            "topicName": "Topics and marking"
        },
        {
            "howtoUseUrl": "",
            "iconUrl": "listening/answering_technique.png",
            "objective": "Tips and tricks to help you perform at your best",
            "topicDescriptionUrl": "content/listening/listening_answering_techniques.html",
            "topicId": 3,
            "topicName": "Answering techniques"
        },
        {
            "howtoUseUrl": "<null>",
            "iconUrl": "listening/take_a_quiz.png",
            "objective": "Prepare yourself better by taking a quiz",
            "topicDescriptionUrl": "<null>",
            "topicId": 65,
            "topicName": "Take a quiz"
        }
    ]

    ParsableModel:

    class ListItemModel: ParsableModel  {
        
        var topicName: String?
        var objective: String?
        var topicId: NSNumber?
        var iconUrl: String?
        var topicDescriptionUrl: String?
        var howToUseUrl: String?
    }

    Method to call:

    do {
      let jsonString = "given above"
      let responseModel: [ListItemModel] = try JSONParserSwift.parse(string: jsonString)
      print(responseModel)
    } catch {
      print(error)
    }
  3. Data to Parsable model:
    You can parse Data object in parsable model. To do that make your Model and call the method given below:

    do {
      let data: Data = // Your Data Object
      let responseModel: BaseResponse = try JSONParserSwift.parse(data: data)
      print(responseModel)
    } catch {
      print(error)
    }
  4. Data to Array of numbers / String / Parsable model:
    You can convert your data into array. To do that call a single method and define its type as array as given below:

    do {
      let data: Data = // Your Data Object
      let responseModel: [ListItemModel] = try JSONParserSwift.parse(data: data)
      print(responseModel)
    } catch {
      print(error)
    }
  5. Dictionary to Parsable model:
    You can also convert a dictionary into Parsable model object. For example:
    Dictionary:

    {
       howtoUseUrl = "";
       iconUrl = "listening/topics_marking.png";
       objective = "Understand how the test is marked and what topics might come up";
       topicDescriptionUrl = "content/listening/listening_topics_marking.html";
       topicId = 2;
       topicName = "Topics and marking";
    }

    Model for this dictionary is given above. To convert it into ParsableModel Object call given method:

    let dict = // Your Dictionary object 
    let responseModel: ListItemModel = JSONParserSwift.parse(dictionary: dictionary) 
    print(responseModel)
  6. Array of Dictionary to array of numbers / String / Parsable model:
    It also returns the array of parsable model from Array of Dictionary.

    do {
      let array = // Your Array of Dictionary object
      let responseModel: [ListItemModel] = try JSONParserSwift.parse(array: array)
      print(responseModel)
    } catch {
      print(error)
    }

All methods which can be used to parsing:

do {
  //json string to parsable model
  let userInfo: UserInfoModel = try JSONParserSwift.parse(string: json)

  //json string to array of parsable model
  let userInfo: [UserInfoModel] = try JSONParserSwift.parse(string: json)

  //data to parsable model
  let userInfo: UserInfoModel = try JSONParserSwift.parse(data: data)

  //data to array of parsable model
  let userInfo: [UserInfoModel] = try JSONParserSwift.parse(data: data)

  //dictionary to parsable model
  let userInfo: UserInfoModel = JSONParserSwift.parse(dictionary: dictionary)

  //array to array of parsable model
  let userInfo: [UserInfoModel] = try JSONParserSwift.parse(array: array)

} catch {
  print(error)
}

Here you just need to define the type of variable to let the parser know the Model class to make an object of that class.

2. Reverse Marshalling (Object to JSON): 

Reverse marshalling means converting the object of model class into JSON string. You need to call a single static method `getJSON:`. We can convert an object into following things:

  1. Object to JSON String:
    To convert the object into JSON String call method ` getJSON(object:)  ` as given below:
    Model Class:

    class TestModel {
    
        var test: String?
        var number: Double = 0
        var boolValue: Bool = false
        var anotherTest: TestModel?
        var array: [TestModel]?
    }

    Converting Model object to JSON String:

    // Prepare Test Model
    let testModel: TestModel = TestModel()
    testModel.test = "xyz"
    testModel.number = 10.0
    testModel.boolValue = true
        
    let anotherTestModel = TestModel()
    anotherTestModel.test = "abc"
    anotherTestModel.number = 23
    anotherTestModel.boolValue = false
        
    testModel.anotherTest = anotherTestModel
    testModel.array = [anotherTestModel]
    
    do {
        // Convert into json string
        let jsonString = try JSONParserSwift.getJSON(object: testModel)
        print("Json String : \(jsonString)")
    } catch {
        print(error)
    }

    The JSON String will be:

    {
      "boolValue":true,
      "number":10,
      "test":"xyz",
      "array":[
        {
          "boolValue":false,
          "number":23,
          "test":"abc",
          "array": null,
          "anotherKey": null
        }
      ],
      "anotherKey": {
        "boolValue":false,
        "number":23,
        "test":"abc",
        "array": null,
        "anotherKey": null
      }
     }

     

  2. Object to Dictionary:
    You can also convert your object in dictionary. For that use Given object ` testModel `:

    let jsonString = JSONParserSwift.getDictionary(object: testModel)
    print("Json String : \(jsonString)")
  3. Object to Array:
    It converts the Array of any object to array of dictionary:

    let jsonString = try JSONParserSwift.getDictionary(object: testModel)
    print("Json String : \(jsonString)")

3. Custom Keys For JSON:

To use the given library, declare the property name same as the keys given in your JSON String or data. By defining the properties with same name helps to map the keys with properties of class.

But if you don’t want to declare these keys with same name then you need to conform the protocol `JSONKeyCoder`. This protocol provides you a method
`func key(for key: String) -> String?`.

You need to implement this method and pass your property name and JSON key in this method as given below:

class TestModel: ParsableModel, JSONKeyCoder {

  var test: String?
  var number: Double = 0
  var boolValue: Bool = false
  var anotherTest: TestModel?
  var array: [TestModel]?
 
  public func key(for key: String) -> String? {
    switch key {
    case "boolValue": // Properties name
      return "bool_value" // Key in response
    case "anotherTest":
      return "another_key"
    default:
      return nil
    }
  }
}

JSON String for given Model:

{
  "bool_value":true,
  "number":10,
  "test":"xyz",
  "array":[
    {
      "bool_value":false,
      "number":23,
      "test":"abc",
      "array": null,
      "another_key": null
    }
  ],
  "another_key": {
    "bool_value":false,
    "number":23,
    "test":"abc",
    "array": null,
    "another_key": null
  }
 }

In `case`,  pass your property name as string and return your JSON key.
Using this protocol you can declare properties with different names.

Steps To use JSONParserSwift:

You can use this Library with following some easy steps:

  1. Create a project on Xcode.
  2. Create `pod` File for your project using command
    `pod init`
  3. Open pod file in editor and add  ” `pod ‘JSONParserSwift’` “
  4. Install Pod file using `pod install`
  5. Open workspace of your project
  6. import `JSONParserSwift` in your class.
  7. Create a model class and confirm it with `ParsableModel`

Note: Currently this version do not support Optional with Int and Array of Optional types. So prefer to use NSNumber for number related data.

For more information follow these links:

Your project is ready to use` JSONParserSwift`. Enjoy parsing without efforts and save your time 🙂

Leave a Reply