2015-04-03 78 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; 
    } 
}