I am having a hard time to find any examples for NSURLConnection delegate method implementations.
I want to send data with a HTTP post with a button click. Not sure how to make a "submitting" screen and "submitted". (I know how to use spinner and will use them)
I am using this code under a botton click action, but unable to use any delegate stuff. Not sure how to implement them with my current set up.
NSMutableURLRequest *request =
[[NSMutableURLRequest alloc] initWithURL:
[NSURL URLWithString:#"http://myURL.com"]];
[request setHTTPMethod:#"POST"];
NSString *postString = [wait stringByAppendingString:co];
[request setValue:[NSString
stringWithFormat:#"%d", [postString length]]
forHTTPHeaderField:#"Content-length"];
[request setHTTPBody:[postString
dataUsingEncoding:NSUTF8StringEncoding]];
//[[NSURLConnection alloc] initWithRequest:request delegate:self];
[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
[SVProgressHUD dismissWithSuccess:#"Submission Successful"];
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(#"Did Receive Response %#", response);
responseData = [[NSMutableData alloc]init];
}
- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data
{
//NSLog(#"Did Receive Data %#", data);
[responseData appendData:data];
}
- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
{
NSLog(#"Did Fail");
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"Did Finish");
// Do something with responseData
}
You need to use the new NSURLConnectionDataDelegate protocol.
I found some exemples here:
http://blog.kemalkocabiyik.com/index.php/2012/02/fetching-data-with-getpost-methods-by-using-nsurlconnection/
And if you can read portuguese: http://www.quaddro.com.br/blog/desenvolvimento-ios/baixando-conteudo-com-nsurlconnection-e-nsurlconnectiondatadelegate-no-ios
//Connection request
-(void)requestURL:(NSString *)strURL
{
// Create the request.
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:strURL]];
// Create url connection and fire request
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
//Delegate methods
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(#"Did Receive Response %#", response);
responseData = [[NSMutableData alloc]init];
}
- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data
{
//NSLog(#"Did Receive Data %#", data);
[responseData appendData:data];
}
- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
{
NSLog(#"Did Fail");
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"Did Finish");
// Do something with responseData
NSString *strData=[[NSString alloc] initWithData:responseData encoding:NSASCIIStringEncoding];
NSLog(#"Responce:%#",strData);
}
http://codewithchris.com/tutorial-how-to-use-ios-nsurlconnection-by-example/
in this code you will use GCD ,Activity Indicator ,UIButton Action
on login button
First you will call StartActivityindicator on another thread and it keeps in moving until you remove or stop the Activityindicator.
then you will call the web service for login in GCD queue .
at the time you receive response from server call main queue to update the UI.
// After the interface declration
#interface LoginViewController ()
{
NSData *responseData;
dispatch_queue_t myqueue;
}
//Button Action
- (IBAction)Login_Button_Action:(id)sender
{
[NSThread detachNewThreadSelector: #selector(StartActivityindicator) toTarget:self withObject:nil];
myqueue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_group_t group=dispatch_group_create();
dispatch_group_async(group, myqueue, ^{ [self loginWebService];});
}
-(void)loginWebService
{
//Combine Both url and parameters
NSString *UrlWithParameters = [NSString stringWithFormat:#"http://www.xxxxx.com?count=%#&user=%#&email=%#&password=%#",#"4",#"Username",s#"UserEmail",#"PAssword String"];
//Pass UrlWithParameters to NSURL
NSURL *ServiceURL =[NSURL URLWithString:UrlWithParameters];
NSMutableURLRequest *serviceRequest =[NSMutableURLRequest requestWithURL:ServiceURL];
[serviceRequest setHTTPMethod:#"POST"];
[serviceRequest setValue:#"application/json" forHTTPHeaderField:#"accept"];
[serviceRequest setValue:#"application/json" forHTTPHeaderField:#"content-type"];
//GEt Response Here
NSError *err;
NSURLResponse *response;
responseData = [NSURLConnection sendSynchronousRequest:serviceRequest returningResponse:&response error:&err];
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
NSInteger code = [httpResponse statusCode];
// check status code for response from server and do RND for code if you recive anything than 200
NSLog(#"~~~~~ Status code: %ld",(long)code);
if (code ==200)
{
// your response is here if you call right
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:responseData options: NSJSONReadingMutableContainers error: &err];
dispatch_async(dispatch_get_main_queue(),^{
// place the code here to update UI with your received response
[NSThread detachNewThreadSelector: #selector(StopActivityindicator) toTarget:self withObject:nil];
});
}
}
//Activity indicator Method to display
- (void) StartActivityindicator
{
mySpinner.hidden = NO;
[mySpinner startAnimating];
}
- (void) StopActivityindicator
{
mySpinner.hidden = YES;
[mySpinner stopAnimating];
}
Related
i know there are a lot of questions about this but none seems to work for what I want to do. I want to change the value of a tag so let's say i have this file :
</Courbe>
<tempset>140</tempset>
</Courbe>
I want my http post request to change this value. How do I do this?
I have already tried something like that :
- (IBAction)changeTemp:(id)sender
{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://207.134.145.16:50001/Courbe.xml"]];
[request setHTTPMethod:#"POST"];
[request setValue:#"text/xml" forHTTPHeaderField:#"Content-type"];
NSString *xmlString = #"<tempset>137</tempset>";
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
Is it something like this? Thanks for your help!
Url encode the xmlString, then:
NSData *postData = [xmlString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
[request setHTTPBody:postData];
[request setValue:[NSString stringWithFormat:#"%d", [postData length]] forHTTPHeaderField:#"Content-Length"];
[request setValue:#"text/xml" forHTTPHeaderField:#"Content-Type"];
To send, use something like this:
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {}];
Prior to iOS5, you can send asynchronously this way:
// make the request and an NSURLConnection with a delegate
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
[[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];
// create a property to hold the response data, then implement the delegate methods
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
responseData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[responseData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[responseData release];
[textView setString:#"Unable to fetch data"];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *responseString = [[[NSString alloc] initWithData:responseData encoding: NSASCIIStringEncoding] autorelease];
}
In iOS (current target 5.0, Base SDK 5.1) how can I send a post request to a server, and then read the contents of the page. For example, the page takes a username and password, and then echos true or false. This is just for a better understanding of NSURLRequest.
Thanks in Advance!
A few things first
Decide how you want to encode your data - JSON or url-encoding are a good start.
Decide upon a return value - will it be 1, TRUE or 0, FALSE, or even YES/non-nil nothing/nil.
Read up on the URL Loading System, it's your friend.
Aim to make all your url connections asynchronous so your UI remains responsive. You can do this with NSURLConnectionDelegate callbacks. NSURLConnection has a small drawback: your code must be decoupled. Any variables you want available in the delegate functions will need to be saved to ivars or in your request's userInfo dict.
Alternatively you can use GCD, which, when coupled with the __block qualifiers, allows you to specify error/return code at the point you declare it - useful for one off fetches.
Without further ado, here's a quick and dirty url-encoder:
- (NSData*)encodeDictionary:(NSDictionary*)dictionary {
NSMutableArray *parts = [[NSMutableArray alloc] init];
for (NSString *key in dictionary) {
NSString *encodedValue = [[dictionary objectForKey:key] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *encodedKey = [key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *part = [NSString stringWithFormat: #"%#=%#", encodedKey, encodedValue];
[parts addObject:part];
}
NSString *encodedDictionary = [parts componentsJoinedByString:#"&"];
return [encodedDictionary dataUsingEncoding:NSUTF8StringEncoding];
}
Using a JSON library like JSONKit makes encoding things easier, consider it!
Method 1 - NSURLConnectionDelegate async callbacks:
// .h
#interface ViewController : UIViewController<NSURLConnectionDelegate>
#end
// .m
#interface ViewController () {
NSMutableData *receivedData_;
}
#end
...
- (IBAction)asyncButtonPushed:(id)sender {
NSURL *url = [NSURL URLWithString:#"http://localhost/"];
NSDictionary *postDict = [NSDictionary dictionaryWithObjectsAndKeys:#"user", #"username",
#"password", #"password", nil];
NSData *postData = [self encodeDictionary:postDict];
// Create the request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:[NSString stringWithFormat:#"%d", postData.length] forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request
delegate:self];
[connection start];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[receivedData_ setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[receivedData_ appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSLog(#"Succeeded! Received %d bytes of data", [receivedData_ length]);
NSString *responeString = [[NSString alloc] initWithData:receivedData_
encoding:NSUTF8StringEncoding];
// Assume lowercase
if ([responeString isEqualToString:#"true"]) {
// Deal with true
return;
}
// Deal with an error
}
Method 2 - Grand Central Dispatch async function:
// .m
- (IBAction)dispatchButtonPushed:(id)sender {
NSURL *url = [NSURL URLWithString:#"http://www.apple.com/"];
NSDictionary *postDict = [NSDictionary dictionaryWithObjectsAndKeys:#"user", #"username",
#"password", #"password", nil];
NSData *postData = [self encodeDictionary:postDict];
// Create the request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:[NSString stringWithFormat:#"%d", postData.length] forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Peform the request
NSURLResponse *response;
NSError *error = nil;
NSData *receivedData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
if (error) {
// Deal with your error
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
NSLog(#"HTTP Error: %d %#", httpResponse.statusCode, error);
return;
}
NSLog(#"Error %#", error);
return;
}
NSString *responeString = [[NSString alloc] initWithData:receivedData
encoding:NSUTF8StringEncoding];
// Assume lowercase
if ([responeString isEqualToString:#"true"]) {
// Deal with true
return;
}
// Deal with an error
// When dealing with UI updates, they must be run on the main queue, ie:
// dispatch_async(dispatch_get_main_queue(), ^(void){
//
// });
});
}
Method 3 - Use an NSURLConnection convenience function
+ (void)sendAsynchronousRequest:(NSURLRequest *)request queue:(NSOperationQueue *)queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler
Hope this helps.
NSData *postData = [someStringToPost dataUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:someURLString];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
[req setHTTPMethod:#"POST"];
[req setValue:[NSString stringWithFormat:#"%d", postData.length] forHTTPHeaderField:#"Content-Length"];
[req setValue:#"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[req setHTTPBody:postData];
NSError *err = nil;
NSHTTPURLResponse *res = nil;
NSData *retData = [NSURLConnection sendSynchronousRequest:req returningResponse:&res error:&err];
if (err)
{
//handle error
}
else
{
//handle response and returning data
}
This project might be quite handy for your purpose. It will take care of your downloads and store it locally. Check out the link https://github.com/amitgowda/AGInternetHandler
I have trouble finding info on this topic. Please help me out here.
I need to pass arguments via POST or GET method to my web server and get a reply.
Basically, if using GET method, I want to do something like server.com/?user=john&password=smith and receive the dynamically generated HTML code that is done with my php script. All this without using the web browser on my app.
How is it usually done?
You'll want to look into NSMutableURLRequest and NSURLConnection.
For example, you could use them like this do to a GET request to your server:
- (void)loginUser:(NSString *)username withPassword:(NSString *)password {
// GET
NSString *serverURL = [NSString stringWithFormat:#"http://yourserver.com/login.php?user=%#&pass=%#", username, password];
NSURL *url = [NSURL URLWithString:serverURL];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:req delegate:self];
if (connection) {
connectionData = [[NSMutableData alloc] init];
}
}
This will send an asynchronous GET request to your server with the query string containing username and password.
If you want to send username and password using a POST request, the method would look something like this:
- (void)loginUser:(NSString *)username withPassword:(NSString *)password {
// POST
NSString *myRequestString = [NSString stringWithFormat:#"user=%#&pass=%#",username,password];
NSData *myRequestData = [NSData dataWithBytes: [myRequestString UTF8String] length: [myRequestString length]];
NSURL *url = [NSURL URLWithString:#"http://yourserver.com/login.php"];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
[req setHTTPMethod: #"POST"];
[req setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"content-type"];
[req setHTTPBody: myRequestData];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:req delegate:self];
if (connection) {
connectionData = [[NSMutableData alloc] init];
}
}
In order to get the response from the server, you will need to implement the NSURLConnection delegate methods, for example:
#pragma mark -
#pragma mark NSURLConnection delegate methods
#pragma mark -
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
// Called if you have an .htaccess auth. on server
NSURLCredential *newCredential;
newCredential = [NSURLCredential credentialWithUser:#"your_username" password:#"your_password" persistence:NSURLCredentialPersistenceForSession];
[[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge];
}
-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[connectionData setLength: 0];
}
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[connectionData appendData:data];
}
-(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[connectionData release];
}
-(void) connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *content = [[NSString alloc] initWithBytes:[connectionData bytes]
length:[connectionData length] encoding: NSUTF8StringEncoding];
// This will be your server's HTML response
NSLog(#"response: %#",content);
[content release];
[connectionData release];
}
References:
NSMutableURLRequest Class Reference
NSURLConnection Class Reference
Hope this helps :)
Usually this is done using a NSURLConnection. You can also use NSString's method stringWithContentsOfURL.
I am calling NSURLConnection asynchronous method calls in my view controller. I would like to handle TWO RESPONSES FOR TWO REQUEST in the same Delegate. Please suggest me what would the best approach to achieve this? I'm developing in iOS 5 SDK.
UPDATED:
// Class A
[serverconns setDelegate:self];
connection = [serverconns executeAsyncHttpPost :firstjsonrequest];
[serverconns setDelegate:self];
connection = [serverconns executeAsyncHttpPost :secondjsonrequest];
- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
}
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.appendData appendData:data];
}
- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
// logs the error
}
- (void) connectionDidFinishLoading:(NSURLConnection *)connection
{
NSData *responseData = [[NSData alloc] initWithData:appendData];
//HOW CAN WE HANDLE TWO RESPONSES FOR TWO REQUEST in the same Delegate
if (responseData)
{
// doing something
}
}
//Class B: ServerConnection
- (NSURLConnection *) executeAsyncHttpPost :(id) jsonParams
{
NSString *urlstr = [NSString stringWithFormat:#"%#", baseURL];
urlstr = [urlstr stringByAppendingFormat:method];
NSURL *pUrl = [NSURL URLWithString:urlstr];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:pUrl];
NSData *requestData = [NSData dataWithBytes:[jsonParams UTF8String] length:[jsonParams length]];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-type"];
[request setHTTPBody: requestData];
return [[NSURLConnection alloc] initWithRequest:request delegate:delegateResponder startImmediately:YES];
}
-(void) setDelegate:(id)newDelegate
{
delegateResponder = newDelegate;
}
save your connections somewhere (maybe ivar of your delegate)
- (void) connectionDidFinishLoading:(NSURLConnection *)connection
{
NSData *responseData = [[NSData alloc] initWithData:appendData];
//HOW CAN WE HANDLE TWO RESPONSES FOR TWO REQUEST in the same Delegate
if (responseData)
{
if (connection == yourFirstConnection) {
// doing something for first connection
} else {
// doing something for second connection
}
}
}
just point out some minor problem of your code
NSString *urlstr = [NSString stringWithFormat:#"%#", baseURL];
urlstr = [urlstr stringByAppendingFormat:method];
should replace to
NSString *urlstr = [baseURL absoluteString];
urlstr = [urlstr stringByAppendingString:method];
and add two(or more or array) weak/assign property of NSURLConnection to your class A (connection delegate)
#property (assign) NSURLConnection *myFirstConnection;
#property (assign) NSURLConnection *mySecondConnection;
// assume only need to handle two connection otherwise NSArray should be used instead
than in your class B (create connection)
- (NSURLConnection *) executeAsyncHttpPost :(id) jsonParams
{
NSString *urlstr = [baseURL absoluteString];
urlstr = [urlstr stringByAppendingString:method];
NSURL *pUrl = [NSURL URLWithString:urlstr];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:pUrl];
NSData *requestData = [NSData dataWithBytes:[jsonParams UTF8String] length:[jsonParams length]];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-type"];
[request setHTTPBody: requestData];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:delegateResponder startImmediately:YES];
delegateResponder.myFirstConnection = connection;
// delegateResponder.mSecondConnection = connection;
return connection;
}
If I were you I would create a CustomClass which inherits the NSURLConnection. And I will add property called tag.
When I initiate the CustomClass, I would set the tag property and use that to determine which request is being worked on
CustomURLConnection *connection = [[CustomURLConnection alloc] initWithRequest:request delegate:self tag:1];
- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate tag:(int)_tag
{
if(self = [super initWithRequest:request delegate:delegate])
{
self.tag = _tag;
}
Now in the code you posted add this
- (void) connectionDidFinishLoading:(NSURLConnection *)connection
{
NSData *responseData = [[NSData alloc] initWithData:appendData];
//HOW CAN WE HANDLE TWO RESPONSES FOR TWO REQUEST in the same Delegate
if (responseData)
{
if (connection.tag == 1){
}
}
}
return self;
}
I think all the mentioned solutions are "ugly". I would not implement a solution with delegate methods but instead create a blocks-based solution. I could post an example if you're interested. I would make use of the AFNetworking classes for this approach.
What follows is an example of a class that handles 2 different responses without using a delegate implementation, opting for blocks instead with the AFNetworking library.
- (void)JSONFromService
{
// create the first request and set the methods that handle the return values (either NSData or NSError in this case) in blocks ...
NSURL *firstURL = [NSURL URLWithString:#"http://dl.dropbox.com/u/6487838/test1.html"];
NSURLRequest *firstRequest = [NSURLRequest requestWithURL:firstURL];
AFHTTPRequestOperation *firstOperation = [[AFHTTPRequestOperation alloc] initWithRequest:firstRequest];
[firstOperation setCompletionBlockWithSuccess:^ (AFHTTPRequestOperation *operation, id object)
{
NSString *firstString = [[NSString alloc] initWithData:object encoding:NSASCIIStringEncoding];
NSLog(#"%#", firstString);
} failure:^ (AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"%#", error);
}];
[firstOperation start];
// create the second request and set the methods that handle the return values (either NSData or NSError in this case) in blocks ...
NSURL *secondURL = [NSURL URLWithString:#"http://dl.dropbox.com/u/6487838/test2.html"];
NSURLRequest *secondRequest = [NSURLRequest requestWithURL:secondURL];
AFHTTPRequestOperation *secondOperation = [[AFHTTPRequestOperation alloc] initWithRequest:secondRequest];
[secondOperation setCompletionBlockWithSuccess:^ (AFHTTPRequestOperation *operation, id object) {
NSString *secondString = [[NSString alloc] initWithData:object encoding:NSASCIIStringEncoding];
NSLog(#"%#", secondString);
} failure:^ (AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"%#", error);
}];
[secondOperation start];
}
I usually subclass NSURLConnection and add properties to store whatever context I need to handle the response.
Since the delegate methods get NSURLConnection passed in, you can just cast it back to your subclass and access the context.
Take a look at this example.
I think you should keep all of your connections in an activeConnections array. Every time one finishes, you do [activeConnections indexForObject:connection] and you update your delegate method accordingly, using the index.
Now, a cleaner way to do it( and a better way from my point of view, but this depends on how large is the data you want to transfer) is to use queues. I'll provide a small example and add comments to it:
// we assume you have 2 requests: req1, req2
//now, create a new dispatch queue
dispatch_queue_t netQueue = dispatch_queue_create("com.mycompany.netqueue",DISPATCH_QUEUE_SERIAL);
//execute the operations in the queue ASYNC
//is very important to dispatch this ASYNC on a background thread, otherwise your UI will be stuck until the request finishes
dispatch_async(netQueue,
^{
// We are on a background thread, so we won't block UI events (or, generally, the main run loop)
NSHTTPURLResponse *response = nil;
NSError *error = nil;
NSData *data = nil;
//We can call the request synchronous and block this thread until completed
data = [NSURLConnection sendSynchronousRequest:req1
returningResponse:&response
error:&error];
dispatch_async(dispatch_get_main_queue(),
^{
//call your delegate with the appropriate method for req1
//be sure to copy the contents in data, as we will reuse it with the next request
});
//We can call the other request synchronous and block this thread until completed
data = [NSURLConnection sendSynchronousRequest:req2
returningResponse:&response
error:&error];
dispatch_async(dispatch_get_main_queue(),
^{
//call your delegate with the appropriate method for req2
});
//and this can go on forever. If you have many requests to execute, simply put them in a loop
});
dispatch_release(netQueue);
I have a rather unusual issue here. The code below is running fine and the data is sending to the source fine, but none of the NSURLConnection triggers are returning anything. The only items being logged are in the function that the request is sent in. Any ideas?
// code starts above here
NSData *myRequestData = [ NSData dataWithBytes: [ requestString UTF8String ] length: [ requestString length ] ];
NSURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlPrefix]];
[request setHTTPMethod: #"POST"];
[request setHTTPBody: myRequestData];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"content-type"];
NSURLResponse *resp = nil;
NSError *err = nil;
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse: &resp error: &err];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
if (!theConnection)
{
NSLog(#"Failed to submit request");
}
if(theConnection)
{
NSMutableData* receivedData=[[NSMutableData data] retain];
NSLog(#"Created connection.");
NSLog(#"--------- Request submitted ---------");
NSLog(#"receivedData: %#", receivedData);
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(#"Received response: %#", response);
NSLog(#"Received response, connection retain count is %d",[connection retainCount]);
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSLog(#"Connection received data, retain count: %d", [connection retainCount]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSLog(#"finished connection retain count: %d", [connection retainCount]);
}
This is the problem:
NSData *response = [NSURLConnection sendSynchronousRequest:request
returningResponse:&resp
error:&err];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:request
delegate:self
startImmediately:YES];
First you start a synchronous request and then you start the request again but than asynchronous. Makes no sense.
Try removing the first line.