3

我从NSDictionary. 我创建的 JSON 字符串没有按照我在NSDictionary.

现在我需要按字母顺序作为 JSON 字符串返回的所有键和值对。我尝试了很多方法,但没有按字母顺序对 JSON 字符串进行排序。

这是最终字符串呈现方式的示例:

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

如何确保项目以我输入的方式呈现?或者我如何指定项目按字母顺序排序?

4

5 回答 5

4

SBJson 能够做到这一点,在 SBJsonWriter 上将 sortKeys 设置为 YES

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];
于 2013-10-08T12:31:28.083 回答
2

像许多键值存储类一样,NSDictionary不保证您添加的元素的顺序。假设键/值对或键集将以任何特定顺序返回是错误的。

此外,JSON 对象以相同的方式无序。您不应该关心添加对象的顺序。您(或您的接收者)也不应该依赖提供带有“排序”键的 JSON 对象,因为对于这些特定结构来说,这并不是一个真正有效的概念。虽然对键排序可能会导致迭代器按照您期望的顺序遍历键,但这不是保证,也不应该依赖。

我认为你应该重新审视为什么首先需要对键进行排序,看看你是否能找到一种方法来避免依赖于它们的字母顺序。

编辑:您提到服务器需要JSON 字符串的 SHA 哈希。如果必须,您可以通过对 中的键进行排序来创建排序的 JSON 字符串NSMutableArray,然后从这些键创建 JSON 字符串。

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:@"}"];

此代码尚未经过测试,因此您可能需要稍微尝试一下。认为如果您能找到一个 JSON 库来为您执行此操作会更好,尽管您可能无法对密钥排序进行太多控制。

于 2013-10-08T12:02:12.590 回答
1

你不能这样做(或者至少你不能依赖它)。JSON 对象是无序集,您可以在JSON.org上阅读。

于 2013-10-08T11:59:32.600 回答
0

实际上,系统方法 [NSString stringWithFormat:] 是您所需要的。所以这里是简单的方法:

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);

结果是:

{
    Amount = 1;
    Channel = Wallet;
    MerchantID = 100012;
    PosID = 0465F35F5577CUST;
    RequestCode = 0331;
    Stan = NA;
    SubscriberID = 603;
    TID = 0000014;
}
于 2020-02-08T07:48:44.473 回答
-3

这个问题没有意义,因此无法以目前的形式回答。

如果将一些 JSON 编码为{"keyB":"valueB","keyA":"valueA"},取其校验和,然后将编码后的 JSON 和校验和传输到远程站点,远程站点别无选择,只能将接收到的 JSON 校验和进行比较。要对排序值进行校验和,它必须将接收到的 JSON 字符串解码为 NSDictionary,重新编码为“排序”的 JSON,然后对重构的 JSON 进行校验和,这将是很多额外的努力原因。

更有可能的是,校验和的计算方式(例如,SHA256 输入的填充)或所使用的 JSON 字符串存在一些差异——代码页差异、转义字符、一端正在这样做在 Base64 上,另一个不在,等等。

于 2013-10-08T15:16:58.313 回答