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

[SR-7992] JSONEncoder should allow custom key ordering behavior #3676

Open
subdigital opened this issue Jun 13, 2018 · 6 comments
Open

[SR-7992] JSONEncoder should allow custom key ordering behavior #3676

subdigital opened this issue Jun 13, 2018 · 6 comments

Comments

@subdigital
Copy link

subdigital commented Jun 13, 2018

Previous ID SR-7992
Radar rdar://problem/41127529
Original Reporter @subdigital
Type Improvement
Additional Detail from JIRA
Votes 4
Component/s Foundation
Labels Improvement
Assignee @itaiferber
Priority Medium

md5: b325e74ffe4c72ee5ea685cb2c3ee15b

Issue Description:

I am working with a server that requires a certain key to be present first in an object ("for performance reasons" they said)...

Unfortunately, implementing `encode(to🙂` manually and encoding in a specific order does not end up having any effect on the key order of the resulting document.

Discussions about key order not being a valid JSON concern aside (which I agree with) it would be nice to have functionality for determining the order of keys by providing a custom function, similar to how we handle custom date formatting logic.

I'd love to have something like this:

let encoder = JSONEncoder()
encoder.outputFormatting = .customKeyOrdering { keys in
  // return a new array of sorted keys however I need

}

(And if Radar is a better place for this I'd be happy to submit it there instead.)

@belkadan
Copy link

belkadan commented Jun 14, 2018

cc @itaiferber

@itaiferber
Copy link
Contributor

itaiferber commented Jun 14, 2018

Although this sounds like a relatively simple request, I think in practice there would be quite a bit of complication here due to the fact that JSONEncoder currently produces JSON by going through JSONSerialization. JSONEncoder collects the entire encoded tree (storing dictionaries as {{NSDictionary}}s, which don't allow for ordering constraints like this) and passes that off to JSONSerialization; to support this, we'd need JSONSerialization to be able to make use of this sorting strategy and call back into Swift (potentially through an Objective-C shim). JSONSerialization also only gets dictionaries with string keys, and we'd have to map those back to CodingKeys to call the strategy; not impossible, but likely lossy.

I'm not sure how generally applicable this feature would be—as you say yourself, this isn't really a valid requirement on the JSON—but something we could definitely consider. This would be easier if JSONEncoder started using its own serializer (which we've considered doing), but that's not certain.

@itaiferber
Copy link
Contributor

itaiferber commented Jun 14, 2018

@swift-ci create

@subdigital
Copy link
Author

subdigital commented Jun 14, 2018

Ah, that's a good explanation. I had assumed that because lexographic key sorting is offered that this was something that might be easy to hook into.

@itaiferber
Copy link
Contributor

itaiferber commented Jun 14, 2018

@subdigital Yeah, that was significantly easier to do because we introduced a similar option on JSONSerialization and simply toggle that option in JSONEncoder with no additional work needed (JSONSerialization does the lexicographic sorting on its own there). Calling back into JSONEncoder from JSONSerialization would be more difficult though.

@swift-ci
Copy link
Contributor

swift-ci commented Dec 20, 2020

Comment by Damian Mehers (JIRA)

I've just hit this issue, converting .NET code to Swift.

I'm talking to an Amazon service over which I have no control, and it gives an error if the keys are not ordered as they specify.

I lost many many hours because of this - most of which were caused by me not believing that the service could require a specific field ordering ... but it does ... is there any recommended approach if ordering is required to be preserved, other than rolling my own encoder?

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@shahmishal shahmishal transferred this issue from apple/swift May 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants