【问题标题】:Present JSON string in sorted order from NSDictionary从 NSDictionary 中按排序顺序显示 JSON 字符串
【发布时间】:2013-10-15 08:06:59
【问题描述】:

我从NSDictionary 创建了一个 JSON 字符串。我创建的 JSON 字符串没有按照我在 NSDictionary 中输入键和值对的顺序显示项目。

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

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

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

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

【问题讨论】:

  • 您无法对 JSON“对象”中的条目进行排序。根据定义,订单是“未定义的”。
  • 我很确定您误解了症状。可能 SHA 算法的应用略有不同,或者你们中的一个正在检查转义或 Base64 编码的版本,而另一个不是。解码接收到的 JSON 字符串并然后进行校验和是绝对没有意义的。

标签: iphone ios objective-c json sorting


【解决方案1】:

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

【讨论】:

  • 但这不是标准的 JSON,任何网络协议都不应该依赖它。
  • @HotLicks 为什么键排序的事实突然使它“不是标准的 JSON”?是正方形会禁止它同时是矩形吗?
  • 要求对键进行排序使其不是标准 JSON。
【解决方案2】:

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

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

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

编辑:您提到服务器需要 JSON 字符串的 SHA 哈希。如果必须,您可以通过对 NSMutableArray 中的键进行排序来创建排序的 JSON 字符串,然后从这些键创建 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 库来为您执行此操作会更好,尽管您可能无法控制密钥顺序。

【讨论】:

  • 实际上我需要制作这个字符串的 SHA256 ,这与服务器生成的不同。因为服务器使用字母 JSON 字符串
  • 您正在创建 JSON 字符串的 SHA 哈希?为什么,服务器需要它?如果是这样,也许您可​​以发布代码来显示您发送到服务器的内容?
  • 我正在使用安全服务器,我需要在其中制作 SHA256,然后从 SHA256 获取 HEXA 值并将该值传递给服务器
  • @Prateeksharma - JSON 字符串 在传输过程中不会改变顺序。您可以在字符串上创建校验和,根据另一端的字符串对其进行验证,并可靠地对其进行验证。只是不要先将字符串转换为“本机”对象。
  • @HotLicks 我想也许他必须发送 SHA 哈希 along 和 JSON 字符串,以便服务器可以确保它接收到客户端发送的内容。由于他必须生成哈希,我想他必须找到一种方法来复制服务器正在使用的方法。致 OP:查看我更新的代码 sn-p。
【解决方案3】:

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

【讨论】:

  • 你能分享直接链接吗,其中提到我们不能对 JSON 字符串进行排序。因为我没有看到任何行显示“在 JSON 字符串上无法排序”
  • An object is an unordered set of name/value pairs. 在我链接的页面中。
【解决方案4】:

其实系统方法[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;
}

【讨论】:

    【解决方案5】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-16
      • 1970-01-01
      • 1970-01-01
      • 2018-05-29
      相关资源
      最近更新 更多