I was observirng some strange behaviour of my app sometime caching responses and sometime not caching them (all the responses have Cache-Control: max-age=600).
The test is simple: I did a test.php script that was just setting the headers and returning a simple JSON:
<?php
header('Content-Type: application/json');
header('Cache-Control: max-age=600');
?>
{
"result": {
"employeeId": "<?php echo $_GET['eId']; ?>",
"dateTime": "<?php echo date('Y-m-d H:i:s'); ?>'" }
}
This is the response I get from the PHP page:
HTTP/1.1 200 OK
Date: Thu, 28 Nov 2013 11:41:55 GMT
Server: Apache
X-Powered-By: PHP/5.3.17
Cache-Control: max-age=600
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/json
{
"result": {
"employeeId": "",
"dateTime": "2013-11-28 11:41:55'"
}
}
Then I've created a simple app and added AFNetworking library.
When I call the script with few parameters, the cache works properly:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *params = #{
#"oId": #"4011",
#"eId": self.firstTest ? #"1" : #"0",
#"status": #"2031",
};
[manager GET:#"http://www.mydomain.co.uk/test.php" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
NSLog(#"Cache current memory usage (after call): %d", [cache currentMemoryUsage]);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
But when I increase the number of parameters, like:
NSDictionary *params = #{
#"organizationId": #"4011",
#"organizationId2": #"4012",
#"organizationId3": #"4013",
#"organizationId4": #"4014",
#"organizationId5": #"4015",
#"organizationId6": #"4016",
#"eId": self.firstTest ? #"1" : #"0",
#"status": #"2031",
};
it doesn't work anymore and it execute a new request each time it is called.
I've done many tests and it seems to me that it is related to the length of the URL, because if I includes this set of params:
NSDictionary *params = #{
#"oId": #"4011",
#"oId2": #"4012",
#"oId3": #"4013",
#"oId4": #"4014",
#"oId5": #"4015",
#"oId6": #"4016",
#"eId": self.firstTest ? #"1" : #"0",
#"status": #"2031",
};
It works!!
I've done many tests and that's the only pattern I've found...
To exclude AFNetworking from the equation, I've created another test program that uses NSURLConnection only and I can see the same behaviour so it's not AFNetworking and definitely NSURLCache. This is the other test:
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://www.mydomain.co.uk/test.php?eId=%#&organizationId=4011&organizationId2=4012&organizationId3=4013&organizationId4=4014&organizationId5=4015&organizationId6=4016", self.firstTest ? #"1" : #"0"]]; // doesn't work
//NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://www.mydomain.co.uk/test.php?eId=%#&oId=4011&oId2=4012&oId3=4013&oId4=4014&oId5=4015&oId6=4016", self.firstTest ? #"1" : #"0"]]; // work
//NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://www.mydomain.co.uk/test.php?eId=%#", self.firstTest ? #"1" : #"0"]]; // work
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLResponse *response = nil;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
if (error == nil) {
// Parse data here
NSString *responseDataStr = [NSString stringWithUTF8String:[data bytes]];
NSLog(#"Response data: %#", responseDataStr);
}
I've also tried to establish how many characters in the URL will trigger the problem but even in this case I've got strange results:
This one is 112 characters long and it doesn't work:
http://www.mydomain.co.uk/test.php?eId=1&organizationId=4011&organizationId2=4012&organizationId3=4013&orgaId4=4
This one is 111 characters long and it works:
http://www.mydomain.co.uk/test.php?eId=1&organizationId=4011&organizationId2=4012&organizationId3=4013&orgId4=4
Ive renamed the PHP script to see if the first part of the URL would matter and I've got a strange behaviour again:
This one is 106 characters long and it doesn't work:
http://www.mydomain.co.uk/t.php?eId=1&organizationId=4011&organizationId2=4012&organizationId3=4013&org=40
This one is 105 characters long and it works:
http://www.mydomain.co.uk/t.php?eId=1&organizationId=4011&organizationId2=4012&organizationId3=4013&org=4
So I've removed 3 characters from the page name and I've got a working threshold 6 characters lower.
Any suggestion?
Thanks,
Dem
I am witnessing something similar with certain responses not being cached by NSURLCache and I have come up with another possible reason:
In my case I have been able to ascertain that the responses not being cached are the ones that are returned using Chunked transfer-encoding. I've read elsewhere that NSURLCache should cache those after iOS 6 but for some reason it doesn't in my case (iOS 7.1 and 8.1).
I see that your example response shown here, also has the Transfer-Encoding: chunked header.
Could it be that some of your responses are returned with chunked encoding (those that are not cached) and some are not (those that are cached)?
My back-end is also running PHP on Apache and I still can't figure out why it does that...
Probably some Apache extension...
Anyway, I think it sounds more plausible than the request URL length scenario.
EDIT:
It's been a while, but I can finally confirm that in our case, it is the chunked transfer encoding that causes the response not to be cached. I have tested that with iOS 7.1, 8.1, 8.3 and 8.4.
Since I understand that it is not always easy to change that setting on your server, I have a solution to suggest, for people who are using AFNetworking 2 and subclassing AFHTTPSessionManager.
You could add your sub-class as an observer for AFNetworking's AFNetworkingTaskDidCompleteNotification, which contains all the things you will need to cache the responses yourself. That means: the session data task, the response object and the response data before it has been processed by the response serializer.
If your server uses chunked encoding for only a few of its responses, you could add code in -(void)didCompleteTask: to only cache responses selectively. So for example you could check for the transfer-encoding response header, or cache the response based on other criteria.
The example HTTPSessionManager sub-class below caches all responses that return any data:
MyHTTPSessionManager.h
#interface MyHTTPSessionManager : AFHTTPSessionManager
#end
MyHTTPSessionManager.m
#import "MyHTTPSessionManager.h"
#implementation MyHTTPSessionManager
+ (instancetype)sharedClient {
static MyHTTPClient *_sharedClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[[NSNotificationCenter defaultCenter] addObserver:_sharedClient selector:#selector(didCompleteTask:) name:AFNetworkingTaskDidCompleteNotification object:nil];
});
return _sharedClient;
}
- (void)didCompleteTask:(NSNotification *)notification {
NSURLSessionDataTask *task = notification.object;
NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
NSData *responseData = notification.userInfo[AFNetworkingTaskDidCompleteResponseDataKey];
if (!responseData.length) {
// Do not cache empty responses.
// You could place additional checks above to cache responses selectively.
return;
}
NSCachedURLResponse *cachedResponse = [[NSCachedURLResponse alloc] initWithResponse:response data:responseData];
[[NSURLCache sharedURLCache] storeCachedResponse:cachedResponse forRequest:task.currentRequest];
}
I tried to come up with some sort of cleaner solution, but it seems that AFNetworking does not provide a callback or a delegate method that returns everything we need early enough - that is, before it has been serialized by the response serializer.
Hope people will find this helpful :)
Did you try to configure
NSURLRequestCachePolicy
for NSURLRequest
+ (id)requestWithURL:(NSURL *)theURL cachePolicy:(NSURLRequestCachePolicy)cachePolicy timeoutInterval:(NSTimeInterval)timeoutInterval
These constants are used to specify interaction with the cached responses.
enum
{
NSURLRequestUseProtocolCachePolicy = 0,
NSURLRequestReloadIgnoringLocalCacheData = 1,
NSURLRequestReloadIgnoringLocalAndRemoteCacheData =4,
NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData,
NSURLRequestReturnCacheDataElseLoad = 2,
NSURLRequestReturnCacheDataDontLoad = 3,
NSURLRequestReloadRevalidatingCacheData = 5
};
typedef NSUInteger NSURLRequestCachePolicy;
You could investigate what your cached response is from the sharedURLCache by subclassing NSURLProtocol and overriding startLoading:
add in AppDelegate application:didFinishLaunchingWithOptions:
[NSURLProtocol registerClass:[CustomURLProtocol class]];
Then create a subclass of NSURLProtocol (CustomURLProtol) and override startLoading
- (void)startLoading
{
self.cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:self.request];
if (self.cachedResponse) {
[self.client URLProtocol:self
didReceiveResponse:[self.cachedResponse response]
cacheStoragePolicy:[self.cachedResponse storagePolicy]];
[self.client URLProtocol:self didLoadData:[self.cachedResponse data]];
}
[self.client URLProtocolDidFinishLoading:self];
}
self.cachedResponse is a property NSCachedURLResponse i've added. You can see if anything is wrong with any cachedResponse here.
Related
I currently am using AFNetworking to determine if my application has network reachability.
NSNumber *s = notification.userInfo[AFNetworkingReachabilityNotificationStatusItem];
AFNetworkReachabilityStatus status = [s integerValue];
if (status == AFNetworkReachabilityStatusReachableViaWWAN || status == AFNetworkReachabilityStatusReachableViaWiFi) {
But, now I also need to know if my application can reach a specific server. More specifically, the server I am connecting to may be down and I need a way to determine if this is the case, from the client side, so I can notify my users appropriately.
It's a very tough google because all searches I do just point me to "How to determine network reachability". Has anybody dealt with this before, and have a solution in mind?
EDIT: #AvT recommended a promising looking solution, so I tried it like this:
self.testTSCReachabilityManager = [AFNetworkReachabilityManager managerForDomain:#"www.asdasfjsldfkjslefjslkjslfs.com"];
__weak MyObject *weakSelf = self;
[self.testReachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
if (weakSelf.testReachabilityManager.reachable) {
NSLog(#"YES");
}
else
{
NSLog(#"NO");
}
}];
But unfortunately, it is logging out "YES" for me, even after I have confirmed it is most definitely not reachable.
Instantiate AFNetworkReachabilityManager with class method
+ (instancetype)managerForDomain:(NSString *)domain;
and pass string with the required domain. AFNetworkReachabilityManager will check reachability of this domain.
If serverURL is an url of your server you should use it the following way:
[AFNetworkReachabilityManager managerForDomain:serverURL.host]
Update
Following code works as expected:
static AFNetworkReachabilityManager *testTSCReachabilityManager;
testTSCReachabilityManager = [AFNetworkReachabilityManager managerForDomain:#"www.asdasfjsldfkjslefjslkjslfs.com"];
[testTSCReachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
if (testTSCReachabilityManager.reachable) {
NSLog(#"YES");
}
else
{
NSLog(#"NO");
}
}];
[testTSCReachabilityManager startMonitoring];
Update: I actually ended up going w/ a different implementation than what Avt recommended, and did what matt recommended in the comments instead
I created an NSURLRequest and make a request to my server, then used the delegate callbacks to determine if the server was reachable. Works like a charm
-(void)checkConnectionToServers
{
NSMutableURLRequest* request = [NSMutableURLRequest new];
request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"www.myserver.com"] cachePolicy:0 timeoutInterval:(NSTimeInterval)5.0];
[request setHTTPMethod:#"GET"];
[NSURLConnection connectionWithRequest:request delegate:self];
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(#"SUCCESS");
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(#"FAIL");
}
I am attempting the use the UNIRest API to run this get request in an iPhone application
https://api.guildwars2.com/v1/guild_details.json?guild_name=The%20Legacy
The code I am running is this
NSDictionary* headers = #{#"accept": #"application/json"};
NSDictionary* parameters = #{#"guild_name": #"The Legacy"};
UNIHTTPJsonResponse* response = [[UNIRest post:^(UNISimpleRequest* request) {
[request setUrl:#"https://api.guildwars2.com/v1/guild_details.json"];
[request setHeaders:headers];
[request setParameters:parameters];
}] asJson];
NSDictionary *guildInformation = response.body.JSONObject;
NSLog(#"response length: %lu", (unsigned long)[guildInformation.allValues count]);
for(NSString *key in [guildInformation allKeys]) {
NSLog(#"key: %# object: %#", key, [guildInformation objectForKey:key]);
}
I had hoped the for loop would display the response. But it seems I get no response at all when you see that the only output is,
response length: 0
I don't know the UNIRest API well enough to fix this and cannot find any good documentation for it. What am I doing wrong?
The problem seems to be that the parameters values are not correctly encoded.
As a fast workaround you can simply pass the entire constructed URL.
UNIHTTPJsonResponse* response = [[UNIRest post:^(UNISimpleRequest* request) {
[request setUrl:#"https://api.guildwars2.com/v1/guild_details.json?guild_name=The%20Legacy"];
[request setHeaders:#{#"accept": #"application/json"}];
}] asJson];
Probably the space in #"The Legacy" doesn't translate to "The%20Legacy", will do a test case before adding issue to https://github.com/Mashape/unirest-obj-c
UPDATE
Only while I was adding a TestCase for spaced values (which do work correctly) I spotted that you where using POST while you should have used GET.
UNIHTTPJsonResponse* response = [[UNIRest get:^(UNISimpleRequest* request) {
Hej,
I am struggling with doing a POST request to the parse REST API. I am using AFNetworking 2.0. My code for the AFHTTPSessionManager Subclass looks as follows:
+ (ParseAPISession *)sharedSession {
static ParseAPISession *sharedSession = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedSession = [[ParseAPISession alloc] initWithBaseURL:[NSURL URLWithString:kSDFParseAPIBaseURLString]];
});
return sharedSession;
}
And:
- (id)initWithBaseURL:(NSURL *)url {
self = [super initWithBaseURL:url];
if (self) {
[self.requestSerializer setValue:kSDFParseAPIApplicationId forHTTPHeaderField:#"X-Parse-Application-Id"];
[self.requestSerializer setValue:kSDFParseAPIKey forHTTPHeaderField:#"X-Parse-REST-API-Key"];
}
return self;
}
I am doing the request like this:
[[ParseAPISession sharedSession] POST:#"ClassName" parameters: [NSDictionary dictionaryWithObjectsAndKeys:#"name", #"name", nil]
success:^(NSURLSessionDataTask *task, id abc) {
NSLog(#"%#", abc);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(#"%#", error);
}];
Doing this I always get this kind of error:
Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.) UserInfo=0x8c72420 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}
Since the GET Request works like a charm I am quite confused why I can’t POST something. Can anybody halp me with this problem?
Best regards!
UPDATE
Happily after testing around a lot this Error message isn't displayed anymore, unfortuatelly another appeared:
<NSHTTPURLResponse: 0x8b96d40>
{ URL: https://api.parse.com/1/users }
{ status code: 400,
headers {
"Access-Control-Allow-Origin" = "*";
"Access-Control-Request-Method" = "*";
"Cache-Control" = "no-cache";
Connection = "keep-alive";
"Content-Length" = 130;
"Content-Type" = "application/json; charset=utf-8";
Date = "Wed, 30 Oct 2013 20:01:58 GMT";
Server = "nginx/1.4.2";
"Set-Cookie" = "_parse_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlNjIxZjUxMzY3NWVhZWJmMDYyYWYwMGJiZTQ3MThmMWE%3D--851bd31b07e7dba2c5f83bb13a8d801ecbea42c4; domain=.parse.com; path=/; expires=Fri, 29-Nov-2013 20:01:58 GMT; secure; HttpOnly";
Status = "400 Bad Request";
"X-Runtime" = "0.060910";
"X-UA-Compatible" = "IE=Edge,chrome=1";
} }
Can anyone tell me what the Status: 400 Bad Request is telling me and how I can get rid of it?
This error means that your POST request went through, the server is successfully returning you some data, which NSJSONSerialization is having trouble parsing.
You probably need to set your AFJSONResponseSerializer to allow JSON fragments.
In the init method of your AFHTTPSessionManager subclass:
AFJSONResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];
[self setResponseSerializer:responseSerializer];
If this doesn't work, you probably have an encoding issue. From the NSJSONSerialization class reference:
The data must be in one of the 5 supported encodings listed in the JSON specification: UTF-8, UTF-16LE, UTF-16BE, UTF-32LE, UTF-32BE. The data may or may not have a BOM. The most efficient encoding to use for parsing is UTF-8, so if you have a choice in encoding the data passed to this method, use UTF-8.
Check the encoding type sent by your server.
Finally, you can either set breakpoints inside of AFNetworking, or set up AFNetworkActivityLogger, which will log requests as they are sent and received to your console. This tool is incredibly helpful for debugging this type of issue.
This worked for me :
in the AFHTTPSessionManager subclass initialise it with the following serialisers:
[self setRequestSerializer:[AFHTTPRequestSerializer serializer]];
[self setResponseSerializer:[AFJSONResponseSerializer serializer]];
I am trying to send a POST request to a server using AFNetworking, and everything seems to be working, i.e. the application is successfully pinging the server. However, the parameter values that it is sending are blank when it reaches the server even though after stepping through my code below using the debugger, the values appear to be being passed successfully. Any help on this would be greatly appreciated.
APIClient.m
#import "APIClient.h"
#import "AFJSONRequestOperation.h"
// Removed URL for privacy purposes.
static NSString * const kAPIBaseURLString = #"string goes here";
#implementation APIClient
+ (APIClient *)sharedClient {
static APIClient *_sharedClient;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedClient = [[APIClient alloc] initWithBaseURL:[NSURL URLWithString:kAPIBaseURLString]];
});
return _sharedClient;
}
- (id)initWithBaseURL:(NSURL *)url {
self = [super initWithBaseURL:url];
if (self) {
[self registerHTTPOperationClass:[AFJSONRequestOperation class]];
// Accept HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
[self setDefaultHeader:#"Accept" value:#"application/json"];
}
return self;
}
#end
Login Method in LoginBrain.m
- (void)loginUsingEmail:(NSString *)email andPassword:(NSString *)password withBlock:(void (^)(NSDictionary *loginResults))block {
self.email = email;
self.password = password;
// Removed path for privacy purposes
[[APIClient sharedClient] postPath:#"insert path here" parameters:[NSDictionary dictionaryWithObjectsAndKeys:email, #"uname", password, #"pw", nil] success:^(AFHTTPRequestOperation *operation, id responseJSON) {
if (block) {
block(responseJSON);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
if (block) {
block(nil);
}
}];
// Store user data in app?
}
Login Called Method in LoginViewController.m
- (IBAction)loginPressed {
[self.loginProgressIndicator startAnimating];
NSString *email = self.emailTextField.text;
NSString *password = self.passwordTextField.text;
[self.brain loginUsingEmail:email andPassword:password withBlock:^(NSDictionary *loginResults) {
[self.loginProgressIndicator stopAnimating];
[self.delegate uloopLoginViewController:self didLoginUserWithEmail:email andPassword:password];
}];
}
UPDATE
I tried changing the parameterEncoding as recommended here, but it did not fix the problem.
SECOND UPDATE
Here is the PHP code from the server side that is accessing the POST data. This was written by a co-worker of mine, as I don't do anything on the server side and am very unfamiliar with how it works.
header('Content-type: application/json');
$username = $_POST['uname'];
$pw = $_POST['pw'];
The server code is pretty straight forward. He has some sort of log script that checks to see what the variable values are, and he says that the client is hitting the server, but the variable values are blank.
THIRD UPDATE
This is a dump of the HTTP request by generating a print_r of the $_REQUEST variable:
Array ( [sid] => FwAqvZrfckw )
And here is a dump of the $_POST variable. As you can see, it's completely blank:
Array ( )
FOURTH UPDATE
I used Wireshark to capture the packet before it's being sent to the server, and everything appears to be in order:
Accept: application/json
Content-Type: application/x-www-form-urlencoded; charset=utf-8
And the POST parameters were all there as well. We also created a test file on the server side and just did a test POST to make sure that the code there is working, and it is.
Thank you.
With the same problem, using AFFormURLParameterEncoding was what I needed.
So just to simplify all the thread, you have to use :
[[APIClient sharedClient] setParameterEncoding:AFFormURLParameterEncoding];
I don't see anything in particular that would cause a problem here but I'll start off by giving you the steps I used to solve a similar problem.
To start, checkout the tool, Charles, which is a Debugging Web Proxy that will intercept the response from the server and should give you a more clear idea of what's going wrong. There's a 30 day free trial and it really helped me pick out the little bugs. To use it, press the sequence button and filter the results via your server url. From there you can see the request and response sent and received from the server. If the following doesn't fix your problem, post the request and response that Charles spits out.
Fix wise, try adding [[APIClient sharedClient] setParameterEncoding:AFJSONParameterEncoding] right before you send the POST request. It looks like yall are using JSON as the server-side format.
So in loginUsingEmail:
self.email = email;
self.password = password;
[[APIClient sharedClient] setParameterEncoding:AFJSONParameterEncoding];
[[APIClient sharedClient] postPath:#"insert path here" parameters:[NSDictionary dictionaryWithObjectsAndKeys:email, #"uname", password, #"pw", nil] success:^(AFHTTPRequestOperation *operation, id responseJSON) {
if (block) {
block(responseJSON);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
if (block) {
block(nil);
}
}];
// Store user data in app?
}
How to access the (POST)data sent with the request from the requestFailed/requestFinished function.
- (void) abc {
NSString *postString = #"john";
NSURL *url = [NSURL URLWithString:#"http://abc.com"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setPostValue:postString forKey:#"name"];
[request setDelegate:self];
[request startAsynchronus];
}
- (void) requestFinished:(ASIHTTPRequest *)request
{
// Question is whether the request holds the sent post values.
// If it holds. how can we access them.
// i tried using [request valueForKey:#"name"];
// but it won't work.
}
Handling success and failure for multiple requests in delegate methods
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 For more complex situations, or where you want to parse
the response in the background, create a minimal subclass of
ASIHTTPRequest for each type of request, and override requestFinished:
and failWithError:.
That provided me a good solution to handle different requests.
You could try this -
- (void)requestFinished:(ASIHTTPRequest *)request {
NSLog(#"Response %d ==> %#", request.responseStatusCode, [request responseString]);
}
You can also handle other methods if you choose, such as:
- (void)requestStarted:(ASIHTTPRequest *)request;
- (void)requestFailed:(ASIHTTPRequest *)request;
The docs are located at http://allseeing-i.com/ASIHTTPRequest/ and are fantastic.
You can cast your request into a ASIFormDataRequest:
if ([request isKindOfClass:[ASIFormDataRequest class]]) {
ASIFormDataRequest *requestWithPostDatas = (ASIFormDataRequest *)request;
NSArray *myPostData = [requestWithPostDatas getPostData];
}
You will also have to make "postData" accessible with a "getPostData" public function in ASIFormDataRequest.