2015-04-03 72 views
4

我正在努力为我正在编写的应用程序获取JSON的挂起。在应用程序方面,我有一个NSInputStream,通过CFStreamCreatePairWithSocketToHost连接到服务器。在iOS中解析连续的JSON流

服务器以异步方式向应用程序生成JSON对象。

在应用程序中,我对事件NSStreamEventHasBytesAvailable的网络数据作出了反应。在某些网络中,我遇到了在网络缓冲区中收到多个JSON对象的情况。但是我也想要照顾一个网络缓冲区中没有收到整个JSON对象的场景。

我一直在寻找一个JSON解析器,可以为我处理这些场景,但一直未能找到。 NSJSONSerialization无法很好地处理它要传递的NSData中的多个JSON对象。我无法弄清楚如何让NSJSONSerialization在一个流上工作,并且我不确定这会解决我的问题。

我已经看过YAJL,但我只能让它工作多次。我似乎无法为我的场景找到任何好的例子。

我很沮丧和困惑什么是最好的方法,我在哪里找到一个很好的例子?欢迎任何建议!

+0

喜欢的东西YAJL是你想要的。看看https://github.com/gabriel/yajl-objc与YAJL的一些ObjC绑定,但不清楚你的意思是“让它工作多次”。您应该将一个小例子放在一起,并提出与您的YAJL代码面临的特定问题有关的问题。异地资源请求(如示例代码)是StackOverflow的主题。 – 2015-04-03 22:21:45

+0

你确定这实际上是你想要的吗?你真的想分析JSON,因为它到达,一点点?大多数人会收集完整的数据流并在所有数据都存在时解析数据,然后使用NSData接口来完成。 – gnasher729 2015-08-21 06:16:27

+0

我有同样的问题。数据到达网络,但我想在它到达时继续显示。我怎样才能做到这一点? – Renu 2017-12-30 21:40:47

回答

3

有一个叫SBJson

库下面是一个例子(from here):

- (IBAction)go { 
    id block = ^(id item, BOOL *stop) { 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      // do something with item 
     }); 
    }; 

    id eh = ^(NSError *error) { 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      // handle error 
     }); 
    }; 
    self.parser = [SBJson4Parser unwrapRootArrayParserWithBlock:block 
                errorHandler:errorHandler]; 

    NSURLSessionConfiguration *c = [NSURLSessionConfiguration defaultSessionConfiguration] 
    NSURLSession *urlSession = [NSURLSession sessionWithConfiguration:c 
                  delegate:self 
                 delegateQueue:nil]; 
    NSURL *url = [NSURL URLWithString:self.urlField.text]; 
    NSURLSessionDataTask *urlSessionDataTask = [urlSession dataTaskWithURL:url]; 
    [urlSessionDataTask resume]; 
} 

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask 
    didReceiveData:(NSData *)data { 
    switch ([self.parser parse:data]) { 
     case SBJson4ParserError: 
      self.parser = nil; 
      break; 
     case SBJson4ParserComplete: 
     case SBJson4ParserStopped: 
      self.parser = nil; 
      break; 
     case SBJson4ParserWaitingForData: 
      break; 
    } 
}