Preparing a GET/POST request to fetch data on iPhone - iphone

i am trying to fetch data in JSON format for the search word 'cancer'.
But i can't figure out how to call the websvice, i tried a few things but they are not working, can anybody help me in this.
Below is the API i should be calling
https://api.justgiving.com/docs/resources/v1/Search/FundraiserSearch
Clicking the following URL will get desired data in the browser.
https://api.justgiving.com/2be58f97/v1/fundraising/search?q=cancer
apiKey = 2be58f97
Here is the code i am using:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
NSURL *requestURL = [NSURL URLWithString:#"https://api.justgiving.com/2be58f97/v1/fundraising/search"];
[request setURL:requestURL];
[request setHTTPMethod:#"GET"];
NSString *boundary = #"---------------------------14737809831466499882746641449";
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[request addValue:contentType forHTTPHeaderField: #"Content-Type"];
NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Disposition: form-data; name=\"q\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"%#",searchText] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSLog(#"ERROR = %#",error.localizedDescription);
if(error.localizedDescription == NULL)
{
NSString *returnString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"response >>>>>>>>> %#",returnString);
}
else
{
NSString *returnString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"response >>>>>>>>> %#",returnString);
}
}];

-(AFHTTPClient *) getHttpClient{
AFHTTPClient *httpClient = [[AFHTTPClient alloc]initWithBaseURL:[NSURL URLWithString:kBASEURL]];
httpClient.parameterEncoding = AFJSONParameterEncoding;
[httpClient setDefaultHeader:#"Accept" value:#"application/json"];
[httpClient registerHTTPOperationClass:[AFJSONRequestOperation class]];
return httpClient;
}
//This is how you should call
-(void) callAPI{
AFHTTPClient *httpClient = [self getHttpClient];
NSMutableURLRequest *request = [httpClient requestWithMethod:#"GET" path:method parameters:queryStrDictionary];// querystringDictionary contains value of all q=? stuff
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
//You have Response here do anything you want.
[self processResponseWith:JSON having:successBlock andFailuerBlock:failureBlock];
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
//Your request failed check the error for detail
failureBlock(error);
}];
NSOperationQueue *queue = [[NSOperationQueue alloc] init] ;
[queue addOperation:operation];
}

In your code you setup a multipart/form-data request. While the achievement is creditable, it's not how you talk to the API of the given web service.
In fact, it's simpler:
As you can retrieve from the documentation from that site, "query parameters" go into the URL as a query string: "q=cancer". Then, just specify the Content-Type header as "application/json" - and it should work.
In general, URL query parameters will be prepended to a URL by appending a '?', followed by "non-hierarchical data" comprising the query string and then followed by an optional '#'.
What "non-hierarchical data" means is not exactly specified, but in almost all cases web services require a query string as a list of key/value pairs, whose key and value is separated by a '=', and the pairs are separated by a '&':
param1=value1&param2=value2
Furthermore, in order to disambiguate the query string, say when a value or key itself contains "special characters", like spaces, non-ASCII characters, an ampersand or a equal sign, etc., the query string must be properly "URL encoded" before appended to the url and send to the server.
The details of constructing a URL can be found consulting the corresponding RFC. However, wiki provides a comprehensible definition of the query string in a much more concise form:
http://en.wikipedia.org/wiki/Query_string
For further information how to "URL encode" a query string utilizing a handy method or function please read the NSString documentation, stringByAddingPercentEscapesUsingEncoding: https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html
and Core Foundation: CFURLCreateStringByAddingPercentEscapes: https://developer.apple.com/library/mac/#documentation/CoreFOundation/Reference/CFURLRef/Reference/reference.html
A third party library may make this more convenient, nonetheless you should understand what that API means and how you would have to construct a URL, the HTTP headers and the query string yourself.

Related

HTTP Post Request from iOS to Django URL

