Reputation: 239
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
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
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
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
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