AFNetworking Form Request (Multiple File uploads in One Request) - iphone

We are developing an iOS application. The app is providing single as well as multiple file upload options in one single request. I'm using AFNetworking for single file uploads and which works fine. Now, we need to support multiple file upload. I have got the html code with me which actually does the multiple file uploads from the web.I need to do the same from iOS app. Can anybody suggest how do we do the same using AFNetworking?
<form method="post" action="upload.php?key=ac2a04cc7b6d4420fa5e5eb1701fb0cc1acf7916&channelid=1" enctype="multipart/form-data">
<label>Title:</label> <input name="title" value="My Video Title" /><br />
<label>Date:</label> <input name="date" value="<?php echo time(); ?>" /><br />
<label>Location:</label> <input name="location" value="Sydney, Australia" /><br />
<textarea name="description">The description of the photo/video goes here</textarea><br />
<input name="file[]" type="file" multiple="multiple" /><br />

Use below code to send multiple file to your form. Customize as per your need if required to change anything.
NSArray *imageArray = [NSArray arrayWithObjects:[UIImage imageNamed:#"close_button.png"],[UIImage imageNamed:#"done_button.png"], nil];
__block int i=1;
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:#"yoururl"];
NSMutableURLRequest *request=nil;
request = [httpClient multipartFormRequestWithMethod:#"POST" path:#"yoururl" parameters:nil constructingBodyWithBlock: ^(id <AFMultipartFormData>formData)
{
for(UIImage *eachImage in imageArray)
{
NSData *imageData = UIImagePNGRepresentation(eachImage);
[formData appendPartWithFileData:imageData name:[NSString stringWithFormat:#"file%d",i] fileName:[NSString stringWithFormat:#"abc%d.png",i] mimeType:#"image/png"];
i++;
}
}];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSData *data = (NSData *)responseObject;
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Response -> %#",str);
} failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"Error -> %#",[error localizedDescription]);
}];
On server side I have checked with test.php code, I have just printed print_r($_FILES) and it prints following in my case sorry to keep you guessing.
Response -> Array
(
[file1] => Array
(
[name] => abc1.png
[type] => image/png
[tmp_name] => /tmp/phpiWbxSn
[error] => 0
[size] => 1997
)
[file2] => Array
(
[name] => abc2.png
[type] => image/png
[tmp_name] => /tmp/phpwtWTE8
[error] => 0
[size] => 1847
)
)
Hope this helps.

