The following code is used to make a post request to a server using AFHTTPClient:
NSURL *url = [NSURL URLWithString:urlString];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
//objects and keys
nil];
[httpClient postPath:postPath parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
id results = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONWritingPrettyPrinted error:nil];
//completion block
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"%#",error);
}];
[httpClient release];
But I noticed the request is still running even when the user has popped from the current viewController (noticed when a timed out error was logged, when on another viewController).
How do stop the request, when the viewController is no longer in the view hierarchy.
You can do this:
[[httpClient operationQueue] cancelAllOperations];
or this :
[self cancelAllHTTPOperationsWithMethod:#"POST" path:#"/path"];
You can put one of them in your viewWillDisappear;
Related
I'm having a problem with AFNetworking.
Currently I can send a POST request in JSON format [AFJSONParameterEncoding] using NSDictionary to a server and it correctly replies, the problem is that the server replies with a JSON formatted response too, response I'm able to convert to NSString using:
[[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
// responseObject is the server response
The problem is I'm not able to transform the response in any other format, other than NSString like in the code posted before. How can that be possible? I would like to convert the response to JSON format so I can read a precise value, the value associated with the key "isInformative"
Here's my code so far:
NSDictionary *requestBody = [NSDictionary dictionaryWithObjectsAndKeys:
#"value1", #"key1",
#"value2", #"key2",
nil];
NSDictionary *requestHead = #{
#"RequestHead": requestBody
};
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:#"http://XXX.XXX.XXX.XXX:XXXX"]];
[httpClient setParameterEncoding:AFJSONParameterEncoding];
[httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
NSMutableURLRequest *request = [httpClient requestWithMethod:#"POST"
path:#"/public-mobile-sdk/"
parameters:requestHead];
AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *requestOperation, id responseObject) {
// Here I can convert the responseObject to NSSTring correctly
NSLog(#"Response: %#", [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]);
} failure:^(AFHTTPRequestOperation *requestOperation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[requestOperation start];
Note - I can't update the AFNetworking version bundled in the Xcode project since it's not my own, so sadly I must stick and use version 1.X
This solved my problem:
AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:jailbreakRequest];
[requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *requestOperation, id responseObject) {
//Place this line of code below to create a NSDictionary from the async server response
NSDictionary *jsonList = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
} failure:^(AFHTTPRequestOperation *requestOperation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[requestOperation start];
Thanks anyway :-)
I am currently trying to create a JSON array like I do here like this:
NSURL *url = [NSURL URLWithString:currentJSON];
NSData *jsonData = [NSData dataWithContentsOfURL:url];
NSError *error = nil;
if (jsonData) {
result = [NSJSONSerialization JSONObjectWithData:jsonData
options:NSJSONReadingMutableContainers
error:&error];
}
Which works fine. Apart from I want it to time out if the internet connection is not great.
So I then wen to AFNetworking where I wrote code like this:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:currentJSON parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSError *error = nil;
result = [NSJSONSerialization JSONObjectWithData:responseObject
options:NSJSONReadingMutableContainers
error:&error];
[[NSUserDefaults standardUserDefaults] setObject:result forKey:#"All"];
[[NSUserDefaults standardUserDefaults] synchronize];
} failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
result = [[NSUserDefaults standardUserDefaults] mutableArrayValueForKey:#"All"];
}
But this method always runs to a failure How come? What am I doing wrong?
Check that server is sending JSON using correct content type 'application/json'. AFNetowrking checks this out of the box and if receives something else (for example 'text/html'), failure block will be called.
Also AFNetworking does JSON to object parsing out of the box. 'id responseObject' is already the result of '[NSJSONSerialization JSONObjectWithData]'.
If you can't change content type sent by server, you could add that content type to accepted types using following snippet
NSMutableSet *accepted = [NSMutableSet set];
[accepted addObject:#"text/html"];
[accepted addObject:#"application/json"];
manager.responseSerializer.acceptableContentTypes = accepted;
Try this :
NSURL *url = [NSURL URLWithString:string];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
result = (NSDictionary *)responseObject;
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
[operation start];
I am querying my server using AFNetworking, the latest - to date - version.
My server side PHP is sending a PHP related error but I am unable to see what the error is ( so I can debug it) as AFNetworking is expecting a JSON.
Could anyone tell me how could I see the full HTTP result. I've researched and I know is something to do with operation.responseString inside the success / fail block my current block does not have AFHTTPRequestOperation* operation and I can't add it as another block variable somehow.
I would really appreciate some help.
The following code uses
NSURL *url = [[NSURL alloc]initWithString:URL];
AFHTTPClient *httpClient = [[AFHTTPClient alloc]initWithBaseURL:url];
NSURLRequest *request = [httpClient multipartFormRequestWithMethod:#"POST" path:URLPATH parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
{
//...
}
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON){
NSLog(#"Inside the success block %#",JSON);
[[self delegate ]shareExerciseDone:JSON];
[[self delegate] activityIndicatorFinish];
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON){
NSLog(#"Response text is: %#", operation.responseString);
NSLog(#"json text is: %#", JSON);
NSLog(#"Request failed with error: %#, %#", error, error.userInfo);
[[self delegate] activityIndicatorFinish];
}];
[operation start];
The error
Request failed with 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=0xc1b4520 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}, {
NSDebugDescription = "JSON text did not start with array or object and option to allow fragments not set.";
Don't use AFJSONRequestOperation, just use AFHTTPRequestOperation.
For Uploading Images From iOS to Server i am using Afnetworking
can you try with this Code.and you will get response in success or failure.
NSData *userImgToUpload = UIImagePNGRepresentation(userImg.image);
NSURL *url = [NSURL URLWithString:#"www.domainname.com"];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
NSLog(#"%#",#"Uploading data");
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:usernameTxt.text,#"username", firstnameTxt.text,#"first_name",lastnameTxt.text,#"last_name", nil];
// Upload Image
NSMutableURLRequest *request = [httpClient multipartFormRequestWithMethod:#"POST" path:#"/addPatient" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:userImgToUpload name:#"patientimage" fileName:[NSString stringWithFormat:#"%#.png",usernameTxt.text] mimeType:#"image/png"];
}];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"response: %#",[operation.responseString objectFromJSONString]);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Upload Failed");
NSLog(#"error: %#", [operation error]);
}];
[operation start];
You should listen for the AFNetworkingOperationDidStartNotification and AFNetworkingOperationDidFinishNotification events that fire at the beginning and end of the operation:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(YourOperationStartMethod:)
name:AFNetworkingOperationDidStartNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(YourOperationFinishMethod:)
name:AFNetworkingOperationDidFinishNotification
object:nil];
You can grab the operation object from the notification like this:
AFHTTPRequestOperation *operation =
(AFHTTPRequestOperation *) [notification object];
This operation object contains request and response properties.
A good example of how all this works can be found in the AFHTTPRequestOperationLogger plugin (which, of course, you could simply use, instead of writing your own thing).
I am using AFNetworking to sent a post request to a sever,
the request is successful, but no data were sent to the server.
the response string is the html form itself and
the form is filled in the value i sent to the sever.
Here is the code
NSURL *url = [NSURL URLWithString:#"http://www.example.com"];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
#"", #"__EVENTTARGET",
#"", #"__EVENTARGUMENT",
#"", #"__LASTFOCUS",
self.VIEWSTATE, #"__VIEWSTATE",
self.subject.text, #"ctl00$ContentPlaceHolder1$messagesubject",
self.message.text, #"ctl00$ContentPlaceHolder1$messagetext",
#"yes", #"ctl00$ContentPlaceHolder1$btn_Submit",
nil];
[httpClient postPath:#"/post.aspx" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSString *responseStr = [[NSString alloc] initWithData:operation.responseData encoding:NSUTF8StringEncoding];
NSLog(#"Request Successful, response '%#'", responseStr);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"[HTTPClient Error]: %#", error.localizedDescription);
}];
any idea?
I am using AFHTTPRequestOperation to get a couple of HTML pages to parse.
The problem i'm having, is if I use a wrong port number for example, when connecting to the server, the 'failed' error block doesn't fire. Instead the completion block fires but the responce string is nil.
I'm just switching over to AFNetworking from ASIHTTP, and with ASIHTTP this would produce an error.
Surely this should provide an error? How can I trap this?
NSString *urlString;
urlString = [NSString stringWithFormat:#"%#://%#:%#/",kHttp,_IP,_Port];
NSURL *url = [NSURL URLWithString:urlString];
// Set authorization
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
[httpClient setAuthorizationHeaderWithUsername:_User password:_Pass];
NSURLRequest *request = [httpClient requestWithMethod:#"POST" path:#"Info.htm" parameters:nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
if ([self parseInfoLive:operation.responseString])
_count_parsed++;
if (_count_parsed == 2)
[[NSNotificationCenter defaultCenter] postNotificationName:#"downloadsComplete" object:nil];
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error during connection: %#",error.description);
[[NSNotificationCenter defaultCenter] postNotificationName:#"errorConnecting" object:nil];
}];
[operation start];
This seems to be a bug in AFNetworking, even 2.5 years after this question. This occurs when response contains a special character(it can appear as a space since sometimes even text viewers too can't parse it). You can try converting recieved JSON string to NSUTF8StringEncoding and then use it as NSData, if needed.
NSURL *url = <YOUR REQUEST URL>
NSString *data = [NSString stringWithContentsOfURL:url];
NSData *metOfficeData = [data dataUsingEncoding:NSUTF8StringEncoding];
NSError *error = [NSError new];
NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:metOfficeData options:kNilOptions error:&error];