Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS 17 Data equality checks have changed [JSONEncoding/JSONDecoding] #4812

Open
samitaha2 opened this issue Aug 18, 2023 · 3 comments
Open

Comments

@samitaha2
Copy link

Data equality checks have incorrectly changed on iOS 17.

Step to reproduce:

Run XCTestCase file in iOS 16. It will pass.
Run XCTestCase file in iOS 17. It will fail.

Suspected Cause:

In iOS 17, Data has changed how it performs equality. Previously equality did not care about ordered keys, now it does.
I've noticed if I modify the test case to use a JSONEncoder setting of encoder.outputFormatting = .sortedKeys, then it passes.

Reason this is a bug:

This is unexpected and changed behavior. Equality should not care what the ordering of the keys are when comparing one data object to another data object. Ordering is irrelevant for a JSON object. It's the content that matters. This will cause a huge regression for us in our previously released app if this hits production.

import XCTest

final class JSONDecodingTest: XCTestCase {
    
    struct Address: Codable {
        let street: String
        let city: String
        let state: String
        let postalCode: String
    }

    struct OrderItem: Codable {
        let productID: String
        let productName: String
        let quantity: Int
    }

    struct Order: Codable {
        let orderID: String
        let totalAmount: Double
        let items: [OrderItem]
    }

    struct User: Codable {
        let id: Int
        let username: String
        let email: String
        let address: Address
        let orders: [Order]
    }

    struct RootObject: Codable {
        let user: User
    }

    
    func testData() throws {
        
        let object1Json: String = """
        {
          "user": {
            "id": 12345,
            "username": "johndoe",
            "email": "[email protected]",
            "address": {
              "street": "456 Elm St",
              "city": "Somewhere",
              "state": "NY",
              "postalCode": "54321"
            },
            "orders": [
              {
                "orderID": "A987",
                "totalAmount": 75.99,
                "items": [
                  {
                    "productID": "P123",
                    "productName": "Widget",
                    "quantity": 2
                  },
                  {
                    "productID": "P456",
                    "productName": "Gizmo",
                    "quantity": 1
                  }
                ]
              },
              {
                "orderID": "B543",
                "totalAmount": 32.50,
                "items": [
                  {
                    "productID": "P789",
                    "productName": "Thingamajig",
                    "quantity": 3
                  }
                ]
              }
            ]
          }
        }

        """
        let encoder = JSONEncoder()
        encoder.outputFormatting = .sortedKeys
        
        let itemData = object1Json.data(using: .utf8)!
        let item = try JSONDecoder().decode(RootObject.self, from: itemData)
        
        let data1 = try encoder.encode(item)
        let data2 = try encoder.encode(item)
        
        
        XCTAssertTrue(data1 == data2)
    }
}
@samitaha2
Copy link
Author

@ypli-chn FYI -- since I see in a recent commit you modified decoding for generics.

@samitaha2 samitaha2 changed the title iOS 17 Data equality checks have changed. iOS 17 Data equality checks have changed [JSONEncoding/JSONDecoding' Aug 18, 2023
@samitaha2 samitaha2 changed the title iOS 17 Data equality checks have changed [JSONEncoding/JSONDecoding' iOS 17 Data equality checks have changed [JSONEncoding/JSONDecoding] Aug 18, 2023
@ypli-chn
Copy link
Contributor

@samitaha2 This library is just an open source version of Foundation, and only affects the behavior under Linux. The Foundation used in the iOS system is not from this repository.

@parkera
Copy link
Member

parkera commented Aug 28, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants