Search code examples
objective-cjsonnsoperationnsoperationqueue

Data transfer between NSOperations


I would like to obtain the following: I have two NSOperations in a NSOperationQueue. The firs is a download from a website (gets some json data) the next is parsing that data. This are dependent operations. I don't understand how to link them together. If they are both allocated and in the queue, how do I transfer the json string to the operation that parses it? Is it a problem if this queue is inside another NSOperationQueue that executes an NSOperation that consists of the two mentioned previously?

All I could find is transfers of data to a delegate on the main thread (performSelectorOnMainThread), but I need all this operations to execute in the background.

Thanks. Code: NSDownload : NSOperation

    - (instancetype)initWithURLString:(NSString *)urlString andDelegate:(id<JSONDataDelegate>)delegate
{
    self = [super init];
    if (self) {
        _urlStr = urlString;
        _delegate = delegate; /// this needs to be a NSOPeration
        _receivedData = [NSMutableData dataWithCapacity:256];
    }
    return self;
}

#pragma mark - OVERRIDE

    - (void)main
    {
        @autoreleasepool {

            if (self.isCancelled) {
                return;
            }

            NSURL *url = [NSURL URLWithString:self.urlStr];
            NSURLRequest *request = [NSURLRequest requestWithURL:url];
            self.urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
        }
    }

    #pragma mark - NSURLConnectionDataDelegate

    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
    {
        if (self.isCancelled) {
            [connection cancel];
            self.receivedData = nil;
            return;
        }
        [self.receivedData appendData:data];
    }

    - (void)connectionDidFinishLoading:(NSURLConnection *)connection
    {
        if (self.isCancelled) {
            self.receivedData = nil;
            return;
        }
        // return data to the delegate
        NSDictionary *responseDict = @{JSON_REQUESTED_URL : self.urlStr,
                                       JSON_RECEIVED_RESPONSE : self.receivedData};
        [(NSObject *)self.delegate performSelectorOnMainThread:@selector(didReceiveJSONResponse:) withObject:responseDict waitUntilDone:NO]; // ok to uses performSelector as this data is not for use on the main thread ???
    }

    - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
    {
        // return error to the delegate
        [(NSObject *)self.delegate performSelectorOnMainThread:@selector(didFailToReceiveDataWithError:) withObject:error waitUntilDone:NO];
    }

Solution

  • @user1028028:

    Use the following approach.

    1) Maintain the operation queue reference that you are using to add DownloadOperation.

    2) In connectionDidFinishLoading method, create ParseOperation instance, set the json data and add it to operation queue. Maintain ParseOperation strong reference variable in DownloadOperation and handling of cancelling of parsing operation through DownloadOperation interface.

    3) After completed parsing call the UI functionality in main thread.

    I hope this helps.