how to create a synchronous NSURLConnection request

11,492

Solution 1

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.

Solution 2

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].

Share:
11,492
C.Johns
Author by

C.Johns

Updated on June 14, 2022

Comments

  • C.Johns
    C.Johns almost 2 years

    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.

    • Nick Hutchinson
      Nick Hutchinson over 12 years
      What do you mean by "garnet the data I am receiving from the server is received in the order it is sent"? Synchronous networking—even in a background thread—is almost always an indicator of a bad design.
    • C.Johns
      C.Johns over 12 years
      well as far as I am aware async can sometimes receive data in an incorrect order. The database engine I am having to communicate with requires me to do this syncronosly as its important to receive the data in the correct order. Why do you think its an indicator of bad design, I'm interested in your perspective as I am currently only doing as I have been instructed however if I can put together a case to the database engineer as to why he should so otherwise I would be intrested in hearing your opinion.
    • Nick Hutchinson
      Nick Hutchinson over 12 years
      That's not correct — 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:. This would only be a problem if, for some reason, you were running multiple NSURLConnections at the same time, all with the same delegate. But you generally don't want to do that!
    • C.Johns
      C.Johns over 12 years
      okay cool I get what your saying thanks for the clarification.
  • Richard J. Ross III
    Richard J. Ross III over 12 years
    @C.Johns no problem, just remember to accept the answer if it does what you need it to.
  • C.Johns
    C.Johns over 12 years
    it will.. I had been searching the wrong thing.. this is defiantly what I need to be using. hopefully I can work thought it.
  • C.Johns
    C.Johns over 12 years
    Okay thats awesome thanks very much for you help. I'm going to go over it some more now :)
  • JaakL
    JaakL over 8 years
    This describes it nicely stackoverflow.com/questions/6212453/…