2

現在、ストリーミング API を使用して Twitter からデータをストリーミングしようとしています。NSDatamyを作成して に追加するためのコードを以下に添付しましたdidReceiveData。何らかの理由で、Twitter からの応答を取得するたびdidReceiveDataに、新しい JSON ルートとして に追加されるNSDataため、 を JSON 構造に解析しようとすると、NSData爆発します。

何が起こっているのか理解できず、JSON をバリデーターに投稿したところ、JSON に複数のルートがあることがわかりました。既存の JSON ルートに引き続き追加するようにコードを変更するにはどうすればよいですか? または、に複数の JSON エントリがある場合、JSON にデシリアライズする簡単な方法はありますNSDataか?

- (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];
}
4

2 に答える 2

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"} を表す 1 つの要素が含まれ、_responseData は {"c":"5 になります。

その後、データの次のストリームはオブジェクトで継続する必要があります。2 番目の NSData は次のようになります。

"}

残りの古いメッセージに新しいメッセージを追加したため、_responseData は {"c":"5"} になります。これを構築し、_wholeObjects で 2 番目の要素を取得すると、_responseData は空になり、次のデータ セットを受け取る準備が整います。

それがいくつか役立つことを願っています。_responseData のどれだけが有効な JSON オブジェクトと見なされるかを判断するのは、あなたにとって難しい部分だと思います。それらが十分に単純な場合は、開始 {/[ 終了 }/] の数を数えて、その部分文字列を引き出すことができます。

于 2013-08-23T15:48:01.277 に答える