ASIHTTPRequest cansel request (using block) - ios

I need to cancel my request. How can I make this. I have tried to create property and use it as assign for ASIHTTPRequest *request. But when I called [request cancel] I have bed access, because request retain count has 0 (due [ASIHTTPRequest requestWithURL:url] return autorelease object). I can't create strong property, I get this warning:
Capturing 'request' strongly in this block is likely to lead to a retain cycle
This is my code below:
__unsafe_unretained __block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setCompletionBlock:^{
NSString *response = [request responseString];
}];
[request setFailedBlock:^{
}];
[request startAsynchronous];

Related

Calling NSURLConnection one by one

I have a NSMutableArray containing 10 URLs from which I need to grab the HTTP headers.
Below is my code:
for(int i=0; i<[contactsArray count];i++)
{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
NSString *reqstr=[NSString stringWithFormat:#"%#",urlString ];
[request setURL:[NSURL URLWithString:reqstr]];
NSLog(#"requested url is %#",reqstr);
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/json" forHTTPHeaderField:#"content-type"];
[request setHTTPBody:[mDict JSONData]];
NSURLConnection *theConnection=[[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:YES];
}
current result: all requests are going to server at a time.
expected result: want to send one request to sever after getting response I want to send another request in background.
Any suggestions?
Refactor your code to use the sendAsynchronousRequest:queue:completionHandler: method, and call itself once the current post is complete:
Move your count to an instance variable. Let's call it currentItem. Your code might look something like this:
- (void) postItems;
{
while (currentItem < [contactsArray count)
{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
NSString *reqstr=[NSString stringWithFormat:#"%#",urlString ];
[request setURL:[NSURL URLWithString:reqstr]];
NSLog(#"requested url is %#",reqstr);
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/json" forHTTPHeaderField:#"content-type"];
[request setHTTPBody:[mDict JSONData]];
[NSURLConnection sendAsynchronousRequest: request
queue: dispatch_get_main_queue ()
completionHandler: ^(NSURLResponse *response, NSData *data, NSError *error)
{
//check for errors
//save any response data
//Now trigger the next request
currentItem++
[self postItems];
}
];
}
}
(The syntax for the completion block might not be exactly right. I struggle a little with the syntax for blocks that take parameters.)
You use ASIHTTPRequest asynchronous call:
Link for ASIHTTPRequest
Then write like following code:
for(int i=0; i<[contactsArray count];i++)
{
NSURL* url = [NSURL URLWithString:urlString];
__block ASIHTTPRequest* request = [ASIHTTPRequest requestWithURL:url];
[request setCompletionBlock:^
{
//NEED SOMEHOW RETURN TRUE IF SUCESSED
}];
[request setFailedBlock:^
{
//NEED RETURN FALSE
}];
[request startAsynchronous];
}

Though I follow _Block , Memory Leak Happening # ASIHTTPRequest

Its my code , can you help where am I missing to handle Memory? I'm using X-Code 4.6. And also I have checked instrument , to get other memory leaks. Its almost showing all "ASIHTTPRequest". Im not handling manually like [request release]; Is that necessary to fix memory leak? Thanks in advance
__block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setCompletionBlock:^{
}];
[request setFailedBlock:^{
}];
[request setTimeOutSeconds:60];
[request startAsynchronous];
It leaks because of the retain cycle created between the block and the request object.
Try the below:
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
__weak ASIHTTPRequest *weakRequest = request;
[request setCompletionBlock:^{
}];
[request setFailedBlock:^{
}];
[request setTimeOutSeconds:60];
[request startAsynchronous];
Cheers..
EDIT:
ASIHTTPRequest is not supported anymore, try to move to AFNetworking, it is the best.
Then instead do this:
__weak __block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setCompletionBlock:^{
__strong ASIHTTPRequest *requestInBlock = request;
//your code, and replace all refrences of request inside the block with requestInBlock.
}];
[request setFailedBlock:^{
//same here
}];
[request setTimeOutSeconds:60];
[request startAsynchronous];
try this out.

ASIHTTPRequest delegation

im using ASIHTTPRequest to call webservice (soap):
-(void)callWebService:(NSString*)URL:(NSString*)SOAP{
NSURL *url = [NSURL URLWithString:URL];
NSString *SOAPMessage = [NSString stringWithFormat:SOAP];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
request.shouldAttemptPersistentConnection = NO;
[request setValidatesSecureCertificate:NO];
[request setRequestMethod:#"POST"];
[request appendPostData:[SOAPMessage dataUsingEncoding:NSUTF8StringEncoding]];
[request setDidFinishSelector:#selector(requestCompleted:)];
[request setDidFailSelector:#selector(requestFailed:)];
[request setDelegate:self];
[request startAsynchronous];
}
-(void)requestCompleted:(ASIHTTPRequest * )r{
NSString *responseString = [r responseString];
NSLog(#"%#",responseString);
}
-(void)requestFailed:(ASIHTTPRequest * )r{
NSError *Err = [r error];
NSLog(#"%#",Err);
}
If i call this in appDelegate.m, it works fine, requestCompleted handler throws the response...But when i use this same code in my own class it throws BAD ACCESS error, which i figured tells me i cannot delegate:self to handle response. if i setDelegate to appdelgate pointer (passed as ID sender) it works (and have handlers there). So why cant my own class handle its own events ? Im new to objective-c so i guess im missing something major here. Thanks
You have to have the requestCompleted and requestFailed in your "own class". Also that class has to live which means it can't be released while the service is being called. You have to save the instance of "your own class" in a strong/retained property or something.
Add this code to dealloc or viewWillDisappear
[request setDelegate:nil];
Check if your self is getting released while the delegate call happens. Make sure it is retained properly.

NSURLRequest HTTPBody vs. ASIHTTPRequest postBody

I'm trying to convert most of a project's NSURLRequests that use NSURLConnection to ASIHTTPRequest calls. I came across an issue about setting the HTTPBody in an ASIHTTPRequest. Here's what I had for the NSURLRequest call:
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.urlString]];
[req setHTTPMethod:#"POST"];
[req setHTTPBody:[self.paramString dataUsingEncoding:NSUTF8StringEncoding]];
[self _sendRequest:req];
And to convert to ASI, this is what I have so far:
__block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:self.urlString]];
[request setRequestMethod:#"POST"];
[request appendPostData:[self.paramString dataUsingEncoding:NSUTF8StringEncoding]];
[request setCompletionBlock:^{
NSLog(#"ASIHTTP request finished: %#", [request responseString]);
// Do stuff here
}];
[request setFailedBlock:^{
NSError *error = [request error];
NSLog(#"ASIHTTP error: %#", [error description]);
}];
[request startAsynchronous];
Although when I run this with ASI, I get this error:
ASIHTTP error: Error Domain=ASIHTTPRequestErrorDomain Code=6 "Unable to start HTTP connection" UserInfo=0x10ddf6b0 {NSLocalizedDescription=Unable to start HTTP connection}
EDIT This error was fixed, but data is still not being transmitted correctly due to the body not being set.
I'm thinking this has to do with me not setting the body correctly. I tried using ASI's setPostBody, but that only produced the same result. This works fine with NSURLRequest, but not ASI. I'm pretty sure it's really simple and I just haven't explored ASI's full library quite yet, but I was just wondering if anyone had any suggestions. I have read the documentation, but I couldn't find what I was looking for.
Thanks!
Could you check that
self.paramString
is correct? How does it look like?
I ended up using ASIFormDataRequest and setting values and keys. That seemed to work!

Passing an object into a ASIHTTPRequest block

OK. I'm not completely clear about blocks, but I do use them often; especially when doing an ASIHTTPRequest. I'd like to pass an object into the block and have the request assign a value to the object on completion, but I don't know how to make the object 'available' inside a block.
Here's my method...
- (void)fetchImageAsynchronously:(NSURL *)theURL intoImageObject:(UIImage *)anImageObject
{
__block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:theURL];
[request setDownloadCache:[ASIDownloadCache sharedCache]];
[request setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
[request setCompletionBlock:^{
NSData *responseData = [request responseData];
anImageObject = [UIImage imageWithData:responseData];
}];
[request setFailedBlock:^{
// NSError *error = [request error];
}];
[request startAsynchronous];
}
So, when the request completes, I want the value of anImageObject to be the fetched image. But anImageObject is not available inside the block.
Would someone kindly help?
anImageObject would have to be passed by reference. That is, UIImage**, and pass the address of anImageObject when calling the method.
This isn't a great design because you'll also have to manage the lifetime of anImageObject and also likely post some sort of notification that it is ready. That is, this code will break if anImageObject is deallocated in the time that it takes to download the image data. And you wont know that anImageObject was initialized with data or not.
- (void)fetchImageAsynchronously:(NSURL *)theURL intoImageObject:(UIImage **)anImageObject
{
__block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:theURL];
[request setDownloadCache:[ASIDownloadCache sharedCache]];
[request setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
[request setCompletionBlock:^{
NSData *responseData = [request responseData];
*anImageObject = [UIImage imageWithData:responseData];
}];
[request setFailedBlock:^{
// NSError *error = [request error];
}];
[request startAsynchronous];
}

Resources