Essentially this seems to be working however on the server side of things, the Query Dict looks something like this.
POST: QueryDict: {u'Contestant1 John Doe Contestant2 Jane Doe ': [u'']}
which is storing all my values as keys with no values in the Dictionary. Clearly this is a rookie mistake which I'm guessing is on the iOS side of things, so any help would be appreciated. The code is as follows:
NSString *queryString = [NSString stringWithFormat:#"URL HERE"];
NSMutableURLRequest *theRequest=[NSMutableURLRequest
requestWithURL:[NSURL URLWithString:
queryString]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
[theRequest setHTTPMethod:#"POST"];
NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:#"Contestant1 %# ",contestant1] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Contestant2 %# ",contestant2] dataUsingEncoding:NSUTF8StringEncoding]];
[theRequest setHTTPBody:body];
NSURLConnection *con = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (con) {
NSLog(#"success!");
} else {
//something bad happened
}
EDIT: The solution to my problem.
NSDictionary *postDict = [NSDictionary dictionaryWithObjectsAndKeys:contestant1, #"contestant1",
contestant2, #"contestant2", nil];
NSError *error=nil;
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:postDict
options:NSJSONWritingPrettyPrinted error:&error];
[theRequest setHTTPBody:jsonData];

how to post an image to the web server

I am working with web services using json parsing. I am able to get images from the web services, can someone help me how to post an image? How i can post an image to the web services?
it will be something along the lines of this...
NSMutableURLRequest *mutableRequest = [[NSMutableURLRequest alloc] initWithURL:#"you url"];
[mutableRequest addValue:#"image/jpeg" forHTTPHeaderField: #"Content-Type"];
NSMutableData *body = [NSMutableData data];
[body appendData:[NSData dataWithData:UIImageJPEGRepresentation(self.image, 0.9)]];
[mutableRequest setHTTPBody:body];
NSURLResponse *response;
NSError *error;
(void) [NSURLConnection sendSynchronousRequest:mutableRequest returningResponse:&response error:&error];
Thanks
Find here serverside (PHP) coding for image Upload with random name. also it will give the image link as response.
//Create a folder named images in your server where you want to upload the image.
// And Create a PHP file and use below code .
<?php
$uploaddir = 'images/';
$ran = rand () ;
$file = basename($_FILES['userfile']['name']);
$uploadfile = $uploaddir .$ran.$file;
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
echo "www.host.com/.../images/{$uploadfile}";
}
?>
And Here is iOS code
- (IBAction)uploadClicked:(id)sender
{
/*
turning the image into a NSData object
getting the image back out of the UIImageView
setting the quality to 90
*/
NSData *imageData = UIImageJPEGRepresentation(imageView.image, 90);
// setting up the URL to post to
NSString *urlString = #"your URL link";
// setting up the request object now
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
/*
add some header info now
we always need a boundary when we post a file
also we need to set the content type
You might want to generate a random boundary.. this is just the same
as my output from wireshark on a valid html post
*/
NSString *boundary = [NSString stringWithString:#"---------------------------14737809831466499882746641449"];
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[request addValue:contentType forHTTPHeaderField: #"Content-Type"];
/*
now lets create the body of the post
*/
NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:#"rn--%#rn",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Disposition: form-data; name="userfile"; filename="ipodfile.jpg"rn"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Type: application/octet-streamrnrn"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:imageData]];
[body appendData:[[NSString stringWithFormat:#"rn--%#--rn",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
// setting the body of the post to the reqeust
[request setHTTPBody:body];
// now lets make the connection to the web
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(returnString);
}
Check below good tutorial.In that tutorial you able to find the ios side code as well server side php code too.
http://zcentric.com/2008/08/29/post-a-uiimage-to-the-web/
The best way to use ASIHttpFormData Click here to know how to use

Issue with uploading a video file using HTTP Post from iPhone app to server:

I am trying to upload a .3gp video file into my server using HTTP post method from my iPhone app to my server. 3gp video file is available in my project resource. I use the following code for that,
-(IBAction)buttonAction
{
NSMutableURLRequest* post = [NSMutableURLRequest requestWithURL: [NSURL URLWithString: #"http://115.111.27.206:8081/vblo/upload.jsp"]];
[post setHTTPMethod: #"POST"];
NSString *boundary = [NSString stringWithString:#"---------------------------358734318367435438734347"];
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[post addValue:contentType forHTTPHeaderField: #"Content-Type"];
body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Disposition: form-data; name=\"videofile\"; filename=\"video.3gp\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[[NSBundle mainBundle] pathForResource:#"video" ofType:#"3gp"]
dataUsingEncoding: NSASCIIStringEncoding]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[post setHTTPBody:body];
NSData *returnData = [NSURLConnection sendSynchronousRequest:post returningResponse:nil error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
// Just to show the response received from server in an alert...
UIAlertView *statusAlert = [[UIAlertView alloc]initWithTitle:nil message:(NSString *)returnString delegate:self cancelButtonTitle:#"cancel" otherButtonTitles:#"ok", nil];
[statusAlert show];
}
This code doesn't do anything.
Could someone guide me what's wrong?
UPDATED:
I saw an example from the link -> iphone.zcentric.com/page/2 there are using "iphone.zcentric.com/test-upload.php"; PHP to upload and in my code i use JSP "115.111.27.206:8081/vblo/upload.jsp"; to upload to my server. Is this anything wrong here?
Thanks.
I suggest the following sample code. The multipart is not required if you send one single body - in this case the video. I would recommend binary encoding instead of any other character encoding for speed and preserve binary data integrity.
NSMutableURLRequest* post = [NSMutableURLRequest requestWithURL: [NSURL URLWithString: #"http://115.111.27.206:8081/vblo/upload.jsp"]];
[post setHTTPMethod: #"POST"];
[post addValue:#"video/3gpp" forHTTPHeaderField:#"Content-Type"];
body = [[NSData alloc] initWithContentOfFile:[[NSBundle mainBundle] pathForResource:#"video" ofType:#"3gp"]];
[post setHTTPBody:body];
NSData *returnData = [NSURLConnection sendSynchronousRequest:post returningResponse:nil error:nil];
[post release];
Good luck!
As it looks like you are faking being a form I would recommend using ASIFormDataRequest
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request addData:videoData withFileName:#"videofile.3gp" andContentType:#"video/3gpp" forKey:#"video"];
Maybe you should have a look at the response and - maybe - the Error:
NSError *error;
NSURLResponse *response;
NSData *returnData = [NSURLConnection sendSynchronousRequest:post
returningResponse:response error:error];
if (returnData==nil) {
/* Edit this or set Breakpoint */
NSLog(#"Ups... Response: %# Error: %#",response,error);
}

UIImage uploading using NSMutable request

I need to POST a request. The request has 3 parameters, 'email_id' , 'location' and 'image_data'. The value for 'image_data' contains NSData jpeg representation of a UIImage. The request must be submitted using a content type of multipart/form-data. How can I create the NSMutableRequest for posting this request? How should I set the boundary? Is the boundary required for the entire packet or is it enough only for the image part?
This link:
http://iphone.zcentric.com/2008/08/29/post-a-uiimage-to-the-web/
Should contain all you need. U'll need to extend the PHP-script to handle your non-image parameters but this is what I used. :)
Edit: Noticed the previous link was broken. The new one works
If I were you, I'd check out the ASIHTTPRequest library. It's an HTTP client library for Cocoa that makes life EVER so much easier for people who do a lot of web interactions from their iPhone apps.
Here's me, using ASIFormDataRequest (a component of ASIHTTPRequest) to upload an image from my iPhone app. The client's term for these images is "marks"--they're going on a map of local pictures taken by users all around the local area. Users are invited to "make your mark". You can imagine the hilarity that ensues.
Anyhoo, self.mark is an instance of my Mark class that encapsulates the data about an image-and-details package I'm uploading. I have a data manager singleton I use in the first line of this method, which contains the current CLLocation, so I can get geocode info for this picture.
Notice I don't concern myself with encoding types or multipart boundaries. The library handles all that.
-(void)completeUpload
{
CLLocation *currentLoc = [DataManager sharedDataManager].currentLocation;
self.mark.latitude = [NSNumber numberWithDouble:currentLoc.coordinate.latitude];
self.mark.longitude = [NSNumber numberWithDouble:currentLoc.coordinate.longitude];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:
[NSURL URLWithString:[NSString stringWithFormat:#"%#image_upload.php", WEBAPPURL]]];
[request setPostValue:self.mark.titleText forKey:#"title"];
[request setPostValue:self.mark.descriptionText forKey:#"description"];
[request setPostValue:self.mark.event.guid forKey:#"event"];
[request setPostValue:self.mark.latitude forKey:#"latitude"];
[request setPostValue:self.mark.longitude forKey:#"longitude"];
[request setPostValue:self.mark.project forKey:#"project"];
[request setPostValue:[[NSUserDefaults standardUserDefaults] valueForKey:#"userID"] forKey:#"user_id"];
request.timeOutSeconds = 120;
int i = 1;
for (NSString *tag in self.tags) {
[request setPostValue:tag forKey:[NSString stringWithFormat:#"tag-%d", i]];
i++;
}
NSData *imageData = UIImagePNGRepresentation(self.mark.image);
NSData *thumbData = UIImagePNGRepresentation(self.mark.thumbnail);
[request setData:imageData forKey:#"file"];
[request setData:thumbData forKey:#"thumb"];
self.progress.progress = 20.0;
[request setUploadProgressDelegate:self.progress];
request.showAccurateProgress = YES;
request.delegate = self;
[request startAsynchronous];
}
EDIT: By the way, the PHP script I'm posting to is behind HTTP authentication. ASI caches those credentials, and I provided them earlier, so I don't have to provide them again here. I note that because otherwise, the way this post and the corresponding PHP script is written, anybody could fake anybody else's user ID value and post whatever under their username. You have to think about web-application security when you build an app like this, no different than if it was a web site. It IS a web site, actually, just browsed through a non-traditional client.
NSData *imageData=UIImageJPEGRepresentation(imageview.image, 1.0);
NSString *filename=#"nike.jpg"
NSString *urlString = #"http://xyz.com/file_upload/file1.php";
NSMutableURLRequest *request =[[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
NSString *boundary = [NSString stringWithString:#"-----------------99882746641449"];
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[request addValue:contentType forHTTPHeaderField: #"Content-Type"];
NSMutableData *body = [NSMutableData data];
NSMutableString * string = [[NSMutableString alloc] init];
[string appendFormat:#"\r\n\r\n--%#\r\n", boundary];
[string appendFormat:#"Content-Disposition: form-data; name=\"emailid\"\r\n\r\n"];
[string appendFormat:#"pradz39#gmail.com"]; //value
[body appendData:[string dataUsingEncoding:NSUTF8StringEncoding]]; // encrypt the entire body
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"userfile\"; filename=\"%#\"\r\n",filename]] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:imageData]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[string release];
[request setHTTPBody:body];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];

HTTP POST to Imageshack

I am currently uploading images to my server via HTTP POST. Everything works fine using the code below.
NSString *UDID = md5([UIDevice currentDevice].uniqueIdentifier);
NSString *filename = [NSString stringWithFormat:#"%#-%#", UDID, [NSDate date]];
NSString *urlString = #"http://taptation.com/stationary_data/index.php";
request= [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
NSString *boundary = #"---------------------------14737809831466499882746641449";
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[request addValue:contentType forHTTPHeaderField: #"Content-Type"];
NSMutableData *postbody = [NSMutableData data];
[postbody appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"userfile\"; filename=\"%#.jpg\"\r\n", filename] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[[NSString stringWithString:#"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[NSData dataWithData:imageData]];
[postbody appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:postbody];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(returnString);
However, when I try to convert this to work with Image Shacks XML API, it doesn't return anything. The directions from ImageShack are below.
Send the following variables via POST to imageshack. us /index.php
fileupload; (the image)
xml = "yes"; (specifies the return of XML)
cookie; (registration code, optional)
Does anyone know where I should go from here?
You might want to consider using ASIHTTPRequest, as it will build a form data post body for you with a lot less hassle, and can stream the request body from disk, so you'll save memory when uploading large images.
A quick google found this, which seems to suggest you should be posting to /upload_api.php rather than /index.php.
Something like this would probably be a good start:
ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithUrl:[NSURL URLWithString:#"http://www.imageshack.us/upload_api.php"]] autorelease];
[request setFile:#"/path/to/file" forKey:#"fileupload"];
[request setPostValue:#"yes" forKey:#"xml"];
[request setPostValue:#"blahblah" forKey:#"cookie"];
//It looks as though you probably need these too
[request setPostValue:#"me#somewhere.com" forKey:#"email"];
[request setPostValue:#"blah" forKey:#"key"];
[request start];
if ([request error]) {
NSLog(#"%#",[request error]);
} else {
    NSLog([request responseString]); // The xml that got sent back
}
Warning: untested!
I've used a synchronous request because you did, but you almost certainly should be using an asynchronous request instead (a queue with ASIHTTPRequest).
Took me a while, but you need to use ASIHTTPREQUEST!
- (void)uploadToImageShack {
NSAutoreleasePool *paul = [[NSAutoreleasePool alloc] init];
UIImage *tempImage = self.selectedimage;
ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithURL:[NSURL URLWithString:#"http://www.imageshack.us/upload_api.php"]] autorelease];
NSData *imageData = UIImagePNGRepresentation(tempImage);
[request setFile:imageData withFileName:#"image" andContentType:#"image/png" forKey:#"fileupload"];
[request setPostValue:#"yes" forKey:#"xml"];
[request setPostValue:#"3ZQ7C09K708fce677d9cadee04811cfcbdf63361" forKey:#"key"];
[request setUseCookiePersistence:NO];
[request startSynchronous];
NSError *error = [request error];
if (error) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:[error localizedDescription] delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[alert show];
[alert release];
}
else if (!error) {
if ([request responseString]) {
parser = [[NSXMLParser alloc] initWithData:[[NSData alloc] initWithData:[request responseData]]];
[parser setDelegate:self];
[parser parse];
}
}
[paul drain];
}