ASIHTTPRequest Send Data With Each Request - iphone

I have an array which includes URLs of JSON feeds. I am using ASIHTTPRequest to download the feed and process it. Each feed contains several JSON entries or objects. The request downloads the data and selects only one object and stores it.
The feeds URLs look like this: http:www.*.com/id.json, where id is some string. After downloading the data and selecting the object, I'd like to store the id in a dictionary as a key that maps to a value of the object downloaded.
How can I pass that string with the request? So for example:
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
request.tag = 3;
[request setDelegate:self];
[request startAsynchronous];
Now in requestFinished, I can identify that request as follows: if (request.tag == 3. Along with tag of 3, I'd like to send the ID. So I can do something with it in if (request.tag == 3). Is there some property where I can pass a string or any data along with a request?

You can pass your own dictionary of data in the userInfo property, which, like the tag property, can be read back on the request after receiving the response.
NSString* jsonId = #"1234";
request.userInfo = [NSDictionary dictionaryWithObject:jsonId forKey:#"id"];
See documentation.
If you need to handle success and failure on many different types of
request, you have several options:
If your requests are all of the same broad type, but you want to
distinguish between them, you can set the userInfo NSDictionary
property of each request with your own custom data that you can read
in your finished / failed delegate methods. For simpler cases, you can
set the request’s tag property instead. Both of these properties are
for your own use, and are not sent to the server.
If you need to handle success and failure in a completely
different way for each request, set a different setDidFinishSelector /
setDidFailSelector for each request
If you want to post data like a web page posts a form, you can use the ASIFormDataRequest subclass. It makes it very easy to send POST requests with strings you add individually:
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:#"Ben" forKey:#"first_name"];
[request setPostValue:#"Copsey" forKey:#"last_name"];
See the documentation.

Related

what is the difference between GET and POST method in rest API IOS?

i have use this code but i don't know why we use POST and why we use GET in rest API?
-(IBAction)ClickSignUP:(id)sender
{
NSString *urlLoc = #"YOUR URL";
NSLog(#"%#",urlLoc);
NSString * requestString = [NSString stringWithFormat:#"Name=%#&Email=%#&Password=%#&MobileNumber=%#&BloodGroup=%#&DeviceID=%#&City=%#&DeviceType=I",txtName.text,txtEmail.text,txtPassword.text,txtMobileno.text,strBlood,strDeviceID,txtCity.text];
NSData *postData = [requestString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu",(unsigned long)[postData length]];
request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlLoc]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
PostConnectionSignUp = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
how we can integrate kingfisher image loading in swift 3.0
pod 'Kingfisher', '~> 4.6.1.0'
import Kingfisher
imgVUser.kf.setImage(with: URL(string: data.propertyImage), placeholder: UIImage.init(named: "placeholder"), options: [.transition(.fade(1))], progressBlock: nil, completionHandler: nil)
how we can integrate KRProgress Indicator in swift 3.0
pod 'KRProgressHUD', '~> 3.1.1.0'
DispatchQueue.main.async {
KRProgressHUD.show()
}
DispatchQueue.main.async {
KRProgressHUD.dismiss()
}
Main difference between GET and POST
GET - When you get some data from URL Like name, address, gender etc. GET methods is only use for retrive data from URL.
Post - When you send some data on server then use post methods.
GET : The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI. If the Request-URI refers to a data-producing process, it is the produced data which shall be returned as the entity in the response and not the source text of the process, unless that text happens to be the output of the process.
The semantics of the GET method change to a "conditional GET" if the request message includes an If-Modified-Since, If-Unmodified-Since, If-Match, If-None-Match, or If-Range header field. A conditional GET method requests that the entity be transferred only under the circumstances described by the conditional header field(s). The conditional GET method is intended to reduce unnecessary network usage by allowing cached entities to be refreshed without requiring multiple requests or transferring data already held by the client.
POST : The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line. POST is designed to allow a uniform method to cover the following functions:
- Annotation of existing resources;
- Posting a message to a bulletin board, newsgroup, mailing list,
or similar group of articles;
- Providing a block of data, such as the result of submitting a
form, to a data-handling process;
- Extending a database through an append operation.
The actual function performed by the POST method is determined by the server and is usually dependent on the Request-URI. The posted entity is subordinate to that URI in the same way that a file is subordinate to a directory containing it, a news article is subordinate to a newsgroup to which it is posted, or a record is subordinate to a database.
Read this LINK for more information
your code is using post method.
i.e.
Post Method:
urlLoc = this is url before. //i.e www.google.com
requestString = you are add your textfield value after urlLoc. //name='Bhadresh'
- this method user doesn't see requestString data in browser url
Get Method:
urlLoc + requstString = website.com/directory/index.php?name=YourName&bday=YourBday
- this method user see requestString data in browser url
More infomation:: What is the difference between POST and GET?
Both are used to transfer data from client to server in HTTP protocol
GET:
Parameters are appended in URL
Used mainly for fetching data
GET parameters are used to describe which document you need, or which page you are in
URL length is restricted, hence the parameters
Limited amount of data can be sent
Data is not secure, because they are exposed in URL bar
POST:
Parameters are included in body
Used mainly for updating data & making changes to server.
Large amount of data can be sent
Secured because no data is exposed in URL bar

How to submit a very-very long String to server via POST and get jSON response

I wish to send a very very long string(length of string is more than 10000) to the server and in return get the jSON response from the string.What is the best approach for the task. I am sending various parameters along with this very very long string.
Split down your long string to parts which can be send over one request. Create a json like this
{
"index":"0",
"length":"LENGTH_OF_STRING",
"string":"xsfsffwff.......",
//other json parameters
}
then you can send your string
The problem is that you're trying to put this all into a query parameter. Most servers have built-in limits for URLs, and for good reason.
There's nothing special about the body of an HTTP POST, so just send that up like you would anything else. Just make sure that you set the Content-Length header (since you know that; it might be covered by the HTTP library) and then just stream your data up. No need for any encoding or query params.
I don't know much about objective-c, but I'm sure there's a way to send data like this in an HTTP POST very simply. I've done this with Go and node.js, and both have simple ways of sending arbitrary data in a POST request body.
If you are using the ASI-Http classes , then you can send request like this
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:[WebService getAddPhoto]]];
[request addPostValue:[[imgArray objectAtIndex:i] valueForKey:#"vComments"] forKey:#"comment"];
NSData *imageData = UIImagePNGRepresentation([UIImage imageWithContentsOfFile:[[imgArray objectAtIndex:i] valueForKey:#"vPhoto"]]);
NSString *encodedString = [imageData base64EncodingWithLineLength:[imageData length]];
[request addPostValue:encodedString forKey:#"Photo"];
[request setDelegate:self];
[request startAsynchronous]

Post Data format is diffrent then what I needed

I am having a simple problem while making a request to server for updating a name field. I need to post some data in this format:-
{"api_token"=>"api", "device_token"=>"device", "user"=>{"name"=>"mohit"}, "id"=>"4"}
But when i am trying to post something its posting in this format:-
{"user"=>"(\n {\n name = ChangeName;\n }\n)", "api_token"=>"api", "device_token"=>"device", "id"=>"4"}
I am not able to figure out how to change my code to generate proper request. Here is the code that I am using.
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:#"http://localhost:3000/users/4?api_token=api&device_token=device"]];
NSMutableDictionary *dict= [NSMutableDictionary dictionaryWithObjectsAndKeys: #"Mike",#"name", nil];
NSArray *array=[[NSArray alloc]initWithObjects:dict, nil];
[request setPostValue:array forKey:#"user"];
[request setRequestMethod:#"PUT"];
[request setDelegate:self];
[request setDidFinishSelector:#selector(requestFinished:)];
[request startAsynchronous];
Please let me know if i need to post some more code fragments.
ASIFormDatRequest setPostValue:forKey: wants strings, not structures. It ends up calling description to convert them to strings and you're getting the printable description of an array with a dictionary in it.
Rails uses a naming scheme that allows you to simulate a hierarchy in a flat space using a field naming convention detailed at http://guides.rubyonrails.org/form_helpers.html. You should read that and understand the html produced by the form helpers.
Try:
[request setPostValue:#"mohit" forKey:#"user[name]"];
and rails will unpack it into the proper kind of collection on the server.

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.

Empty body in POST in ASIHTTPRequest

Basically, I am sending a POST request with an empty data body:
ASIHTTPRequest *request [ASIHTTPRequest alloc] init];
[request setURL:[NSURL URLWithString:escapedUrlString]];
[request setRequestMethod:#"POST"];
[request addRequestHeader:#"Content-Type" value:#"application/xml"];
[request startSynchronous];
But i am getting this response each time:
Incorrect NSStringEncoding value 0x0000 detected. Assuming NSStringEncodingASCII. Will stop this compatiblity mapping behavior in the near future.
I am wondering if it's mandatory to set post values.
I don't have much experience with the ASIHTTPRequest wrapper but I can see you are initialising it with alloc:init whilst most examples I've seen have a convenience initialiser requestWithURL:(NSURL*)url i.e.
ASIHTTPRequest *request = [AIHTTPRequest requestWithURL:escapedUrlString];
At a guess I'd say this convenience initaliser will also set some of the required variables for your post request to work, including NSStringEnconding.
From the ASIHTTPRequest documentation at http://allseeing-i.com/ASIHTTPRequest/How-to-use#handling_text_encodings
Handling text encodings
ASIHTTPRequest will attempt to read
the text encoding of the received data
from the Content-Type header. If it
finds a text encoding, it will set
responseEncoding to the appropriate
NSStringEncoding. If it does not find
a text encoding in the header, it will
use the value of
defaultResponseEncoding (this defaults
to NSISOLatin1StringEncoding).
When you call [request
responseString], ASIHTTPRequest will
attempt to create a string from the
data it received, using
responseEncoding as the source
encoding.
As Rog says, use initWithURL or requestWithURL. Anyway, in my case the problem was that I was connecting to a slow server and the request timed out giving the "Incorrect NSStringEncoding value 0x0000 detected" error.
I solved it with:
request.timeOutSeconds = 50;
You can try with more than 50 second if your server is even slower.