Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parsing continuous JSON stream in iOS

Tags:

json

ios

I'm struggling to get a hang of JSON for an app I'm writing. On the app side I have a NSInputStream that is connected to a server with CFStreamCreatePairWithSocketToHost.

The server is generating JSON objects in an async fashion to the app.

In the app I react to network data on the event NSStreamEventHasBytesAvailable. On some networks I experience that I receive multiple JSON objects in the network buffer. But I also want to be take care of the scenario where I do not receive the entire JSON object in one network buffer.

I've been looking for a JSON parser that will handle these scenarios for me, but haven't been able to find one. NSJSONSerialization doesn't cope well with multiple JSON objects in the NSData it is to pass. I can't get the hang of how to get NSJSONSerialization working on a stream and am unsure it that will solve my problem.

I've looked into YAJL but I can only get it to work more than once. I can't seem to find any good examples for the scenario I have.

I'm frustrated and confused what is the best approach and where I find a good example? Any suggestions are welcome!

like image 917
Kristian Stobbe Avatar asked Apr 03 '15 22:04

Kristian Stobbe


1 Answers

There is a library called SBJson

Here's an example (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;
    }
}
like image 197
Luke Avatar answered Nov 20 '22 14:11

Luke