John Doe
John Doe

Reputation: 876

Converting NSDictionary to Json String causes re-ordering of elements

I am trying to convert an NSDictionary object to a json string using the following:

let data = try JSONSerialization.data(withJSONObject: data, options :[])
var string = String(data: data, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue))

However it re-orders the individual elements alphabetically, this is what Swift returns:

{"client-nonce":"4q7581q6CbkAlJAAajHuWFiLJTPKJLpk","timestamp":"1480560235","token":"5aeba5cb66644e8e739765632a23f2f98a4035f99306f46777c67cea652dad79","url":"http://api.uselinkthrow.local/api/me/stream/friend/links"}

I would like to keep the order in which the dictionary was made, thus returning this:

{"token":"5aeba5cb66644e8e739765632a23f2f98a4035f99306f46777c67cea652dad79","timestamp":"1480560235","client-nonce":"4q7581q6CbkAlJAAajHuWFiLJTPKJLpk","url":"http://api.uselinkthrow.local/api/me/stream/friend/links"}

Does anyone know how I can do this?

Upvotes: 0

Views: 590

Answers (3)

Son of a Beach
Son of a Beach

Reputation: 1779

You cannot do this with just a dictionary and just flat (single-level) JSON.

Dictionaries are un-ordered by nature, both in JSON and in Swift (and any other language). If you need to maintain an order, you should use an array.

It's difficult to give a specific answer to your question, because you haven't provided any reasons why you want to maintain this order, nor details on the nature of how the data is generated (eg, will the dictionary always have the same keys, and should they always be in the same order?).

However, if it really is necessary to maintain order AND if you are in a position to use a different JSON format, you could do it by either of the following two methods, depending on your requirements:

  1. If the keys are always going to be the same and in the same order...

Populate your JSON from an array and not from your original dictionary. Since you know what order the elements are in, you know which element is which without needing to have any keys.

  1. If the keys are not always going to be the same, OR are not always going to be in the same order...

Maintain an array of ordered keys separately, as well as the dictionary, and then use the array to access the dictionary values in the same order that the keys are stored within the array.

Depending on your requirements, you may need to have the array also stored in the JSON (eg, combined with your dictionary into a parent dictionary).

This is probably a bit kludgy, but to get a better answer, you may have to provide more information on what your requirements actually are.

Upvotes: 0

Frankie
Frankie

Reputation: 11928

As the others have mentioned, it's a dictionary, it's not designed to provide ordered keys. It is designed to have quick hash lookup, so just go ahead and use that to put things in the right order.

I'm not sure of why you want some kind of ordered string, so this is just an example for you to work off of to print strings in the order you want:

if let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any] {
    ["token", "timestamp", "client-nonce", "url"].forEach({ print(String(describing: json?[$0])) })
}

Upvotes: 0

Niko Adrianus Yuwono
Niko Adrianus Yuwono

Reputation: 11112

You cannot and should not rely on the ordering of elements within a JSON object.

JSON Object is a key-value pair, there is no order, and you can't order it and last the order won't matter

For more detail check json.org

Upvotes: 3

Related Questions