Objective-C NSURLConnection didReceiveData在NSData中创建错误的JSON

时间:2013-08-22 21:55:19

标签: ios objective-c nsurlconnection nsdata

我目前正在尝试使用他们的流API来从Twitter流式传输数据。我已附上以下代码,用于创建NSData并在didReceiveData上附加该代码。出于某种原因,每次didReceiveData从Twitter获得响应时,它都会作为新的JSON根添加到NSData中,因此当我尝试将NSData解析为JSON结构时,它爆炸了。

我无法弄清楚发生了什么,并将JSON发布到验证器中,并注意到JSON中有多个根。如何修改代码以继续附加到现有JSON根?或者,当NSData中有多个JSON条目时,是否有更简单的方法可以反序列化为JSON?

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    // A response has been received, this is where we initialize the instance var you created
    // so that we can append data to it in the didReceiveData method
    // Furthermore, this method is called each time there is a redirect so reinitializing it
    // also serves to clear it
    NSLog(@"Did receive response");
    _responseData = [[NSMutableData alloc] init];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    // Append the new data to the instance variable you declared
    NSLog(@"Did Receive data");
    [_responseData appendData:data];
}

2 个答案:

答案 0 :(得分:0)

我认为你需要的只是一些额外的逻辑来处理它的实时性。使用NSMutableData作为容器继续接收数据,但是在每个批处理结束时,您应该扫描数据对象以查找所有有效对象,构建它们,并将它们存储到包含所有构建的json对象的不同对象中。在这个例子中,假设你有这个ivar:NSMutableArray * _wholeObjects

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
  // Append the new data to the instance variable you declared
  NSLog(@"Did Receive data");
  [_responseData appendData:data];
  [self buildWholeObjects]
}

- (void) buildWholeObjects {
  NSArray *rootObjects = <#business logic to return one whole JSON object per array element, or return nil if none found#>
  if (rootObjects != nil) {
    NSUInteger bytesExtracted = 0;
    for (rootObject in rootObjects) {
      [_wholeObjects addElement:rootObject];
      bytesExtracted += rootObject.length;
    }
    NSData *remainingData = [_responseData subdataWithRange:NSMakeRange(bytesExtracted, _responseData.length - bytesExtracted];
    [_responseData setData:remainingData];
  }
}

执行此操作后,只访问_wholeObjects中的对象,其中每个元素表示一个完全有效的JSON对象,您可以以任何方式反序列化或读取。

为了清楚起见,我们假设第一个NSData代表:

{"a":"2"}{"c":"5

当你处理它时_wholeObjects将有一个元素代表{“a”:“2”},而_responseData现在将是{“c”:“5

然后下一个数据流应继续在该对象上。让我们说第二个NSData是:

"}

现在_responseData是{“c”:“5”}因为我们将新消息附加到剩余的旧消息上。我们构建了这个,并在_wholeObjects中获取第二个元素,_ responseseData将为空并准备好接收下一组数据。

希望有所帮助。我认为对你来说困难的部分是确定_responseData被认为是多少有效的JSON对象。如果它们足够简单,你可以只计算开启次数{/ [关闭} /]并拉出子串。

答案 1 :(得分:0)

只是为处理相同事情的人跟进这个主题:我最终使用了支持流媒体的SBJson。 http://superloopy.io/json-framework/