Search code examples
iossynchronizationtouchjson

iOS: TouchJSON & retrieved data size


I want to display a UIProgressView indicating the amount of data received as I request JSON data using touchJSON. I was wondering if there was a way to listen to the size of the data being received.

I request data using the following:

- (NSDictionary *)requestData
{   
    NSData          *data       =   [NSData dataWithContentsOfURL:[NSURL URLWithString:apiURL]];
    NSError         *error      =   nil;
    NSDictionary    *result     =   [[CJSONDeserializer deserializer] deserializeAsDictionary:data error:&error];

    if(error != NULL)
        NSLog(@"Error: %@", error);

    return result;
}

Solution

  • You will have to introduce some more code to include a download status indicator bar. At the moment you download the data with [NSData dataWithConentsOfURL:...]. Instead, you will make a class that uses a NSURLConnection object to download data, accumulate that data in an MSMutableData object, and update your UI accordingly. You should be able to use the ContentLength HTTP header and the - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data; updates to determine the status of the download.

    Here are some relevant methods:

    - (void) startDownload
    {
        downloadedData = [[NSMutableData alloc] init];
        connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
    }
    
    - (void)connection:(NSURLConnection *)c didReceiveResponse:(NSURLResponse *)response
    {
        totalBytes = [response expectedContentLength];
    }
    
    // assume you have an NSMutableData instance variable named downloadedData
    - (void)connection:(NSURLConnection *)c didReceiveData:(NSData *)data
    {
        [downloadedData appendData: data];
        float proportionSoFar = (float)[downloadedData length] / (float)totalBytes;
        // update UI with proportionSoFar
    }
    
     - (void)connection:(NSURLConnection *)c didFailWithError:(NSError *)error
    {
        [connection release];
        connection = nil;
        // handle failure
    }
    
    - (void)connectionDidFinishLoading:(NSURLConnection *)c
    {
        [connection release];
        connection = nil;
        // handle data upon success
    }
    

    Personally, I think the simplest way to do this is to create a class that implements the above methods to do generic data downloads and interface with that class.

    This should be enough to get you what you need.