Prateek sharma
Prateek sharma

Reputation: 239

Present JSON string in sorted order from NSDictionary

I made one JSON string from the NSDictionary. The JSON string which I created doesn't come present the items in the order I entered keys and value pair in the NSDictionary .

Now I need all keys and value pairs returned as JSON string in alphabetic order. I tried lot of ways but not getting sorting of JSON string in alphabetic order.

Here's an example of the way the final string is being presented:

{
    "SubscriberID" : "603",
    "Amount" : "1",
    "MerchantID" : "100012",
    "Channel" : "Wallet",
    "RequestCode" : "0331",
    "PosID" : "0465F35F5577CUST",
    "TID" : "0000014",
    "Stan" : "NA"
}

How do I ensure the items are presented the way I entered them? Or how can I specify the items are alphabetically sorted?

Upvotes: 3

Views: 1297

Answers (5)

karajan
karajan

Reputation: 36

Actually,the system method [NSString stringWithFormat:] is what you need.So here is the easy way:

NSDictionary* inputDictionary = @{
            @"SubscriberID" : @"603",
            @"Amount" : @"1",
            @"MerchantID" : @"100012",
            @"Channel" : @"Wallet",
            @"RequestCode" : @"0331",
            @"PosID" : @"0465F35F5577CUST",
            @"TID" : @"0000014",
            @"Stan" : @"NA"
            };
NSString* sortedJsonStr = [NSString stringWithFormat:@"%@", inputDictionary];
NSLog(@"sorted json string is %@", sortedJsonStr);

The result is:

{
    Amount = 1;
    Channel = Wallet;
    MerchantID = 100012;
    PosID = 0465F35F5577CUST;
    RequestCode = 0331;
    Stan = NA;
    SubscriberID = 603;
    TID = 0000014;
}

Upvotes: 0

Hot Licks
Hot Licks

Reputation: 47729

The question does not make sense, and therefore cannot be answered in its current form.

If you encode some JSON as {"keyB":"valueB","keyA":"valueA"}, take it's checksum, and then transmit the encoded JSON and the checksum to the remote site, the remote site has little choice but to take the checksum of the JSON as received and compare that. To do the checksum on sorted values it would have to decode the received JSON string into an NSDictionary, re-encode into "sorted" JSON, and then take the checksum of the reconstituted JSON, and that would be a lot of extra effort for no reason.

Far more likely is that there is some difference in either the way the checksum is being computed (padding of the SHA256 input, eg) or some difference in the JSON strings being used -- code page differences, escaped characters, one end is doing it on Base64 and the other not, etc.

Upvotes: -3

kevin
kevin

Reputation: 2071

SBJson is able to do this, set sortKeys to YES on SBJsonWriter

http://superloopy.io/json-framework/

SBJsonWriter *writer = [[SBJsonWriter alloc] init];
writer.sortKeys = YES;
// Turn on humanReadable if you also need it pretty-printed
// writer.humanReadable = YES;
NSData *result = [writer dataWithObject:myDictionary];

Upvotes: 4

Craig Otis
Craig Otis

Reputation: 32054

Like many key-value storage classes, NSDictionary does not guarantee order of the elements you've added. It is a mistake to assume that the key/value pairs, or keyset, will be returned with any particular order.

Further, JSON objects are unordered in the same fashion. You should not care about the order in which the objects are added. Nor should you (or your recipient) rely on being provided a JSON object with 'sorted' keys, as that's not really a valid concept with these particular structures. While ordering the keys might result in an iterator traversing the keys in the order you expect, it's not a guarantee, and should not be relied on.

I think you should revisit why you need the keys sorted in the first place, and see if you can find a way to avoid a dependency on their alphabetical ordering.

Edit: You mention the server requires an SHA hash of the JSON string. If you must, you can create a sorted JSON string by sorting the keys in an NSMutableArray, then creating the JSON string from those keys.

NSMutableArray *sortedKeys = [NSMutableArray arrayWithArray:[myDict allKeys]]; 
[sortedKeys sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];

NSMutableString *jsonString = [[NSMutableString alloc] init];
[jsonString appendString:@"{"];
for (NSString *key in sortedKeys) {
    [jsonString appendFormat:@"\"%@\"", key];
    [jsonString appendString:@":"];
    [jsonString appendFormat:@"\"%@\"", [myDict objectForKey:key]];
    [jsonString appendString:@","];
}
if ([jsonString length] > 2) {
    [jsonString deleteCharactersInRange:NSMakeRange([jsonString length] - 1, 1)];
}
[jsonString appendString:@"}"];

This code hasn't been tested, so you might need to play with it a bit. Thought it would be much better if you could find a JSON library to do this for you, although you might not have as much control over the key ordering.

Upvotes: 2

pNre
pNre

Reputation: 5376

You can't do it (or at least you can't rely on that). JSON objects are unordered sets as you can read on JSON.org.

Upvotes: 1

Related Questions