C.Johns
C.Johns

Reputation: 10245

how to create a synchronous NSURLConnection request

I am wanting to create a synchronous nsurlconnection request. Yes I know its stupid and I know the limitations (freezing the UI) however the reason I would like to implement this to garnet the data I am receiving from the server is received in the order it is sent, which Is one of the benefits of a synchronous connection.. if I read correctly.

I am going to be using Grand Central Dispatch to achieve some multi threading in order to run the sync request and not have it effect the UI of the main thread... but this can come later for now I would like to master the sync connection.

The one issue is that I'm not exactly sure how to set my connection as synchronous..

Here is my code.

- (void)loadComics{

    [comics removeAllObjects]; //clears object of any old values
    [[self tableView] reloadData];

    NSURL *url = [NSURL URLWithString:@"http://www.comicbookresources.com/feed.php?feed=previews"];

    NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30];

    //clear any existing connection
    if (connectionInProgress) {
        [connectionInProgress cancel];
        [connectionInProgress release];
    }

    [xmlData release];
    xmlData = [[NSMutableData alloc] init];

    connectionInProgress = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
    [xmlData appendData:data];
}

- (void) connectionDidFinishLoading:(NSURLConnection *)connection{

    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:xmlData];

    [parser setDelegate:self];

    [parser parse];

    [parser release];
    [[self tableView] reloadData];
}

any examples would be great.

Upvotes: 1

Views: 11505

Answers (2)

Richard J. Ross III
Richard J. Ross III

Reputation: 55563

If you want a synchronous connection, you must use +sendSynchronousRequest:returningResponse:error there is no other easy way to do this.

Note that it's deprecated in favor of NSURLSession, but it doesn't support synchronous connection directly.

Upvotes: 9

Nick Hutchinson
Nick Hutchinson

Reputation: 5189

Synchronous networking, even in a background thread, isn't the way to go. You can't properly support cancellation, and you're wasting resources, spinning off a background thread that will spend most of its time idle. While this is mostly an academic concern if you're only sending off one URL request, it can be another story if you send out a large number of them.

You don't have to worry about receiving connection:didReceiveData: callbacks out of order. What you've written looks fine — you can just concatenate the chunks of data as you receive them, and do something with the complete data in connectionDidFinishLoading:.

What you do have to worry about is receiving multiple connection:didReceiveResponse: callbacks in the case of redirects. See Apple's documentation. In this case, you'll simply want to reset the data you've accumulated so far with [xmlData setLength:0].

Finally, if you can require iOS5 or 10.7 and don't need the complexity of a NSURLConnection delegate, then the new +[sendAsynchronousRequest:queue:completionHandler:] method is a nice, non-evil alternative to +[sendSynchronousRequest:returningResponse:error].

Upvotes: 4

Related Questions