skip to Main Content

I have an json object and store it as initialData and after some changes in store the json object into another modifiedData. Now I am trying to compare two json object of initialData and modifiedData but i could not able to compare it.

Note: Here json object are dynamic value.

Sample code:

let jsonObjectVal = JSON(message.body)
let initialData = jsonObjectVal

In save action i have modifiedData object.

 let jsonObjectModVal = JSON(message.body)
 let modifiedData = jsonObjectModVal

 if initialFormDataJson == jsonObjectVal {
     print("json object are equal save handler")
   } else  {      
     print("json object are not equal save handler")
   }

Any help much appreciated pls…

4

Answers


  1. Create a NSObject class or struct from the JSON and compare all the properties to check for equality and return true/false accordingly.
    Equatable protocol will come in handy here.

    class A: Equatable {
        func equalTo(rhs: A) -> Bool {
            // whatever equality means for two As
        }
    }
    
    func ==(lhs: A, rhs: A) -> Bool {
        return lhs.equalTo(rhs)
    }
    
    Login or Signup to reply.
  2. Here’s an example with a random data structure on how exactly you can do it:

    import Foundation
    
    final class YourObject: Decodable, Equatable {
    
        var field1: String
        var field2: Int
        var field3: [String : Double]
    
        static func == (lhs: YourObject, rhs: YourObject) -> Bool {
            lhs.field1 == rhs.field1
                && lhs.field2 == rhs.field2
                && lhs.field3 == rhs.field3
        }
    
    }
    
    let firstJSONString = """
    {
       "field1":"Some string",
       "field2":1,
       "field3":{
          "Some string":2
       }
    }
    """
    let firstJSONData = firstJSONString.data(using: .utf8)!
    let firstObject = try? JSONDecoder().decode(YourObject.self, from: firstJSONData)
    
    let secondJSONString = """
    {
       "field1":"Some string",
       "field2":1,
       "field3":{
          "Some string":2
       }
    }
    """ // Same.
    let secondJSONData = secondJSONString.data(using: .utf8)!
    let secondObject = try? JSONDecoder().decode(YourObject.self, from: secondJSONData)
    
    let thirdJSONString = """
    {
       "field1":"Some other string",
       "field2":2,
       "field3":{
          "Some string":3
       }
    }
    """ // Differs.
    let thirdJSONData = thirdJSONString.data(using: .utf8)!
    let thirdObject = try? JSONDecoder().decode(YourObject.self, from: thirdJSONData)
    
    print(firstObject == secondObject) // true
    print(firstObject == thirdObject) // false
    

    Note: You mentioned that the object should be dynamic, that’s why it’s a class. If you needed a value object, you would be able to use struct and avoid manual implementation of the ==operator.

    It’s just a start of course. Having a specific JSON structure in your hands you can always search for more complicated examples, internet swarms with them.

    Login or Signup to reply.
  3. For Compare 2 objects use === operator

    for eg.

    let jsonObjectModVal = JSON(message.body)
     let modifiedData = jsonObjectModVal
    
     if initialFormDataJson === jsonObjectVal {
         print("json object are equal save handler")
       } else  {      
         print("json object are not equal save handler")
       }
    
    Login or Signup to reply.
  4. If you want to compare two completely arbitrary JSON objects (e.g. for unit testing), I’d suggest using the GenericJSON library. Add it to your project and/or Package.swift, and then (borrowing from @lazarevzubov’s answer):

    import GenericJSON
    
    // Assume `YourObject` is `Encodable`
    let testObject = YourObject(field1: "Some string", field2: 1, field3: ["Some string": 2])
    
    let expectedData = """
    {
       "field1":"Some string",
       "field2":1,
       "field3":{
          "Some string":2
       }
    }
    """.data(using: .utf8)!
    
    let expectedJSON = try? JSON(JSONSerialization.jsonObject(with: expectedData))
    let actualJSON = try? JSON(encodable: testObject)
    
    XCTAssertEqual(actualJSON, expectedJSON, "JSON should be equal")
    
    

    A nice bonus is that you don’t need to add any otherwise unnecessary Decodable or Equatable conformance to your model objects.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search