Rodrigo Salles
Rodrigo Salles

Reputation: 257

Keeping the order of NSDictionary keys when converted to NSData with [NSJSONSerialization dataWithJSONObject:]

I have the following situation:

NSDictionary *params = @{
    @"Checkout" : @{
        @"conditions" : @{@"Checkout.user_id" : @1},
        @"order" : @{@"Checkout.id" : @"DESC"}
    },
    @"PaymentState" : @[],
    @"Offer" : @[]
};

This dictionary contains params for a webservice request passing a JSON string with the webservice URL. I get the JSON string using NSJSONSerialization class, like this:

NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:nil];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

The problem is: jsonString "keys" is ordered differently from the original params dictionary keys order, like this:

{
"Offer":[],
"PaymentState":[],
"Checkout":{
    "conditions":{"Checkout.user_id":6},
    "order":{"Checkout.id":"DESC"}
}

}

That is, the "PaymentState" and "Offer" keys come first in jsonString, and i need maintain the original order. This is very important, like this:

{
"Checkout":{
    "conditions":{"Checkout.user_id":6},
    "order":{"Checkout.id":"DESC"}
},
"Offer":[],
"PaymentState":[]

}

So guys, how can i do that??

Upvotes: 16

Views: 13131

Answers (3)

Eneko Alonso
Eneko Alonso

Reputation: 19662

While NSDictionary and Dictionary do not maintain any specific order for their keys, starting on iOS 11 and macOS 10.13, JSONSerialization supports sorting the keys alphabetically (see Apple documentation) by specifying the sortedKeys option.

Example:

let data: [String: Any] = [
    "hello": "world",
    "a": 1,
    "b": 2
]

let output = try JSONSerialization.data(withJSONObject: data, options: [.prettyPrinted, .sortedKeys])
let string = String(data: output, encoding: .utf8)

// {
//  "a" : 1,
//  "b" : 2,
//  "hello" : "world"
// }

Upvotes: 8

Me1000
Me1000

Reputation: 1758

According to the JSON spec a JSON object is specifically unordered. Every JSON library is going to take this into account. So even when you get around this issue for now, you're almost certainly going to run into issues later; because you're making an assumption that doesn't hold true (that the keys are ordered).

Upvotes: 10

neilvillareal
neilvillareal

Reputation: 3975

I use OrderedDictionary from CocoaWithLove whenever I need to keep the order of my dictionary keys.

Basically, OrderedDictionary contains an NSMutableDictionary and an NSMutableArray for the keys inside it, to keep track of the order of the keys. It implements the required methods for subclassing NSDictionary/NSMutableDictionary and just "passes" the method call to the internal NSMutableDictionary.

Upvotes: 11

Related Questions