How to upload NSData Object to server with specific name? - iphone

How to upload NSData Object to server with specific name ?
NSData *imgData; // Image Data
NSString *imgName = #"myfile.png";
I want to upload data to server with specific file name.
1. Upload Data (imgData)
2. To server (my_server.com/upload.html)
3. With file name (imgName)

I am currently working on a school project where I needed to do something similar to this...
I was placing longitude and latitude values in a database.
MAKE NOTE THAT THERE MAY BE MUCH SIMPLER WAYS TO DO THIS. I AM BY NO MEANS A "PRO" AT OBJECTIVE-C PROGRAMMING
There are going to be three things you need.
a server in which you have access to.
a PHP file that will write the data to the database.
an NSURLConnection object;
I had placed the following code in one of the delegate methods for CLLocationManager.
The NSURLConnection object should look something like this:
//this is where I put the url for my PHP file
url = [[NSURL alloc] initWithString:[NSString stringWithFormat:#"http://www.example.com/folder/example.php"]];
urlRequest = [NSURLRequest requestWithURL:url];
connection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
Of course the variables: url, urlRequest, and connection are declared in the header file like this
NSURL *url;
NSURLRequest *urlRequest;
NSMutableData *filedata;
NSURLConnection *connection;

Related

GET http requests In Objective C

I have the following code in objective c that is supposed to make a GET http request to my website which in turn will submit something into my MySQL database...
NSMutableURLRequest *request =[NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://www.website.com/VideoPush/plist/urlTransfer.php"]];
[request setHTTPMethod:#"GET"];
NSString *post =[[NSString alloc] initWithFormat:#"videoID=%#",videoURL];
[request setHTTPBody:[post dataUsingEncoding:NSUTF8StringEncoding]];
Note: I'm a total beginner to http requests with Objective c so I realize I could be missing something obvious...
Now if I run the following url in my browser...
http://www.website.com/VideoPush/plist/urlTransfer.php?videoID=hhklskdjsad
Then something gets entered into the database, but not when I'm using objective c. Also what is the difference between GET and POST when you make requests like this (since the user doesn't see the url anyways)?
ALSO: Am I allowed to pass a url (still a nsstring with /'s though) as the videoURL variable above
You've tried to set the body of a GET request, which makes no sense. What you probably want is:
NSString *urlString = [NSString stringWithFormat:#"http://www.website.com/VideoPush/plist/urlTransfer.php?videoID=%#", videoURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
... the rest of your method ...
You should probably go and have a read up about what a GET and a POST is and why I said it makes no sense to have a body in a GET request.
ALSO: Am I allowed to pass a url (still a nsstring with /'s though) as the videoURL variable above
No, you will need to URL encode anything in the query string. You can use CFURLCreateStringByAddingPercentEscapes to do this for you.

download data error when using ASIHTTPRequest to set the download destination file path in requestDidReceiveResponseHeadersSelector: method

i use ASIHTTPRequest to download file to ios device
when i set the download destination file path right after the request has been created, it works well, where my code is:
A
SIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadDestinationPath:#"/Users/zxllf23/Desktop/download/tmp.zip"]];
[request setTemporaryFileDownloadPath:#"/Users/zxllf23/Desktop/download/tmp.zip.download"]];
but this is not comfortable, bcs different file on sever have different file name which we can retrive from the http respone header's Content-Disposition, so i want to auto determine file name, and i wrote my code in the requestDidReceiveResponseHeadersSelector: method
-(void) downloadReceiveRespone:(ASIHTTPRequest *)request
{
NSString *CoententDecription = [[request responseHeaders] objectForKey:#"Content-Disposition"];
NSString *filename = [self getFilenameFrom:CoententDecription];
[request setDownloadDestinationPath:[NSString stringWithFormat:#"/Users/zxllf23/Desktop/download/%#",filename]];
[request setTemporaryFileDownloadPath:[NSString stringWithFormat:#"/Users/zxllf23/Desktop/download/%#.download",filename]];
}
where i can download file successfully, but it can not be opened proper, and i compared the downloaded file data with the original file, they are not the same
can any body help me on this issue, i would be very appreciate.
Setting setDownloadDestinationPath after the request has started isn't supported, which would explain why it's not working properly.
Either move the file after the request has finished, or write the data to file yourself.

How to POST multiple requests with XML parser?

I want to POST 3 requests within same class with XML parser. I can manage to do only one request at a time. When I POST multiple requests, it says Parser Error. This is how I tried.
NSURL *url = [[NSURL alloc] initWithString:getAllFoodsURL];
NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:url];
NSString *paramDataString = [NSString stringWithString:
#"<GetNames><DeviceId>1234</DeviceId><UserId>200</UserId></GetNames>"];
[req addValue:#"application/xml" forHTTPHeaderField:#"content-type"];
[req setHTTPMethod:#"POST"];
NSData *paramData = [paramDataString dataUsingEncoding:NSUTF8StringEncoding];
[req setHTTPBody: paramData];
NSURLConnection *theConnection=[[NSURLConnection alloc]initWithRequest:req delegate:self];
if (theConnection) {
NSMutableData *data = [[NSMutableData alloc] init];
self.receivedData=data;
[data release];
}
I have used NSXMLParser delegates methods. After one request is completed(connection release), then I create another connection and do the same process for second request.
But it doesnot work.
I want to know, how to manage multiple requests with NSXMLParser?
If you can give me a code example, its highly appreciated.
I guess NSThread is what you are looking for.
But I am not sure as I am not much aware about that.
Note that NSXMLParser isn't involved in HTTP requests -- do you mean NSURLRequest instead? You'll need to make your requests separately, possibly using separate blocks, operations, or threads.
Once you've retrieved the data for each request, you'll need to use separate NSXMLParser objects for each. A single instance of NSXMLParser is tied to its XML data at initialization -- you can't reuse a parser. You can use the same delegate for all your xml parsers, and the delegate can use the first parameter to each of the xml parser delegate methods (i.e. parser) to know which parser is calling a given method.

Encoding on NSURLConnection

I need to load data from a REST service, but the result is always (null) when I have any accentuation. I know this is an encoding problem but NSUrlConnection gives me no solution. The best result I got is to have all my text with strange codes in the place of the accentuated characters.
I already tried to use NSUrl like the following code and it works, but I need to set two headers for this connection.
NSURL *nsurl = [[NSURL alloc] initWithString:url];
NSString *data = [[NSString alloc] initWithContentsOfURL:nsurl encoding: NSUTF8StringEncoding error: nil];
Well I could have two solutions for this taks, adding headers do NSUrl connection or manage to make the encoding to work in NSURLConnection.
Does anyone have a solution?
You can add header fields for your request in an NSMutableURLRequest instance with setValue:forHTTPHeaderField:

How to keep a connection alive using ASIHTTP? I need to make multiple requests, but can't afford to open, then close a request connection

I have a method that I call to make web service requests using GET. It looks like this:
- (UIImage*)getImageWithSeriesGUID:(NSString*)seriesGUID ImageID:(int)imageID {
NSString * unescapedString = RIVERWOODS_GET_IMAGE(seriesGUID, imageID);
NSURL *url = [[NSURL alloc] initWithString:[unescapedString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setRequestMethod:#"GET"];
[request addRequestHeader:#"Connection" value:#"Keep-Alive"];
[request startSynchronous];
NSError *error = [request error];
if (!error) {
NSData *response = [request responseData];
//NSLog(#"Size: %#",[response length]);
NSString *content = [[[NSString alloc] initWithData:response
encoding:NSUTF8StringEncoding] autorelease];
NSLog(#"Data: %#", content);
UIImage *image = [UIImage imageWithData:response];
return image;
}
return nil;
}
This approach works ok, but it is just REALLY slowly. On the other end I am iterating through a for loop so this method gets called 20 times if the picture array I need to collect has 20 images. I am looking to improve the efficiency of this process, and I am thinking that I should be able to iterate through all the image Id's I need to collect right here in this method.
It seems to me that the reason this goes so slowly is because the multiple requests that we keep opening and closing. THe images I am pulling in are on average ~15kb.
My question: What can I do to change this method around to make it so I can improve efficiency and take advantage of the HTTP keep-alive features? I am thinking that instead of passing in an image ID, I can just pass in the count of the array I need to make, and then setup a for-loop of some sorts here in the request method which would then allow me to pass back an array of images...
Is that the way to go? Is there something I am missing? I appreciate your help and input!!
The reason why this is slow as hell is that you're doing the requests synchronously (which is always a no-no anyway), one-by-one. You need to refactor your download method to work asynchronously, and concurrently.
My approach to requesting data on the wire in that manner is as follows:
Create a global network connection 'controller' (accessible from your App Delegate), which can create an ASINetworkQueue on the fly when required and release it when no requests remain
Wrap your requests into a subclass of ASIHTTPRequest, and override the done/fail methods in those subclasses (make them fire a notification with returned data if you like; or write to disk and update a db with their reference).
For every request, grab the queue reference, and add your request to the queue.
The queue will grow and shrink as needed
If I were at my computer I'd check into github an example of this, but really the only difficult part is the global connection manager, and the ASI* guys have written a great example here on gist.github. Also, a better explanation of the above (where I learnt it from) is here.