Hello good morning everyone. I am using asihttprequest for a series of images download - 4 images from server.However i noticed an issues and cannot find a solution. Suppose i am downloading 4 images via URL and in case any one or 2 of the images is not available it cancels the whole queue.
Here is my code :
[networkQueue setDownloadProgressDelegate:progressIndicator];
[networkQueue setRequestDidFinishSelector:#selector(imageFetchComplete:)];
[networkQueue setRequestDidFailSelector:#selector(imageFetchFailed:)];
request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:#"http://imagees/image1.jpg"]];
[request setDownloadDestinationPath:[[NSHomeDirectory() stringByAppendingPathComponent:#"Documents"] stringByAppendingPathComponent:#"1.png"]];
[request setDownloadProgressDelegate:imageProgressIndicator1];
[request setUserInfo:[NSDictionary dictionaryWithObject:#"request1" forKey:#"name"]];
[networkQueue addOperation:request];
request = [[[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:#"sdvdsvsadvsadv"]] autorelease];
[request setDownloadDestinationPath:[[NSHomeDirectory() stringByAppendingPathComponent:#"Documents"] stringByAppendingPathComponent:#"2.png"]];
[request setDownloadProgressDelegate:imageProgressIndicator2];
[request setUserInfo:[NSDictionary dictionaryWithObject:#"request2" forKey:#"name"]];
[networkQueue addOperation:request];
- (void)imageFetchComplete:(ASIHTTPRequest *)request
{
UIImage *img = [UIImage imageWithContentsOfFile:[request downloadDestinationPath]];
if (img) {
if ([imageView1 image]) {
if ([imageView2 image]) {
[imageView3 setImage:img];
} else {
[imageView2 setImage:img];
}
} else {
[imageView1 setImage:img];
}
}
}
- (void)imageFetchFailed:(ASIHTTPRequest *)request
{
if (!failed) {
if ([[request error] domain] != NetworkRequestErrorDomain || [[request error] code] != ASIRequestCancelledErrorType) {
UIAlertView *alertView = [[[UIAlertView alloc] initWithTitle:#"Download failed" message:#"Failed to download images" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil] autorelease];
[alertView show];
}
failed = YES;
}
}
The problem is that suppose fetching second image failed, it displays the error message and stops the whole operation, although image 1 is a valid image file.
Any help will be greatly appreciated.
:)
From the ASIHTTPRequest documentation:
When a request in an ASINetworkQueue fails, the queue will by default
cancel all other requests. You can disable this behaviour with [queue
setShouldCancelAllRequestsOnFailure:NO].
Related
I am performing JSON POST request by clicking UIButton and after the submission, segue perform can be done. So, After submitting values, I cannot perform POST request anymore. It shows status code 200 and response is OK. But, data is not reflected in the Backend. Here is my code:
(IBAction)transitsurveydone:(id)sender {
if([tempArray count]!=0){
/* alert= [[UIAlertView alloc] initWithTitle:#"Survey Submission"
message:#"Please Enter your location"
delegate:self
cancelButtonTitle:#"Modify"
otherButtonTitles:#"Submit",nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
alert.tag=2;
[alert show];*/
NSLog(#"Caption array is %# %#",captionArray,tempArray);
NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:#"myURL"]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSMutableDictionary *postDict = [[NSMutableDictionary alloc]init];
NSMutableDictionary *d=[[NSMutableDictionary alloc] initWithObjectsAndKeys:#10,#"\"Bus\"", nil];
NSMutableArray *m=[[NSMutableArray alloc] init];
NSString *str1,*str2,*str3,*str4;
// Checking the format
if(tempArray.count==1){
for (int x=0; x<1; x++) {
str1=[NSString stringWithFormat:#"\"%#\"",[captionArray objectAtIndex:x]];
[d setObject:[tempArray objectAtIndex:x] forKey:str1];
}
[request setHTTPBody:[[NSString stringWithFormat: #"{\n \"instance\" : %#,\n \"response_method\": \"web\",\n \"routes\": [\n {%#:%#}\n ]\n}",randomString,str1,[d objectForKey:str1] ]dataUsingEncoding:NSUTF8StringEncoding]];
}
NSLog(#"%#:%#",str1,[d objectForKey:str1]);
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
// Handle error...
return;
}
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSLog(#"Response HTTP Status code: %ld\n", (long)[(NSHTTPURLResponse *)response statusCode]);
NSLog(#"Response HTTP Headers:\n%#\n", [(NSHTTPURLResponse *)response allHeaderFields]);
}
NSString* body = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Response Body:\n%#\n", body);
}];
[task resume];
NSHTTPURLResponse *response = nil;
NSError *error = nil;
NSData *respData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"~~~~~ Status code: %d", [response statusCode]);
if([response statusCode]==200){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"Transit Survey submitted" delegate:self cancelButtonTitle:nil otherButtonTitles:nil];
alert.transform = CGAffineTransformMakeTranslation( 10, 740);
[alert show];
[self performSelector:#selector(dismissAlert:) withObject:alert afterDelay:1.0f];
submitteddonthide=NO;
}
else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"Transit Survey Submission Failed" delegate:self cancelButtonTitle:nil otherButtonTitles:nil];
alert.transform = CGAffineTransformMakeTranslation( 10, 740);
[alert show];
[self performSelector:#selector(dismissAlert:) withObject:alert afterDelay:1.0f];
}
if([prefs integerForKey:#"humandone"]==1){
[self performSegueWithIdentifier:#"transittohuman" sender:nil];
}
else{
[self performSegueWithIdentifier:#"gobackfromtransit" sender:nil];
}
}
`
The above code is in IBAction
Your code looks fine and there is no any issues.
If this issue is happens all the time, add "Advanced Rest Client" add-on to chrome browser and test your server URL passing respective input values. If this process also can't be able to update values on your backend there should be some issue on your backend.
A couple of thoughts:
You are using status code to determine whether the server inserted the data correctly or not. You should actually have your web service build an affirmative response (in JSON, would be great) that says whether data was successfully inserted or not. You should not be relying solely on the web server's request response code.
I would observe the request with something like Charles and make sure it looks OK.
You're building a JSON request manually, which is very fragile. I would suggest using Charles to observe the request, and copy and paste it into http://jsonlint.com and make sure it's OK.
Even better, use NSJSONSerialization which is more robust and easier to use.
Also, you're sending this request twice. Lose this second request (you shouldn't do synchronous requests, anyway) and put all of your confirmation logic inside the session's completion handler block.
Yes. After struggling a bit, Clearing cookies helped me a lot :-
Here is a chunk of code, which is pretty much simple
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSArray *cookies = [cookieStorage cookiesForURL:[NSURL URLWithString:urlString]];
for (NSHTTPCookie *cookie in cookies) {
NSLog(#"Deleting cookie for domain: %#", [cookie domain]);
[cookieStorage deleteCookie:cookie];
}
Thank you Mr. reddys and Rob for the suggestions
How to upload a image to server using ASIFormDataRequest ?
i tried to upload a image its does't show's any error while inserting. and in my requesting did finished method iam getting response as success. so what is the problem is, when i get the data what i have inserted in that i am not able to get the image what i have inserted but iam getting the image path also.
here is my code
NSString *globalurl =[[NSUserDefaults standardUserDefaults]valueForKey:#"Global_Url"];
NSString *urlStr=[NSString stringWithFormat:#"%#/InsertUserInfo?User_Name=%#&User_Pwd=%#&User_FName=%#&User_LName=%#&User_Mail=%#&User_Phno=%#&User_Address=%#&User_Dob=%#&Ic_No=%#&User_Active=%#&User_Questions=%#&User_Ans=%#",globalurl,usernameTxtFld.text,pwdTxtFld.text,firstName.text,lastName.text,email.text,phonNO.text,address.text,dateOfbirth.text,nricNo.text,#"10001",#"",#""];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:urlStr]];
[request setRequestMethod:#"POST"];
[request setDelegate:self];
[request addData:dataImage withFileName:#"Image.png" andContentType:#"image/png" forKey:#"photo"];
//check if passedData is nil
if (dataImage == nil)
{
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"title:iDnil" message:#"nil" delegate:nil cancelButtonTitle:#"fgff" otherButtonTitles:#"erer", nil];
[alert show];
}
[request startAsynchronous];
-(void)requestFinished:(ASIHTTPRequest *)request {
NSString *receivedString = [request responseString];
NSLog(#"received messge %#",receivedString);
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:#"Message" message:receivedString delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alertView show];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
dataImage = UIImageJPEGRepresentation([info objectForKey:#"UIImagePickerControllerOriginalImage"],1);
NSLog(#"dict is %#",info);
UIImage *image=[info objectForKey:UIImagePickerControllerOriginalImage];
[self dismissModalViewControllerAnimated:YES];
}
You can use
[request setFile:#"YOUR IMAGE FILE PATH" forKey:#"photo"];
instead of [request addData:dataImage withFileName:#"Image.png" andContentType:#"image/png" forKey:#"photo"];
as explained in the post . It worked for me like a charm :-)
I have uploaded an example application performing textfile, Image, Video, Images upload in queue, Videos to GitHub on this link. You may well consider having a look at it.
ASI-http-request has an optimisation option to stream your image files right away from your disk, which is the best I've seen with this library. Please consider using the below code snippet for creating ASIFormDataRequest.
// Initilize Variables
NSURL * url = [NSURL URLWithString:IMAGE_POST_URL];
// Add Image
NSString *path = [[NSBundle mainBundle]pathForResource:#"image1" ofType:#"jpg"];
// Get Image
NSData *imageData = [[NSData alloc]
initWithContentsOfFile:path];
// Return if there is no image
if(imageData != nil){
//Request-1
ASIFormDataRequest * request1;
[request1 setTag:201];
request1 = [[ASIFormDataRequest alloc] initWithURL:url];
[request1 setPostValue:#"ID = 201" forKey:#"image_upload"];
[request1 setFile:path forKey:#"image1_file"];
[request1 setDelegate:self];
[request1 setDidFinishSelector:#selector(imageUploadDidFinish:)];
[request1 setDidFailSelector:#selector(imageUploadDidFail:)];
[request1 setTimeOutSeconds:500];
[request1 setShouldStreamPostDataFromDisk:YES];
}
I have a UITableView that is populated with an array, it contains cell label and cell detail text, the detail text is basically the URL at which the file is saved. I want that on long press of the uitableviewcell a pop up comes up which has the option to download the file and on clicking that option the file is saved in a specific directory on the phone memory.
How can i do that?
Add gesture to your cell object
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:#selector(handleLongPress:)];
lpgr.minimumPressDuration = 1.0; //seconds
lpgr.delegate = self;
[objMyTableViewCell addGestureRecognizer:lpgr];
[lpgr release];
Handle it
-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
UITableVIewCell *objTableCell = (UITableVIewCell*)gestureRecognizer
NSURL *url = [NSURL URLWithString:objTableCell.lable.text];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request setDidFinishSelector:#selector(requestDone:)];
[request setDidFailSelector:#selector(requestWentWrong:)];
[request setDownloadDestinationPath:[NSString stringWithFormat:#"%#",filePath]]; //use the path from earlier
[queue addOperation:request]; //queue is an NSOperationQueue
[request setDownloadProgressDelegate:self];
[request setShowAccurateProgress:YES];
}
Response method for download file
- (void)requestDone:(ASIHTTPRequest *)request
{
NSString *response = [request responseString];
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle: #"hurreh!!"
message: #"Your download complete"
delegate: nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
//Do something useful with the content of that request.
}
- (void)requestWentWrong:(ASIHTTPRequest *)request
{
NSError *error = [request error];
}
For long press on the UITableViewCell you can use the UILongPressGestureRecognizer.
To show the options you can use the UIActionSheet.
To download file you can use NSURLConnection or ASIHTTPRequest.
I´m new in Xcode and have a problem with UIProgressView.
I found some code but I don't understand it well. Could you please explain me why UIProgressView is not closing after finish?
- (IBAction)Download:(id)sender
{
NSURL *url = [NSURL URLWithString:#"http://db.tt/5WP2pia"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request startAsynchronous];
progressView = [[UIProgressView alloc]
initWithFrame:CGRectMake(30.0f, 80.0f, 225.0f, 90.0f)];
UIAlertView *progressAlert =
[[UIAlertView alloc] initWithTitle: #"Download..."
message: #"Please wait..."
delegate: self
cancelButtonTitle: nil
otherButtonTitles: nil];
[progressAlert addSubview:progressView];
[progressView setProgressViewStyle: UIProgressViewStyleBar];
[request setDownloadDestinationPath:#"/var/root/osk.rar"];
[request setDownloadProgressDelegate:progressView];
[progressAlert show];
[progressAlert release];
}
You have to manually close the alert, after ASIHTTPRequest is done. progressView != progressAlert
Don't use ASIHTTPRequest
I am downloading a bunch of images via ASINetworkQueue. I have no problems in the simulator, but on the iPad some of the images (each time they are different) are not downloaded. How can I fix this?
Here is the code:
Queue Creation:
if (addedPaintings > 0) {
[currentPaintingsArray addObjectsFromArray:objectsToAdd];
[unseenPaintings addObjectsFromArray:objectsToAdd];
[self downloadImages];
}
// update plist file if data was altered.
if (addedPaintings > 0 || removedPaintings > 0)
[currentPaintingsArray writeToFile:dataFilePath atomically:YES];
else
[self completeSync:request.responseStatusCode];
}
Image Download method:
- (void) downloadImages {
[networkQueue reset];
[networkQueue setDelegate:self];
[networkQueue setShowAccurateProgress:YES];
[networkQueue setDownloadProgressDelegate:self.progressView.customView];
[networkQueue setQueueDidFinishSelector:#selector(imageQueueDownloadComplete:)];
for (NSDictionary *dict in [Globals sharedGlobals].unseenPaintings) {
NSString *link = [dict objectForKey:#"link"];
NSString *smallLink = [dict objectForKey:#"smallLink"];
if ([link length] != 0) {
NSURL *url = [NSURL URLWithString:[[URL stringByAppendingString:GALLERY] stringByAppendingString: link]];
ASIHTTPRequest *downloadRequest = [[ASIHTTPRequest alloc] initWithURL:url];
[downloadRequest setDownloadDestinationPath:[documentsDirectory stringByAppendingPathComponent:link]];
[downloadRequest setDidFailSelector:#selector(imageDownloadFailed:)];
[downloadRequest setDidFinishSelector:#selector(imageDownloadComplete:)];
[downloadRequest setUserInfo:dict];
[downloadRequest setDelegate:self];
[networkQueue addOperation:downloadRequest];
[downloadRequest release];
NSURL *urlCarousel = [NSURL URLWithString:[[URL stringByAppendingString:WS_IMAGES] stringByAppendingString: smallLink]];
downloadRequest = [[ASIHTTPRequest alloc] initWithURL:urlCarousel];
[downloadRequest setDownloadDestinationPath:[documentsDirectory stringByAppendingPathComponent:smallLink]];
[downloadRequest setDidFailSelector:#selector(imageDownloadFailed:)];
[downloadRequest setUserInfo:dict];
[downloadRequest setDelegate:self];
[networkQueue addOperation:downloadRequest];
[downloadRequest release];
}
}
[networkQueue go];
}
Based on the comments you've left to the question, (Specifically: Also, if I change the download method from networkQueue to [downloadRequest startAsynchronous], everything works.) it may be that your request is timing out when being run synchronously.
Another thing you should know is that the "ASI network classes" are no longer being maintained. The developer offers several alternatives in his blog post announcing the end-of-life of that software.