I am trying to check if my POST request is working properly using AFNetworking in Objective c. Request is working fine in Android and Postman. Here is my URL:
#define API_BASE #"54.191.xx.xxx/XXXXXXXX/index.php/checkout"
Here are my params:
NSDictionary *paramters = #{#"quantity":#"21", #"price":#"10"};
This is my code to make the request:
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:#"application/json"];
[manager POST:API_BASE parameters:paramters progress:nil success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(#"%#",responseObject);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Error" message:error.localizedDescription delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}];
This code never enters the success block and I am getting an error saying 'Unsupported URL'. Any help would be appreciated.
Change API_BASE value to include http://:
#define API_BASE #"http://54.191.26.206/EntropikSDKBackend/index.php/checkout
54.191.xx.xxx/XXXXXXXX/index.php/checkout is not a valid URL. You need to specify the scheme. Likely http:// or https://.
Note: http and https are the schemes. :// is just part of the URL syntax.
You will need to add http:// to your API_BASE, like so:
#define API_BASE #"http://54.191.26.206/EntropikSDKBackend/index.php/checkout
You will most likely also need to add an ATS exception to your info.plist to allow unencryped traffic to the host 54.191.26.206
You are missing the network reference path. Any URL you are providing should also need the network reference path for communication and to decide which scheme/protocol need to be used.
Related
I updated afnetwork to 2.0 due to 64 bit. I made a mistake at first using AFHTTPRequestSerializer, but the server side accept Json only. The wried thing was it works fine for me even I used AFHTTPRequestSerializer, so I didn't notice this problem and released the error app to public. Then I keep receiving user complain and somehow I rebuild my app on my device, and local server can catch my wrong content-type(application/x-www.form-urlencoded). After I updated the AFHTTPRequestSerializer to AFJSONRequestSerializer, it doesn't fix the problem, but the user still keep sending wrong content-type to server even they updated the app. New user has no problem, only happen on old user.
Is this related to cache problem?
Server Log:
10:22:53 AM] Mark 1 contentType is: application/x-www-form-urlencoded, method is: POST headers are: Connection=keep-alive&Content-Length=1880739&Content-Type=application%2fx-www-form-urlencoded&Accept=*%2f*&Accept-Encoding=gzip%2c+deflate&Accept-Language=en%3bq%3d1&Cookie=ASP.NET_SessionId%3dbby5dlk5afmsnqnoqpprvqpw&Host
10:04:56 AM] contentType is: application/json, method is: POST header is: Connection=keep-alive&Content-Length=40352 4&Content-Type=application%2fjson &Accept=*%2f*&Accept-Encoding=gzip%2c+deflate&Accept-Language=en%3bq%3d1&Cookie=ASP.NET_SessionId%3dcw3gdkg3sff1f0j50z2rnism&Host
my code is
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
AFHTTPRequestOperation *operation = [manager POST:_url parameters:requestParams success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"operation success: %#\n %#", operation, responseObject);
NSDictionary *decoded = [self processResponce:responseObject failureBlock:failureBlock];
if (!decoded) return;
BOOL containsError = [self checkErrorStatus:decoded failureBlock:failureBlock];
if (containsError) return;
successBlock(decoded[#"Data"]);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
failureBlock(FailureTypeUnknown, [error localizedDescription]);
}];
[operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
progressBlock(bytesWritten,totalBytesWritten,totalBytesExpectedToWrite);
}];
as per your response, please set your manager's content type as below
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:#"application/json"];
I'm new to IOS development and was doing something related to dynamic data request through a 3rd party api using AFNetworing, I assume this is the good way to do networking in IOS?
One issue I have so far is I have two AFHTTPSessionManager in two different class implementation files. When I ran the application, the first one executes successfully. but the second one is not working and the problem is in debug mode, I can see that the
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager GET:PLACE_DETAIL_URL
parameters:#{ #"key": APPLICATION_KEY,
#"placeid": placeid,
#"extensions": #"review_summary"
}
success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(#"%#", responseObject);
placeDetail = [[NSDictionary alloc] initWithDictionary: (NSDictionary *) [responseObject objectForKey:#"result"]];
} failure:^(NSURLSessionDataTask *task, NSError *error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error Places"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
}];
is not even executing. It's been skipped for some reason. Is this a bug or I can only have on AFHTTPSessionManager or AFHTTPOperationManager at a time?
P.S.
debug gif posted here for clear idea.
thanks for all your help.
I have a Django Rest Api with a iOS app and right now I'm testing AFNetworking to change the HTTP Request my app is doing but i came with this dilema that i dont know how to handle, first is that on REST Standards when i get an error i should return a 404_BAD_REQUEST as a status if either sends or something wrong happens and this is OK. The issue comes when AFNetworking sees this 404. I still want to see the JSON that it returns.
curl -X POST http://domain.com:8000/user-login/ -d "nick=superUser&pass_field=superPassword"
i get 202 Status HTTP:
{
"nick": "eddwinpaz", "rate": 30, "name": "Eddwin Paz", "avatar": "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-prn2/t1.0-1/p160x160/10270540_10154074250190063_1762683854515424400_n.jpg", "id": 9}eddwinpazs-MacBook-Pro:~ eddwinpaz$
}
When i get 404 BAD REQUEST i get:
{"message": "Invalid Username or Password"}
I want to grab that message json tag if i get a 404 Error
I've the following code. and put it on the message on the Alert
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = #{#"nick": #"eddwinpaz",#"pass_field":#"eddwinpaz1"};
AFHTTPRequestOperation *operation = [manager POST:#"http://domain.com/user-login/"];
[operation addAcceptableStatusCodes:[NSIndexSet indexSetWithIndex:404]];
[manager POST:#"http://domain.com/user-login/" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Login Failed"
message:#"E-mail or password are wrong, Please Try Again"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[hud hide:YES];
}];
Per default the error code 404 is handled as an error code. You could add it as one of the accepted error codes via
AFHTTPRequestOperation *operation = [manager POST:#"http://doma...
[operation addAcceptableStatusCodes:[NSIndexSet indexSetWithIndex:404]];
Then success: is called on an 404 response and you can handle it there.
The answer by #miho did not work for me. addAcceptableStatusCodes does not exist in AFNetworking 2.5.0 from what I can tell. I had to do the following.
NSMutableIndexSet *acceptedCodes = [[NSMutableIndexSet alloc]
initWithIndexSet:operation.responseSerializer.acceptableStatusCodes];
[acceptedCodes addIndex:304];
operation.responseSerializer.acceptableStatusCodes = [acceptedCodes copy];
After trying nearly every response on the subject, I've come up without a working answer to my problem.
The problem: So I've implemented the uploading portion of my app using AFNetworking 2.0.3 after porting from AFNetworking 1.3:
-(void)commandWithParams:(NSMutableDictionary*)params onCompletion:(JSONResponseBlock)completionBlock {
NSData* uploadFile = nil;
if ([params objectForKey:#"file"]) {
uploadFile = (NSData*)[params objectForKey:#"file"];
[params removeObjectForKey:#"file"];
}
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:#"http://54.204.17.38"]];
manager.responseSerializer = [AFJSONResponseSerializer serilizer];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:#"application/json"];
AFHTTPRequestOperation *apiRequest = [manager POST:#"/API" parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
if (uploadFile) {
[formData appendPartWithFileData:uploadFile name:#"file" fileName:#"photo.jpg" mimeType:#"image/jpeg"];
}
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
completionBlock(responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
completionBlock([NSDictionary dictionaryWithObject:[error localizedDescription] forKey:#"error"]);
}];
[apiRequest start];
}
The error I get when using this code is "Request failed: unacceptable content-type: text/html" I know you might be wondering if the server is responding with proper JSON, and I have every reason to think it is after inspecting the response headers in my browser that say 'MIME type: application/json'. Also, I am using 'header('Content-type: application/json')' at the top of my API as well (PHP API). Now, if I change the serialization type to 'AFHTTPResponseSerializer' instead of 'AFJSONResponseSerializer', it will not spit out the JSON error, but it will give me a different error (a random unrecognized selector error).
Any thoughts on why I cannot seem to get a JSON response out of this method?
You can set the AFHTTPSessionManager to accept any MIME Type:
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:#"text/html"];
Got it! So, turns out, unknowingly, although my API was returning valid JSON, matter examining the header response logged on the Xcode side of things (thru NSLog(#"Error: %#", error);), it was actually returning text/HTML because it wasn't actually hitting the correct file, it was getting re-routed by a header somewhere. After explicitly stating the API path to be /API/index.php and not just /API, it started returning the valid JSON! Next, after making sure the response was properly JSON serialized (using requestManager.responseSerializer = [AFJSONResponseSerializer serializer];), the app worked!
Hopefully this helps someone who was having the same issue :)
Ever since upgrading my IOS code to use AFNetworking version 2.0 instead of 1.x, I cannot do an HTTP Post any more with JSON parameters.
I suspect it is because my HTTP request header is not "application/json" but I have tried to do that and it still does not work.
This is my test code for trying to POST by JSON:
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:
email, #"email",
password, #"password",
nil];
[[OTApiClient sharedInstance] POST:#"login" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"result: %#", responseObject);
Boolean response = [[responseObject valueForKey:#"success"] boolValue];
if(response == TRUE) {
//ok, success
NSLog(#"success");
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:#"Success!" message:#"Successfully logged in" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
} else {
NSLog(#"Not successful");
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:#"Sorry" message:#"The email or password is incorrect." delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
}
dispatch_async(dispatch_get_main_queue(), ^{
[MBProgressHUD hideHUDForView:self.view animated:YES];
});
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %# , for operation: %#", error, operation);
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:#"Sorry" message:#"There is a problem connecting to the server, please try again soon." delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
dispatch_async(dispatch_get_main_queue(), ^{
[MBProgressHUD hideHUDForView:self.view animated:YES];
});
}];
});
and I keep getting this 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=0xca80730 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.} , for operation: <AFHTTPRequestOperation: 0xca6bee0, state: isFinished, cancelled: NO request: <NSMutableURLRequest: 0xca76040> { URL: http://1.2.3.4:9000/api/login }, response: <NSHTTPURLResponse: 0xc963d60> { URL: http://1.2.3.4:9000/error404 } { status code: 404, headers {
"Content-Length" = 1809;
"Content-Type" = "text/html; charset=utf-8";
} }>
I am very sure that the server is up and accessible because all other GET calls work properly.
I have checked the updated documentation for AFNetworking 2.0 and it seems like what I have is the right way to do a JSON POST
Please let me know if I missed anything
Thanks
IS
Actually, I finally got it to work.
Basically, for my requestSerializer of the AFHTTPRequestOperationManager, I was using AFHTTPRequestSerializer and then trying to set the Content-Type to "application/json"
But once I switched to using AFJSONRequestSerializer instead, it works fine now
AFJSONRequestSerializer *requestSerializer = [AFJSONRequestSerializer serializer];
[requestSerializer setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[requestSerializer setValue:#"application/json" forHTTPHeaderField:#"Accept"];
operationManagerInstance.requestSerializer = requestSerializer;
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
AFJSONRequestSerializer *serializer = [AFJSONRequestSerializer serializer];
[serializer setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[serializer setValue:#"application/json" forHTTPHeaderField:#"Accept"];
manager.requestSerializer = serializer;
now it will work.
I encountered the same problem using AFNetworking API through Swift, trying to send a post request and finally got it work as well thanks to user1805458's post.
Basically, for my requestSerializer of the AFHTTPRequestOperationManager, I was also using AFHTTPRequestSerializer and then trying to set the Content-Type to "Application/JSON" and it did not work.
But once I switched to using AFJSONRequestSerializer instead, it works fine now:
let manager = AFHTTPRequestOperationManager()
manager.requestSerializer = AFJSONRequestSerializer(writingOptions: nil)
// Contrary to user1805458's solution, I did not need to use these two instructions below using Swift.
// manager.requestSerializer.setValue("Application/JSON", forHTTPHeaderField:"Content-Type")
// manager.requestSerializer.setValue("Application/JSON", forHTTPHeaderField:"Accept")
I hope it will help you to fix this error in case where you use Swift, AFNetworking and try to send a post request containing a JSON body.