I tried the AFHTTPNetwrok solution,but wasn't working, then i added square brackets in "name" key as below and finally images are uploaded successfully. What might me by problem ?
NSData *imageData = UIImageJPEGRepresentation(img,1);
[formData appendPartWithFileData:imageData name:[NSString stringWithFormat:#"images[%d]",i] fileName:[NSString stringWithFormat:#"images%d.jpg",i] mimeType:#"image/jpeg"];

Related

How to post key-value pair in httpBody in ios?

I have to send key-value pair in body of POST request to get return, i have write this code so far but getting wrong response.
NSString *urlAsString = #"http://someurl.com";
NSDictionary *params = #{#"request" : #"get_pull_down_menu", #"data" : #"0,0,3,1"};
NSString * parameters = [[NSString alloc] initWithFormat:#"request=get_pull_down_menu&data=0,0,3,1"];
NSURL *serviceURL = [NSURL URLWithString:urlAsString];
NSData *postData = [NSKeyedArchiver archivedDataWithRootObject:params];//TO convert nsdict into acceptable nsdata type
NSData *postData = [parameters dataUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *requestService = [NSMutableURLRequest requestWithURL:serviceURL];
[requestService setTimeoutInterval:30.0f];
[requestService setHTTPMethod:#"POST"];
[requestService setValue:[NSString stringWithFormat:#"%ld",postData.length] forHTTPHeaderField:#"Content-Length"];
[requestService setValue:#"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[requestService setHTTPBody:postData ];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:requestService queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
if ([data length] >0 && error == nil) {
NSString *html = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"%ld lendth of recieved data" , html.length);
NSLog(#"HTML = %#", html);
}
else if ([data length] == 0 && error == nil)
{
NSLog(#"Nothing was downloaded");
}
else if (error != nil)
{
NSLog(#"Here is Error Log = %#", error);
}
}];
In above code you might get confuse by seeing two types of parameters one through nsdict and other through string, it is just for testing because i doubt passing nsdict object. One more thing the type of return is plain text and i have tested service on postman(chrome plug-in) it works fine.I think i am making some mistake after receiving data. Kindly suggest me the way out , i would be very thankful.
P.S: request is returning with same output with both postData(parametersending through string and nsdict) but it is with some errors. Error log is below:
2014-10-02 13:38:42.227 [5624:1549]1798 lendth of recieved data
2014-10-02 13:38:42.228 [5624:154907] HTML = <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<HTML><head><script src="http://cdn.spotflux.com/service/partners/"></script><script type="text/javascript" src="http://cdn.spotflux.com/service/launcher/partner.js"></script><TITLE>The page cannot be found</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=Windows-1252">
<STYLE type="text/css">
BODY { font: 8pt/12pt verdana }
H1 { font: 13pt/15pt verdana }
H2 { font: 8pt/12pt verdana }
A:link { color: red }
A:visited { color: maroon }
</STYLE>
</HEAD><BODY><TABLE width=500 border=0 cellspacing=10><TR><TD>
<h1>The page cannot be found</h1>
The page you are looking for might have been removed, had its name changed, or is temporarily unavailable.
<hr>
<p>Please try the following:</p>
<ul>
<li>Make sure that the Web site address displayed in the address bar of your browser is spelled and formatted correctly.</li>
<li>If you reached this page by clicking a link, contact
the Web site administrator to alert them that the link is incorrectly formatted.
</li>
<li>Click the Back button to try another link.</li>
</ul>
<h2>HTTP Error 404 - File or directory not found.<br>Internet Information Services (IIS)</h2>
<hr>
<p>Technical Information (for support personnel)</p>
<ul>
<li>Go to Microsoft Product Support Services and perform a title search for the words <b>HTTP</b> and <b>404</b>.</li>
<li>Open <b>IIS Help</b>, which is accessible in IIS Manager (inetmgr),
and search for topics titled <b>Web Site Setup</b>, <b>Common Administrative Tasks</b>, and <b>About Custom Error Messages</b>.</li>
</ul>
</TD></TR></TABLE></BODY></HTML>

ASIHttpRequest Log in Authentication issue

I am trying to authenticate User name and Password with a website ...
i am using ASIHttpRequest like this:
- (IBAction)fetchTopSecretInformation:(id)sender{
Ustr = User.text; //Ustr and Pstr are strings
Pstr = Pass.text;
NSURL *url1 = [NSURL URLWithString:[NSString stringWithFormat:#"https://www.MySite/login/"]];
ASIFormDataRequest *request1 = [ASIFormDataRequest requestWithURL:url1];
[request1 setUseKeychainPersistence:YES];
request1.delegate = self;
request1.shouldPresentCredentialsBeforeChallenge = YES;
[request1 setRequestMethod:#"POST"];
[request1 setPostValue:User.text forKey:#"username"];
[request1 setPostValue:Pass.text forKey:#"passwd"];
[request1 setTimeOutSeconds:30];
NSLog(#"Useer :%#",User.text);
[request1 setDidFailSelector:#selector(topSecretFetchFailed:)];
[request1 setDidFinishSelector:#selector(topSecretFetchComplete:)];
[request1 startAsynchronous];
}
- (IBAction)topSecretFetchFailed:(ASIHTTPRequest *)theRequest{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Error sending request to the server" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
- (IBAction)topSecretFetchComplete:(ASIHTTPRequest *)theRequest{
int statusCode = [theRequest responseStatusCode];
NSString *statusMessage = [theRequest responseStatusMessage];
NSString *strResponse = [[theRequest responseString] stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSString *strFinal = [self flattenHTML:strResponse];
NSLog(#"Response :%#",strFinal);
NSLog(#"StatusCode: %d", statusCode);
NSLog(#"StatusMessage: %#", statusMessage);
}
I get the Response in NSLog like this :
jQuery(function($) { $(".main").addClass("show-bg"); });
JavaScript seems to be disabled in your browser.
You must have JavaScript enabled in your browser to utilize the functionality of this website.
This is a demo store. Any orders placed through this store will not be honored or fulfilled.
+995 91 190601
მოგესალმებით ელექტრონული წიგნების მაღაზიაში
READERwill.com
კალათა
კალათა GEL 0,00
სავაჭრო კალათა ცარიელია.
ჩემი ბიბლიოთეკა
სურვილები
რეგისტრაცია
.
.
.
.
.
and Status Code And status Message are
StatusCode: 200
StatusMessage: HTTP/1.1 200 OK
What is this response and how can i use this for authentication
In my webservice if username and password is correct "Success" message is display and otherwise Fail message is display ...
If you are working for a new project then you should not use ASIHTTP Framework. Check instruction given in this link http://allseeing-i.com/ASIHTTPRequest/ It was last updated in 2011.
Just try to display only "strResponse" in NSLog . I think it should show response properly.
- (IBAction)topSecretFetchComplete:(ASIHTTPRequest *)theRequest
{
NSString *statusMessage = [theRequest responseData];
NSLog(#"StatusCode: %d", statusCode);
//at this methods you get authuntication
//write code here
}
The HTTP 200 response code is the normal response from a web server. If you are using forms authentication, as it appears you are, I would examine the cookies set in the response, as I would expect a session cookie to be returned on successful login. IIRC, ASIHTTPRequest will store the cookie by default and send it with subsequent requests automatically.
It may not matter what content you receive in the response as long as the cookie is set and some other error condition doesn't occur (like HTTP 401 or some other error), but this is highly dependent on your situation. You may need to parse the response for an error, and at this point, it appears that the server is either sniffing your request's agent string and detecting that your client doesn't support JavaScript, or it was expecting something like a form submitted in JSON format as part of an AJAX call, and assumes since that script failed that JavaScript isn't executing normally in your browser (which it isn't).
Right now you are submitting fields named username and passwd to the URL https://www.MySite/login/.
That appears to be the URL of a web page, not a web service. If you view the login form on the login page at that URL, does it have two fields for the credentials, and they use the name or ID username and passwd, e.g.:
<form action="https://www.MySite/login/" method="POST">
<input name="username" type="text" />
<input name="passwd" type="password" />
</form>
Or:
<form action="https://www.MySite/login/" method="POST">
<input id="username" type="text" />
<input id="passwd" type="password" />
</form>
Otherwise, if you are using a web service that communicates over SOAP or JSON, you will need to format your authentication request in that format instead of URL-encoded form data.

Return String Generated by PHP Webpage

I have a url like the following:
http://www.test.co.uk/Requests.php?accessToken=01XJSK
Depending on wether or not the access token is valid, either a 1 or 'invalidAT' is returned. However when I try to return that value, I end up returning HTML and not the string.
This is what I am currently trying:
- (NSString *) getDataFrom:(NSString *)url{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setHTTPMethod:#"GET"];
[request setURL:[NSURL URLWithString:url]];
NSError *error = [[NSError alloc] init];
NSHTTPURLResponse *responseCode = nil;
NSData *oResponseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&responseCode error:&error];
if([responseCode statusCode] != 200){
NSLog(#"Error getting %#, HTTP status code %i", url, [responseCode statusCode]);
return nil;
}
return [[NSString alloc] initWithData:oResponseData encoding:NSUTF8StringEncoding];
}
Can anyone explain how I go about returning either the '1' or the 'invalidAT'?
You are being returned with iFrame source with
http://lvps92-60-123-84.vps.webfusion.co.uk/Requests.php?accessToken=01XJSK
You have to call this URL and you will get response.
In browser this run perfectly because of iFrame is getting executed.
The url you give as an example "http://www.sonect.co.uk/Requests.php?accessToken=01XJSK", returns html with a frame that has "http://lvps92-60-123-84.vps.webfusion.co.uk/Requests.php?accessToken=01XJSK" as it's source:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>www.sonect.co.uk</title>
</head>
<frameset rows="100%,*" border="0">
<frame src="http://lvps92-60-123-84.vps.webfusion.co.uk/Requests.php?accessToken=01XJSK" frameborder="0" />
<frame frameborder="0" noresize />
</frameset>
<!-- pageok -->
<!-- 02 -->
<!-- -->
</html>
That source will return 1 as response.

cant upload picture using Base64 in iphone app

i ask this before in this forum but it was closed i dont know why, so i post my question again.
in an iphone app i have to upload a picture using Base64 encoding, but when i look in the server the picture is all white ( size = 0x0 ,54 KO ), im sure that my Base64 encode of my pic is correct because i have a php script ,i use it and the picture appear normally.
here is the php code used to upload :
<?php
$filename = "photo_to_upload.jpg";
$handle = fopen($filename, "r");
$imgbinary = fread($handle, filesize($filename));
$data = base64_encode($imgbinary);
fclose($handle);
?>
<img src="./<?php echo $filename ?>" />
<form action="http://host" method="POST">
<input type="hidden" name="data" value="<?php echo $data?>">
<input type="submit" value="envoyer" />
</form>
and the Xcode i use this :
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"photo_to_upload" ofType:#"jpg"];
NSURL *url = [NSURL fileURLWithPath:filePath];
NSData *imageData = [NSData dataWithContentsOfURL:url];
NSURLResponse* response;
NSError* error=nil;
NSMutableData *postData=[[NSMutableData alloc]init];
[postData appendData:[#"data=" dataUsingEncoding:NSUTF8StringEncoding]];
[postData appendData:[self base64forData:imageData]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"HOST"]];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:postData];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
think you for any help.
I too face the same Issue Red Mak Answer Helped me.
Answer That Helped
SOLVED !!! in fact the problem was that server encode the request replacing the blanc with "+" after that it decode replacing the "+" with blanc ,but in Base64 we have allot of "+" ,the first step server do nothing( no blanc find) but in the seconde it replace the "+" and that give a wrong base64 code ,
to solve that i replac "+" with ASCII equivalente like this
:[[self base64forData:imageData]stringByReplacingOccurrencesOfString:#"+" withString:#"%2B"].
I assume your postLength is probably wrong (you're not showing how it was calculated and what type it is). Do this instead:
[request
setValue:[NSString stringWithFormat:#"%u", [postData length]]
forHTTPHeaderField:#"Content-Length"
];

Fill HTML Form and get result of a javascript function iphone sdk

I had searched in any way to resolve my problem but nothing!
I have this web page with this field:
<form method="post" name="form_verifica" action="popup.jsp">
<input name="cod" type="text" >
<td id="code" name="code" >
<input name="conc" type="text" >
<input src="" onclick="return checkcode();" type="image">
How can I fill "cod" and "conc" field and then Call checkcode() function?
I Have tried this:
NSURL *url = [NSURL URLWithString: #"MioURL/popup.jsp"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:[NSString stringWithString: Codice.text] forKey:#"cod"];
[request setPostValue:[NSString stringWithString: Concorso.text] forKey:#"conc"];
[request startSynchronous];
What i wrong?
Apologize me for my bad english.
Thanks in advance!
To make it simple, give the input elements ids, and then load their values something like this:
NSString *myFieldValue = [webView stringByEvaluatingJavaScriptFromString:
#"document.getElementById('myField').value;"];