I'm trying to pass an empty array as a parameter.
[self POST:#"offers.json" parameters:#{ #"offer": #{ #"key": [NSArray new] } } success:success failure:failure];
But AFNetworking cuts that parameter and didn't sent it.
Any help?
As I understand, it's common issue and not AFNetworking bug, this line of code helped me
sessionManager.requestSerializer = [AFJSONRequestSerializer serializer];
https://github.com/AFNetworking/AFNetworking/issues/1722
Related
I am using Afnetworking 3.1.0 for iOS app. My JSON response has a '_' (underscore) sing as bellow.
response --> {"_body":{"data":{"
Android app can serialize same response without any issue, which is using okhhtp3.
I suspect, AFJSONResponseSerializer is the culprit. I have tried as bellow to set acceptableContentType to AFJSONResponseSerializer. But does not work.
self.requestSerializer = [AFJSONRequestSerializer serializerWithWritingOptions:NSJSONWritingPrettyPrinted];
self.responseSerializer = [AFJSONResponseSerializer serializer];
self.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:#"application/json", #"text/json", #"text/javascript",#"text/html", nil];
Anyone has idea how to resolve this, please share.
Found the issue is not in AFNetworking. Problem is in the enumerateKeysAndObjectsUsingBlock method which I am using to construct a customize JSON from the response.
enumerateKeysAndObjectsUsingBlock is ignoring object inside an object.
I am new to AFNetworking and I know how to pass URL parameters. But how would I pass headers into the same call.
I am also subclassing my AFHTTPSessionManager
See my code below:
- (void)getExpenses:(NSString *)page
success:(void (^) (NSArray *myExpenses))success
failure:(RequestFailureBlock)failure
{
NSString *resourceURL = [NSString stringWithFormat:#"%#/expenses/", APIBaseURLString];
NSDictionary *parameters = #{#"page":page, #"Authorization": APIAuthorization};
[self getExpenses:resourceURL parameters:parameters success:success failure:failure];
}
setAuthorizationHeaderFieldWithToken is deprecated due to servers having different requirements about how the access token is sent (token, bearer, etc)
michaels answer otherwise is correct, use
[self.requestSerializer setValue:#"Some-Value" forHTTPHeaderField:#"Header-Field"];
or
[self.requestSerializer setAuthorizationHeaderFieldWithUsername:#"" password:#""];
for basic auth
You set header values on the requestSerializer property of AFHTTPSessionManager:
[self.requestSerializer setValue:#"Some-Value" forHTTPHeaderField:#"Header-Field"];
EDIT:
It looks like you're trying to set authorization; there is a method for that too:
[self.requestSerializer setAuthorizationHeaderFieldWithUsername:#"" password:#""];
// OR
[self.requestSerializer setAuthorizationHeaderFieldWithToken:#""];
If you need to set the Content-Type header, see this SO answer on how to do that
I am using the AFNetworking to connect to API in my code.
Now I have general things on my view controllers like switches and picker views which will determine what is sent to the API.
So I will need to call the AFNetworking block like this :
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:returncompletedURL];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
operation.responseSerializer.acceptableContentTypes = [NSSet setWithObject:#"text/html"];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
and at the end I use [operation start] to run the block, quite easy!
but I need this in some sort of a method/function so that I can call it and pass arguments over to it as and when a switch is changed or a label is changed. Instead of writing the same block over and over again i want it as a function.
I would use [operation start] in the function to check if a switch is on/off but it does not see it within the function.
If i wrap a method around the AFNetworking block would that bad and I cannot use the RETURN statement within a block.
Generally advice is needed if i have switches and labels and if the user changes any of this then the block needs to be called straight the way to amend the API call.
thanks
I could do something like this, create a method that can return for you value:
Method that you could insert your request.
-(void)callRequestWithParameter:(id)parameter returnState:(void(^)(id response))response{
// here make request
// use parameter to send what you want on request
if (requestSucess){
response(data for return our status);
}
};
//Method for handle request and answer
-(void)requestData:(id)dataParameter {
[ClassName callRequestWithParameter:#(2) returnState: (id response)^{
if(response){
// call some update method like
[self updateItensWithData:data];
}
}
};`
I followed the suggested solution at AFNetworking 2.0 add headers to GET request to specify custom headers for the request with the following code snippet:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager.requestSerializer setValue:someID forHTTPHeaderField:#"some_id"];
NSDictionary *parameters = #{#"id": user.id, #"birthday": user.birthday};
[manager POST:[NSString stringWithFormat:#"%#/user_create",BaseURLString] parameters:parameters
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
if (responseObject[#"error"])
{
NSLog(#"REST User Create Response Error: %#", responseObject[#"error"]);
}
else
{
[self saveUserDetails:responseObject];
}
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"REST User Create Error: %#", error);
}];
But what happens when this gets executed is I get an error in the response from the API stating all my parameters are missing. This same block of code used to work before (without setting the custom header and when the API didn't require them originally).
Does anybody know how to properly set both custom headers and POST parameters?
Thanks,
Nino
Your code looks fine to me.
A few things to try:
Try using AFNetworkActivityLogger to see what's actually being sent (set it to AFLoggerLevelDebug.) You can also use a web proxy like Charles or a protocol analyzer like Wireshark.
If you determine the data is not being sent properly, set a breakpoint in [AFURLRequestSerialization -requestBySerializingRequest:withParameters:error:]. This is where your HTTP headers and parameters are added to the URL request. The method is pretty straightforward; you should be able to step through and watch as stuff is added to the request and determine why it gets skipped.
NOTE: AFURLRequestSerialization.m contains multiple subclasses of AFURLRequestSerialization. Set a breakpoint in the super implementation, as well as in the AFJSONRequestSerializer implementation.
Examples that could cause this behavior:
parameters is nil.
you've added POST to HTTPMethodsEncodingParametersInURI but
your API is not prepared to handle parameters appended to a URL on a POST request, or
the queryStringSerialization block is nil AND queryStringSerializationStyle is set to something other than AFHTTPRequestQueryStringDefaultStyle.
NSJSONSerialization can't handle your parameters dictionary
One side note (unrelated to your problem), if you use AFHTTPRequestOperationManager's initWithBaseURL: method, and keep a strong reference to your manager, you won't have to do that [NSString -stringWithFormat:] stuff to construct your URL.
I discovered that I should have set my request serializer to the following instead since my API doesn't require JSON-formatted parameters.
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
Hope this helps others dealing with the same situation as mine.
I'm trying to post an image with a parameter (categories) that is an array. If I leave this parameter out, I can submit fine. However, if I leave it in, my server throws an error because the array value doesn't seem to be getting serialized correctly.
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:#{
#"auth_token" : authToken,
#"title" : title,
#"categories" : #[1,2,3]
}];
return [[MyHTTPSessionManager sharedManager] POST:path parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:imageData
name:#"image"
fileName:#"image.jpg"
mimeType:#"image/jpeg"];
} success:nil failure:nil];
Looking at my server logs, this is how categories is coming across:
Parameters: {"categories"=>"(\n 1,\n 2,\n 3\n)", … }
And I need it to look like:
Parameters: {"categories"=>[1,2,3], … }
I've tried setting my instance of AFHTTPSessionManager's requestSerializer to [AFJSONRequestSerializer serializer] but that doesn't seem to help.
How can I properly POST an image + parameters? I'd like to avoid falling back to AFHTTPRequestOperation.
Thanks!
Try upgrading to the newest version of AFNetworking. I believe this was fixed in github.com/AFNetworking/AFNetworking/issues/1388, which I think was rolled into AFNetworking 2.0.1. If the newest version doesn't work, just pull the latest commit.