Objective c 在Objective C中解析流式JSON

Objective c 在Objective C中解析流式JSON,objective-c,json,Objective C,Json,我在TCP上使用JSON-RPC,问题是我找不到任何能够正确解析多个JSON对象的JSON解析,而且由于没有使用分隔符,所以拆分它相对比较困难 任何人都知道我该如何处理,即: {foo:false,bar:true,baz:cool}{ba 不知何故,我需要将其拆分,以便只得到第一个完整的JSON对象。剩余的字符串需要保留在缓冲区中,直到我有足够的数据正确解析为止。确实给出了一个提示: 因此,您的客户需要能够处理这个问题,例如,通过计算和匹配花括号{} 更新:正如所指出的,在使用这种方法时,要

我在TCP上使用JSON-RPC,问题是我找不到任何能够正确解析多个JSON对象的JSON解析,而且由于没有使用分隔符,所以拆分它相对比较困难

任何人都知道我该如何处理,即:

{foo:false,bar:true,baz:cool}{ba

不知何故,我需要将其拆分,以便只得到第一个完整的JSON对象。剩余的字符串需要保留在缓冲区中,直到我有足够的数据正确解析为止。

确实给出了一个提示:

因此,您的客户需要能够处理这个问题,例如,通过计算和匹配花括号{}

更新:正如所指出的,在使用这种方法时,要小心JSON字符串中的大括号


另一个可能更好的解决方案是使用类似于流式JSON解析器或其Objective-C包装器。您可以向解析器提供数据,直到它表示当前对象已完成,然后重新开始解析。

@ePirat,如果有人只是连接了多个JSON字典而没有分隔符,则应该将其删除

用于解析:JSONSerialization解析NSData,这些NSData可以采用任何编码。幸运的是,如果连接了多个JSON字典,它们很容易分解。您只需查看字节并检查字符\{和}

如果你找到一个{,那么增加开括号的计数器。 如果找到一个},则减少开括号的计数器。如果计数器为零,则找到字典的结尾

如果找到a,则重复查看下一个字符。如果下一个字符是a,则跳过它并转到已找到字符串结尾的正常处理。如果下一个字符是\,则跳过该字符和下一个字符。如果下一个字符是其他字符,则跳过它

如果到达数据的末尾,则JSON数据不完整。您可以记住,在计算开括号时处于哪个状态,是否正在解析字符串,如果正在解析字符串,是否只是遇到了反冲字符,然后继续到结束处


无需将NSData转换为字符串,直到您将其拆分为字典。如果您怀疑可能会收到UTF-16或UTF-32,请检查字节0、1、2或1、2、3是否为零UTF-32,然后检查字节0和2或1和3是否为零UTF-16。但在这种情况下,如果服务器发送UTF-16或UTF-32格式的非标准JSON,请更改t负责人应该被枪杀,负责人必须被枪杀。

好吧,这不是JSON,而是多个JSON流连接在一起。我怀疑你在数据流中丢失了某种分隔符。如果你完全不担心CPU使用,你可以尝试在TCP流中接收到每个字符后解析它。除了在,您必须使用分隔符或类似的东西。@HotLicks不幸的是,我没有,没有分隔符,这一点很清楚。您可能会期望类似:[{foo:false,bar:true,baz:cool},{ba-一个数组,第一个元素是我们可以完全读取的字典,第二个元素是字典,但连第一个键都不知道。这很棘手。还有一个问题是不正确的JSON不应该被部分解释,所以无论你做什么,如果后面的内容包含错误,你都必须能够撤消。@BrunoWerminghoff这将是非常低效的,不幸的是,我无法更改从服务器收到的JSON,这是我无法控制的。请确保您忽略引号中包含的大括号。@JodyHagins感谢您的提示。我使用流解析更新了答案,因为无法重新启动使用剩余数据的解析器。@ePirat您可以将解析器分块输入到下一个]或},例如,使用包含{foo:{bar:baz},bar:baz}{foo:,您输入{foo:{bar:baz},然后输入,bar:baz}的数据包。此时,解析器会说对象已完成,然后您将{foo:left,您可以将其馈送到重新启动的parseryajl中,它肯定可以用于此目的。您可以计算出成功解析后消耗了多少,并在下一次解析操作中重新使用其余部分。请参阅文档:yajl_get_bytes_consumerd考虑到存在明确的解释,它们应该被拍摄是一个相当激进的立场其他JSON解析器支持连接的JSON。