This question already has an answer here:
Fetching JSON data after failed retrieval
(1 answer)
Closed 7 years ago.
I'm trying to get this UIAlertView to run when fetching the JSON data fails, but i can't seem to get it to work. I'd appreciate it if someone could show me how to do it or point me in the right direction!
I think you have forget to write failure block.
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"success: %#", operation.responseString);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %#", operation.responseString);
}];
Hope this will help you.
You can write this in your block
NSDictionary *headersCollection=[[(NSDictionary *)operation valueForKey:#"response"]valueForKey:#"allHeaderFields"];
NSMutableDictionary *headers=[headersCollection mutableCopy];
headers[#"statusCode"]=[NSNumber numberWithInteger:operation.response.statusCode];
and then check the status code value. Headers dictionary will provide you the complete header which is returned. If statuscode is 200 everything is OK else you can show your custom message accordingly with different status code values like 400, 415 etc
Related
I am working on an app where I have AFNetworking fetching JSON requests from the my server. Now JSON is dynamically created based upon the POST variables I send from my app.
I was wondering when I get the following error message
JSON text did not start with array or object and option to allow fragments not set.
Is there a way to adapt my code so that I can actually see in the logger what the returned JSON request looks like. I have a feeling that there is a warning popping up in my PHP that is throwing off the JSON but I am not sure what it is.
Here is my code, it would make it so much easier if I could lets say NSLog the body content.
[manager POST:#"__MY__URL__" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
} progress:nil success:^(NSURLSessionDataTask *operation, id responseObject) {
NSLog(#"Success: %#", responseObject);
if([[responseObject objectForKey:#"state"] isEqualToString:#"success"]){
//[self performSegueWithIdentifier:#"client_choose_ad" sender:self];
}else {
[self alertError:#"Unable To Create Advert" alertMessage:[responseObject objectForKey:#"message"]];
}
} failure:^(NSURLSessionDataTask *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
Maybe printing the raw data of the request is what you are looking for.
How to print AFNetworking request as RAW data
I am trying to use an AFNetworking class to retrieve data from a database. Long story short, the data received from the parameter responseObject is filled with items. Here is my problem however. I am trying to copy the results in responseObject into an NSDictionary called results. I used the following code to get there:
__block NSDictionary *results;
[manager GET:#"http://daneolog.altervista.org/app/getData.php"
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) { results = responseObject;
NSLog(#"Inside: %#", results); }
failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(#"%#", error); }];
NSLog(#"Outside: %#", results);
I tried NSLoging the results dictionary INSIDE the success braces, and everything is a-okay there.
I tried NSLoging the results dictionary OUTSIDE the GET function, and it comes up as (null).
These are my results:
2015-11-12 14:34:34.875 TestApp[4864:258743] Outside: (null)
2015-11-12 14:34:35.242 TestApp[4864:258743] Inside: (
{
address = "Sample Address";
}
)
Now notice the peculiar thing: the outside NSLog is being executed first. I don't know why this is so. Can anyone help me on this? Thanks a bundle.
Your code outside the success block is executing before the success block completes that is why results come up as null. results is on the main thread, and you are not blocking (as is correct with an HTTP request).
You can pass a weak reference to an object, and have that updated. Or if you absolutely need to wait for the result (login for instance) then you should do it on the main thread.
Here is an example of a weak object:
//results is an object created earlier
__weak NSDictionary *weakResults = results;
[manager GET:#"http://daneolog.altervista.org/app/getData.php"
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
weakResults = responseObject;
NSLog(#"Inside: %#", results);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"%#", error);
}];
//when the success block finishes the results object will be populated
If you wanted to block i.e. do it on the main thread you could use:
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
However, if the response doesn't come back, your app hangs.
So I am trying to access a json file online and I can get the contents of the JSON file when I run the completion block using AFHTTPRequestOperation method. But when I try to NSLog outside the completion block, it becomes null. I was wondering why this is happening and how I would go about fixing this. Below is the code I have so far:
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCredential:credentials];
[operation setResponseSerializer:[AFJSONResponseSerializer alloc]];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success %#", responseObject);
jsonOutputData = [NSMutableArray arrayWithObject:responseObject];
self.newsFeedArray = [NSMutableArray arrayWithArray:[jsonOutputData copy]];
}failure:^(AFHTTPRequestOperation *operation, NSError *error){
NSLog(#"Failure: %#", error);
}];
[manager.operationQueue addOperation:operation];
NSLog(#"%#", self.newsFeedArray);
The NSLog with Success shows the JSON but the NSLog with the self.newsFeedArray shows (null). I am just wondering why this is happening. If you need more clarification, let me know. Any help would be appreciated!
Thanks!
The success and failure blocks get called asynchronously. So self.newsFeedArray simply has not been set yet at the time of the last NSLog call, because the operation has not completed.
You could wait for the operation to complete (e.g., [operation waitUntilFinished]) but you almost certainly don't want to do this, especially on the main thread. Rather have the completion blocks trigger the desired behaviour.
Sorry, but im kinda a newb regarding http post terminology!
I have to post to a webservice that cannot be changed:
The format is as follows:
http://SomeWebAddress/JSON/GetAllFeedsRestfullyWrapped?userToken=FOO
so the parameters are:
key:userToken , value=FOO
In the body i need to put a JSON formatted array like this:
{"feedIds":[1,2,3,4,5,6]}
Im trying to accomplish this with AFNetworking but cannot seem to make it work for this situation.
I have tried both the AFHttpclient and AFJSONReqestIOperation but im not able to combine the request and body correct.
So i hope someone knows how to do this. Help is very much appreciated.
Try that
[[YourHTTPClient sharedHTTPClient] postPath:#"GetAllFeedsRestfullyWrapped?userToken=FOO"
parameters:[NSDictionnary {"feedIds":[1,2,3,4,5,6]}]
success:^(AFHTTPRequestOperation *request, id JSON)
{
}
failure:^(AFHTTPRequestOperation *request, NSError *error)
{
}];
So using Mathieu Hausherr's response as a baseline this was my solution:
NSArray *feedIds = [NSArray arrayWithObject:[NSNumber numberWithInteger:3]];
NSMutableDictionary *parameters = [[NSMutableDictionary alloc]init];
[parameters setObject:feedIds forKey:#"listOfFeedIds"];
[[RssReaderWebserviceApiClient sharedInstance] postPath:#"GetFeedsRestfullyWrapped?userToken=FOO"
parameters:parameters
success:^(AFHTTPRequestOperation *request, id JSON){
LOG_TEST(1,#"Response: %#",JSON);
}
failure:^(AFHTTPRequestOperation *request, NSError *error){
LOG_ERROR(1,#"Error: %#",error);
}];
I use the method postPath:parameters to achieve the post.
I manually set the parameters in the request header and input the bodyparameters from a dictionary.
Encoding is set to JSON.
I anyone wonders the logging is done using NSLogging.It's awesome.
I am trying to post a sound to echo nest for file analysis. The POST method is no different than any other method, and I believe it's not echonest dependent.
Here is the documentation. I need the "upload" part.
http://developer.echonest.com/docs/v4/track.html
NSURLRequest *request = [self multipartFormRequestWithMethod:#"POST" path:[NSString stringWithFormat:#"track/upload", self.apiKey] parameters:dictionary constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:data name:#"track" fileName:[path lastPathComponent] mimeType:#"multipart/form-data"];
}];
AFURLConnectionOperation *operation = [self HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"done");
NSLog(#"response: %#", operation.responseString);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %#", error.description);
NSLog(#"response: %#", operation.responseString);
NSLog(#"headers: %#", operation.request.allHTTPHeaderFields.description);
NSLog(#"operation url: %#", operation.request.URL.absoluteString);
}];
However, I have problems. Here is my response:
{"response": {"status": {"version": "4.2", "code": 4, "message": "track - Missing Parameter: track or url is required with a POST content-type of \"application/x-www-form-urlencoded\" or \"multipart/form-data\""}}}
I thought I have already given the "track" parameter to be the data I initialized. Can anyone help me?
I experienced same problem few weeks ago. And here is what i found.
AFNetworking makes slightly wrong multipart/form-data request.
In AFHTTPClient.m file,
static inline NSString * AFMultipartFormFinalBoundary() {
return [NSString stringWithFormat:#"%#--%#--%#%#", kAFMultipartFormCRLF, kAFMultipartFormBoundary, kAFMultipartFormCRLF, kAFMultipartFormCRLF];
}
They put kAFMultipartFormCRLF twice at the end of final boundary of a request.
But Echonest only except request with one CRLF at the end of multipart/form-data post request.
I don't know which one is exactly the righteous way in terms of HTTP protocol standard, but if you modify that code line (remove a kAFMultipartFormCRLF), i think your code would work well.
FYI, while writing this answer, I explored current AFNetworking Git repo, and found out that this defect has been fixed just 5 days ago. So i guess you can just use latest source code to fix the problem.