I am trying to upload a kml file to Google Sites. The api is here- http://code.google.com/apis/sites/docs/1.0/developers_guide_protocol.html#UploadingFiles and they give this example-
POST /feeds/content/domainName/siteName HTTP/1.1
Host: sites.google.com
GData-Version: 1.4
Authorization: <your authorization header here>
Content-Length: 7221984
Content-Type: multipart/related; boundary=END_OF_PART
--END_OF_PART
Content-Type: application/atom+xml
<entry xmlns="http://www.w3.org/2005/Atom">
<category scheme="http://schemas.google.com/g/2005#kind"
term="http://schemas.google.com/sites/2008#attachment" label="attachment"/>
<link rel="http://schemas.google.com/sites/2008#parent" type="application/atom+xml"
href="https://sites.google.com/feeds/content/domainName/siteName/PARENT_ENTRY_ID"/>
<title>PDF File</title>
<summary>HR packet</summary>
</entry>
--END_OF_PART
Content-Type: application/pdf
... pdf contents here ...
--END_OF_PART--
I am trying to use NSMutableURLRequest to perform this post. Here is my code-
NSString *boundary=#"END_OF_PART";
NSMutableString *bodyString = [[NSMutableString alloc]initWithCapacity:50];
[bodyString appendFormat:#"--%#\n",boundary];
[bodyString appendString:#"Content-Type: application/atom+xml\n"];
[bodyString appendString:#"<entry xmlns=\"http://www.w3.org/2005/Atom\">\n"];
[bodyString appendString:#"<category scheme=\"http://schemas.google.com/g/2005#kind\"\n"];
[bodyString appendString:#"term=\"http://schemas.google.com/sites/2008#attachment\" label=\"attachment\"/>\n"];
[bodyString appendString:#"<link rel=\"http://schemas.google.com/sites/2008#parent\" type=\"application/atom+xml\"\n"];
[bodyString appendString:#"href=\"https://sites.google.com/feeds/content/itourlocal/kmlfiles\"/>\n"];
[bodyString appendFormat:#"<title>%#.kml</title>\n",theNewTour.tourName];
[bodyString appendString:#"</entry>\n"];
[bodyString appendFormat:#"--%#\n",boundary];
[bodyString appendString:#"Content-Type: application/kml\n"];
NSString *kmlString=[KMLExporter kmlForPoints:self.theNewTour.locations andRoutes:polylines];
[bodyString appendFormat:#"%#\n",kmlString];
[bodyString appendFormat:#"--%#--",boundary];
NSData *postData = [bodyString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength=[NSString stringWithFormat:#"%d",[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:#"https://sites.google.com/feeds/content/itourlocal/kmlfiles"]];
[request setHTTPMethod:#"POST"];
[request addValue:#"multipart/related; boundary=\"END_OF_PART\"" forHTTPHeaderField: #"Content-Type"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"sites.google.com" forHTTPHeaderField:#"Host"];
[request setValue:#"1.4" forHTTPHeaderField:#"GData-Version"];
[request setValue:[NSString stringWithFormat:#"GoogleLogin auth=%#",authString] forHTTPHeaderField:#"Authorization"];
NSLog(#"%#",authString);
[request setHTTPBody:postData];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request];
Here is the entire text of the body string before it is converted into data-
--END_OF_PART
Content-Type: application/atom+xml
<entry xmlns="http://www.w3.org/2005/Atom">
<category scheme="http://schemas.google.com/g/2005#kind"
term="http://schemas.google.com/sites/2008#attachment" label="attachment"/>
<link rel="http://schemas.google.com/sites/2008#parent" type="application/atom+xml"
href="https://sites.google.com/feeds/content/itourlocal/kmlfiles"/>
<title>bar test.kml</title>
</entry>
--END_OF_PART
Content-Type: application/kml
<kml> <Document> <Placemark> <name>Mezzanine</name> <address>444 Jessie Street, San Francisco</address> <description>(null)</description> <Point> <coordinates>-122.408028,37.782402,0</coordinates> </Point> </Placemark><Placemark> <name>1015 Folsom</name> <address>1015 Folsom Street, San Francisco</address> <description>(null)</description> <Point> <coordinates>-122.405678,37.778072,0</coordinates> </Point> </Placemark><Style id='roadStyle'> <LineStyle> <color>7fcf0064</color> <width>6</width> </LineStyle></Style><Placemark> <styleURL>#roadStyle</styleURL> <LineString> <coordinates>-122.407997,37.782379 -122.409248,37.781399 -122.409248,37.781399 -122.408707,37.780979 -122.408157,37.780540 -122.407700,37.780170 -122.407158,37.779739 -122.406631,37.779308 -122.406158,37.778938 -122.405617,37.778500 -122.405617,37.778500 -122.406036,37.778172 -122.406036,37.778172 -122.405800,37.777981 </coordinates> </LineString> </Placemark></Document> </kml>
--END_OF_PART--
This request returns "Multipart must have Atom and media part"
I have tried many different variation but keep getting errors. Any suggestions for getting this right? thanks.
figured it out-
I needed to add a second line break after the content-type line. not sure why, but it works now.
Related
I have been trying out for a while using Box 2.0 API to upload a file from Objective C client to my Box folder. I've read a few posts from:
how to send form data in a programmatic file upload in box api 2.0
API 2.0 how to upload file with POSTMAN?
I've tried successfully using the Curl, as mentioned in the documentation, but always get a 404 when trying to create a NSMutableUrlRequest.
This is my code:
NSURL *URL = [NSURL URLWithString:#"https://api.box.com/2.0/files/content"];
urlRequest = [[NSMutableURLRequest alloc]
initWithURL:URL cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:30];
[urlRequest setHTTPMethod:#"POST"];
AppDelegate *appDelegate = [AppDelegate sharedDelegate];
NSString *p = [NSString stringWithFormat:#"BoxAuth api_key=%#&auth_token=%#",API_KEY,appDelegate.boxAuthToken];
[urlRequest setValue:p forHTTPHeaderField:#"Authorization"];
[urlRequest setValue:#"multipart/form-data, boundary=AaB03x" forHTTPHeaderField:#"Content-Type"];
NSString *postBody = #"--AaB03x"
#"content-disposition: form-data; name=\"filename\"; filename=\"test.txt\";"
#"folder_id=466838434"
#"Content-type: text/plain"
#""
#"testing box api 2.0"
#""
#"--AaB03x--";
NSData *data = [postBody dataUsingEncoding:NSUTF8StringEncoding];
[urlRequest setHTTPBody:data];
[urlRequest setValue:[NSString stringWithFormat:#"%d",[data length]] forHTTPHeaderField:#"Content-Length"];
There are a couple of problems that I see with the way you're constructing the postBody. Having newlines between string literals in your code simply concatenates them. You actually need to have carriage return and line feed to separate different parts of your HTTP body. Also, you mashed both of your form elements in one. The file and folder_id are two separate form elements. You could try something like this:
NSString *postBody = #"\r\n--AaB03x\r\n"
"Content-Disposition: form-data; filename=\"test.txt\"\r\n"
"Content-Type: text/plain\r\n\r\n"
"testing box api 2.0"
"\r\n--AaB03x\r\n"
"Content-Disposition: form-data; name=\"folder_id\";\r\n\r\n"
"0"
"\r\n--AaB03x--\r\n\r\n";
I think that should work provided everything else is set up properly.
Use http://allseeing-i.com/ASIHTTPRequest/
It makes dealing with multipart forms much easier!
I want to upload (POST) image to server with setkey "FileData" like before (wrote with ASIHTTPRequest and it works)
[self.request setData:imageData withFileName:dateFormatted andContentType:#"image/jpeg" forKey:#"Filedata"];
with AFNetworking I set like below:
NSMutableURLRequest *afRequest = [httpClient multipartFormRequestWithMethod:#"POST" path:#"" parameters:paramsDic constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
[formData appendPartWithFileData:imageData name:#"Filedata" fileName:dateFormatted mimeType:#"image/jpeg"];
}];
seems name not actually works...
How should I set the key? #mattt
Thanks
I figure it out, the problem is I add this line
[afRequest setValue:#"application/x-www-form-urlencoded; charset=UTF8" forHTTPHeaderField:#"Content-Type"];
But I still don't know why, I add this line to other http request and it works, but file upload. I checked server, when do file upload with this line, server received many ... hm... come to think how to describe it, mass letters ...like below:
Content-Type: image/jpeg^M ^M
ÿØÿà^#^PJFIF^#^A^A^#^#^A^#^A^#^#ÿá^#XExif^#^#MM^#*^#^#^#^H^#^B^A^R^#^C^#^#^#^A^#^A^#^#<87>i^#^D^#^#^#^A^#^#^#
hi i am uploading audio/image file as below please check it and its working fine using the ASIHTTPRequest.
NSURL *audiourl = [NSURL URLWithString:#"Your Url"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:audiourl];
NSData *postData = [NSData dataWithContentsOfURL:SoundPath];
//SoundPath is your audio url path of NSDocumentDirectory.
[request addData:postData withFileName:#"mynewfile.png" andContentType:#"image/png" forKey:#"FileData"];
[request setDelegate:self];
[request startasynchronous];
Thanks
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"
];
I am trying to upload the document using Google API through my iPhone App. Here is the code which I am using:
NSString *authorizationHeader = [NSString stringWithFormat:#"GoogleLogin auth=\"%#\"" ,[another objectAtIndex:1]];
NSURL *url2 = [NSURL URLWithString:#"docs.google.com/feeds/documents/private/full"];
NSMutableURLRequest *urlRequest2 = [[NSMutableURLRequest alloc]initWithURL:url2];
[urlRequest2 setHTTPMethod:#"POST"];
[urlRequest2 setValue:#"2.0" forHTTPHeaderField:#"GData-Version"];
[urlRequest2 setValue:authorizationHeader forHTTPHeaderField:#"Authorization"];
[urlRequest2 setValue:Length forHTTPHeaderField:#"Content-Length"];
[urlRequest2 setValue:#"text/html" forHTTPHeaderField:#"Content-Type"];
[urlRequest2 setValue:slugStr forHTTPHeaderField:#"Slug"];
[urlRequest2 setHTTPBody:audioData];
Where authorizationHeader contains my GoogleLogin auth=theToken
By running this code I get the following response from the server
<HTML>
<HEAD> <TITLE>Token invalid</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Token invalid</H1>
<H2>Error 401</H2>
</BODY>
</HTML>
I don't know where I am making the mistake. Is there an error in my header or am I passing the wrong parameters?
Shouldn't the url in the is prefixed with http:// when creating the NSURL?
NSURL *url2 = [NSURL URLWithString:#"http://docs.google.com/feeds/documents/private/full"];
Before I start: I'm programming for Iphone, using objective C.
I have already implemented a call to a web service function using NSURLRequest and NSURLConnection and SOAP. The function then returns a XML with the info I need.
The code is as follows:
NSString *soapMessage = [NSString stringWithFormat:
#"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
"<soap:Body>\n"
"<function xmlns=\"http://tempuri.org/\" />\n"
"</soap:Body>\n"
"</soap:Envelope>\n"];
NSURL *url = [NSURL URLWithString:#"http://myHost.com/myWebService/service.asmx"]; //the url to the WSDL
NsMutableURLRequest theRequest = [[NSMutableURLRequest alloc] initWithURL:url];
NSString *msgLength = [NSString stringWithFormat:#"%d",[soapMessage length]];
[theRequest addValue:#"text/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[theRequest addValue:msgLength forHTTPHeaderField:#"Content-Lenght"];
[theRequest setHTTPMethod:#"POST"];
[theRequest addValue:#"myhost.com" forHTTPHeaderField:#"Host"];
[theRequest addValue:#"http://tempuri.org/function" forHTTPHeaderField:#"SOAPAction"];
[theRequest setHTTPBody:[soapMessage dataUsingEncoding:NSUTF8StringEncoding]];
theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
I basically copy and modified the soap request the web service gave as an example.
i also implemented the methods
didRecieveResponse
didRecieveAuthenticationChallenge
didRecievedData
didFailWithError
connectionDidFinishLoading.
And it works perfectly.
Now I need to send 2 parameters to the function: "location" and "module".
I tried modifying the soapMessage like this:
NSString *soapMessage = [NSString stringWithFormat:
#"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
"<soap:Body xmlns=\"http://tempuri.org/\" />\n"
"<m:GetMonitorList>\n"
"<m:location>USA</m:location>\n"
"<m:module>DEVELOPMENT</m:module>\n"
"</m:GetMonitorList>\n"
"</soap:Body>\n"
"</soap:Envelope>\n"];
But is not working...any thoughts how should I modify it?
Extra info:
it seems to be working... kind of.
But the webservice return nothing.
During the connection, the method
didReceiveResponse execute once and
the didFinishLoading method executes
as well. But not even once the method
didReceiveData.
I wonder if, even though there is no
USA locations, it will still send at
least something?
is there a way to know which are the
parameters the function is waiting
for?
I don't have access to the source of the webservice but i can access the WSDL.
You are probably passing the service a message that is not valid. You should have a look at the WSDL; there should be one or more schemas or schema documents listed inside it. Those will tell you how you can construct the body of the SOAP message.
I was experiencing your problem before when i develop the code as similar you given.Check your again WSDL file and you need to request a single SOAP message in the single class otherwise your methods(given in first part) of your question will be clash.
Please go to the following link, I hope, it will help you...
1) kosmaczewski.net
2) http://icodeblog.com/2008/11/03/iphone-programming-tutorial-intro-to-soap-web-services/
3) http://viium.com