views:

285

answers:

1

Hi,

Hope you guys can help me :)

In the main thread, I create a NSOperation and add it to a queue. What that operation do is connect to a data server with NSURLConnection, save the receivedData and parse it.

Operation.m

- (void)start
{
    NSLog(@"opeartion for <%@> started.", [cmd description]);

    [self willChangeValueForKey:@"isExecuting"];
    _isExecuting = YES;
    [self didChangeValueForKey:@"isExecuting"];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:_url];

    [request setHTTPMethod:@"POST"];
    [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", m_BOUNDARY] forHTTPHeaderField:@"Content-Type"];
    [request setHTTPBody:_postData];

    _connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

    if (_connection == nil)
        [self finish];
}

Then in this NSURL delegate method I parse the data I've just received from server.

Operation.m

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    [self parseItems];
}

In the data, I can found items like, for instance, screenItem, CellItem, TextItem that I send to the main thread for drawing them while arriving. (I create a UITableView if an itemTable arrives, or I create a UIWebView if an itemWeb arrives)

Using this for sending item to main thread:

Operation.m

- (void) parseItems 
{
    while ([_data length] > 0)
    {
        NSInteger type = [self _readByte];

        switch (type) 
        {
            case SCREEN:
            {
                [self _send: [self _readScreen]];
                break;
            } 
            case CELL:
            {
                [self _send: [self _readCell]];
                break;
            } 

            // ... A lot of different items
        }
    }
}

- (void)_send:(CItem*)_item
{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"newItem" object:_item];
}

Then in notification receiver:

AppDelegate.m

- (void) _newItemArrived:(NSNotification *) notification
{
    [self performSelectorOnMainThread:@selector(processItem:) withObject:[notification object] waitUntilDone:NO];
}

My problem is that the UI is not painted until NSOperation finish. I thought that NSOpertion, being a different thread, would not block the main thread, but believe that is what is happening.

Some tips for this issue?

Thanks a lot for reading!

A: 

Are you using NSOperationQueue?

Check out this answer to the question NSOperation blocks UI painting? for a simple example of how to update the UI with a notification from an NSOperation running asynchronously on another thread.

UPDATE

  1. NSURLConnection supports asynchronous connections by itself with a delegate. You should use this. If you have specific issue(s), you should describe those.
  2. Check out the ASIHTTPRequest library.
  3. If you really want to use this approach, you could trying running NSURLConnection synchronously (using the class method sendSynchronousRequest:returningResponse:error:). Your app would remain responsive since the connection is on a background thread. However, you would not be able to update anything until all the data is received.
gerry3
Thanks for your answer!yes, i'm using NSOperationQueue. I've read that answer, and is just what im doing, but doesnt works. I must be missing something and i cant see it. :S
jota
Why are you forcing the start method from Operation to run on the main thread?
gerry3
Also, the way you are using NSURLConnection is for an asynchronous download, you do not need a separate thread. You just need to implement the delegate methods.
gerry3
Mmm, I've tried that, without NSOPeration, but I have not got the result I need. I keep trying, I'll tell you if I found some way.Thanks gerry!
jota
Can you provide more details? What did not work about NSURLConnection by itself?
gerry3