AFNetworking 2.0 - mutable json - ios

My code currently looks like this
NSURL *URL = [NSURL URLWithString:URLForSend];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]
initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"%#", responseObject);
[BoxJsonDataHelper gotNewJson:responseObject];
} failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"Request Failure Because %#",[error userInfo]);
}];
[operation start];
But when trying to edit dictionaries in object received, I get an error about using methods that belongs to a mutable dictionary rather than a dictionary.
How do I make AFNetworking use nested mutable objects instead?

You tell the AFJSONResponseSerializer that it needs to return mutable containers:
operation.responseSerializer =
[AFJSONResponseSerializer serializerWithReadingOptions: NSJSONReadingMutableContainers]
It is all very well documented: http://cocoadocs.org/docsets/AFNetworking/2.0.0/

Related

How to use the response object of AFHTTPRequestOperation?

I want to use the response object of AFHTTPRequestOperation outside of the success block. Here is my code below:
NSMutableArray *arr = [[NSMutableArray alloc] init];
NSURL *URL = [NSURL URLWithString:#"my_url"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLCredential *credential = [NSURLCredential credentialWithUser:#"user" password:#"pass" persistence:NSURLCredentialPersistenceNone];
AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[op setCredential:credential];
op.responseSerializer = [AFJSONResponseSerializer serializer];
[op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
for(NSDictionary *item in responseObject){
[arr addObject:item];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[[NSOperationQueue mainQueue] addOperation:op];
NSLog(#"%#",arr);// here arr getting null or empty
I am getting the response object fine but if I want to use responseObject outside of the success block then object gets null.
Can anybody help me?

Get value out of setCompletionBlockWithSuccess block

I want to get some data from web service and it works fine bu now I want to store the returned value from a variable from a block, but the variable's value is changed only inside the block and it returns null outside the block, how can I do it ? here is my code:
-(void)getDataFromServer:(NSString *) urlString{
__block id returnedData;
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSURLCredential *credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistenceNone];
NSMutableURLRequest *request = [manager.requestSerializer requestWithMethod:#"GET" URLString:urlString parameters:nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCredential:credential];
[operation setResponseSerializer:[AFJSONResponseSerializer alloc]];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
// NSLog(#"Success: %#", responseObject);
returnedData = responseObject;
NSLog(#"returned data%#" , returnedData); // here returnedData contains the value that I need to store
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failure: %#", error);
} ];
[manager.operationQueue addOperation:operation];
NSLog(#"returned data%#" , returnedData); // here it returns null value !!
}
The problem is not with access to the variable, it is with the timing.
Your second NSLog statement is running before the completion block is run. The operation runs asynchronously, and you're logging returnedData before it is set in the completion block.
Edit to add an example solution:
One solution would be to create the completion block in your calling class and past into the operation in the getDataFromServer: method.
- (void)getDataFromServer:(NSString *)urlString completion:(void (^)(AFHTTPRequestOperation *operation, id responseObject))completion {
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSURLCredential *credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistenceNone];
NSMutableURLRequest *request = [manager.requestSerializer requestWithMethod:#"GET" URLString:urlString parameters:nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCredential:credential];
[operation setResponseSerializer:[AFJSONResponseSerializer alloc]];
[operation setCompletionBlockWithSuccess:completion];
[manager.operationQueue addOperation:operation];
}

AFNetworking 2.0 and GET Request parameters

I have a question about AFNetworking 2.0
I have to make a GET request like this:
http://myhost.come/entity?language=en&query=$UserId=14 and $EntityCreationDate>'2014-09-01'
How to generate the Dictionary parameters for this request?
In particular I not understand how can I build this: and $EntityCreationDate>'2014-09-01'
Here I found a good tutorial.
Which states a simple GET request can be sent like this:
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:#"http://samwize.com/"]];
NSMutableURLRequest *request = [httpClient requestWithMethod:#"GET"
path:#"http://samwize.com/api/pigs/"
parameters:nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
// Print the response body in text
NSLog(#"Response: %#", [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[operation start];

AFNetworking: Create POST request, but not run

I'm trying to create POST request in AFNetworking 2.0:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
AFHTTPRequestOperation *operation = [manager POST: requestURL parameters:params
success:^(AFHTTPRequestOperation *operation, id responseObject) {
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
But how I can create AFHTTPRequestOperation without executing it immediately?
( I need to add this operation to NSOperationQueue )
UPDATE:
Thanks! I ended up with such solution:
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] requestWithMethod: #"POST" URLString: #"website" parameters: params error: nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
[operation start]; // or add operation to queue
Straight from the docs
NSURL *URL = [NSURL URLWithString:#"http://example.com/foo.json"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"%#", responseObject);
} failure:nil];
[operation start];
Edit
If you want to submit this operation to NSOperationQueue, you can use AFHTTPRequestOperationManager as follows
requestManager = [AFHTTPRequestOperationManager manager];
// instead of [operation start]
[requestManager.operationQueue addOperation:operation];
The best way to add something to an NSOperationQueue is to subclass NSOperation.
There are tutorials all over the place... First example I found with a Google search.
You subclass might be called MyPostOperation.
And it has the single task of running your POST request.
It then gets managed and run by your NSOperationQueue.
Try this
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer]
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"%#", responseObject);
} failure:nil];
// Add the operation to a queue
// It will start once added
NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
[operationQueue addOperation:operation];

AFNetworking 2.0 JSON Parse [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Here is my code.
(void)performHttpRequestWithURL :(NSString *)urlString :(NSMutableArray *)resultArray completion:(void (^)(NSArray *results, NSError *error))completion
{
NSURL *myUrl = [NSURL URLWithString:urlString];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:myUrl cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"请求完成");
NSArray *arr;
arr = [NSJSONSerialization JSONObjectWithData:operation.responseData options:NSJSONReadingAllowFragments error:NULL];
[resultArray addObjectsFromArray:arr];
if (completion) {
completion(resultArray, nil);
}
}failure:^(AFHTTPRequestOperation *operation, NSError *error){
NSLog(#"请求失败: %#", error);
if (completion) {
completion(nil, error);
}
}];
[operation start];
}
I can only use apple json parse, I don't know how to use AFNetworking json parse itself.
I didn't find AFJsonrequestOperaton in AFNetworking 2.0.ask for help, thank you.
For AFNetworking 2.0 below sample code works:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = #{#"UserId": #"24",#"Name":#"Robin"};
NSLog(#"%#",parameters);
parameters = nil; // set to nil for the example to work else you can pass data as usual
// if you want to sent parameters you can use above code
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager POST:#"http://maps.google.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=false" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"JSON: %#", responseObject);
}failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"Error: %#", error);
}];
No need to do it manually, just set the response serializer to JSON like this:
....
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
and now inside your block, responseObject should be the deserialised object (NSDictionary or NSArray depending on your root JSON object from the response)
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Hooray, we got %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error){
NSLog(#"Oops, something went wrong: %#", [error localizedDescription]);
}];
[operation start];

Resources