AFNetworking: Create POST request, but not run - ios

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];

Related

AFNetworking POST method call

I am new to AFNetworking. How can i execute the success and failure blocks of the following
NSMutableDictionary *rus = [[NSMutableDictionary alloc] init];
[rus setValue:#"1211" forKey:#"id"];
[rus setValue:#"33" forKey:#"man"];
[[AFHTTPRequestSerializer serializer] requestWithMethod:#"POST" URLString:#"http://mysite.co/service.php" rus];
How to show the success or failure after executing the above code fragment.
requestWithMethod does not actually complete the call, it just returns you an NSMutableURLRequest. You need to take that request and make an AFHTTPRequestOperation. You can set a success/failure block on this object and then run the start method.
NSMutableDictionary *rus = [[NSMutableDictionary alloc] init];
[rus setValue:#"1211" forKey:#"id"];
[rus setValue:#"33" forKey:#"man"];
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] requestWithMethod:#"POST" URLString:#"http://mysite.co/service.php" parameters:rus];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
// Code for success
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//Code for failure
}];
[operation start];
All that being said, are you using an outdated version of AFNetworking? The method you're referencing is deprecated.
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
URLString:(NSString *)URLString
parameters:(id)parameters
error:(NSError *__autoreleasing *)error
Above is the correct method to use. You should pass in an error object.
Finally, an even easier way to accomplish what you're doing with AFNetworking 2.0 is below:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:#"http://mysite.co/service.php" parameters:rus success:^(AFHTTPRequestOperation *operation, id responseObject) {
// Code for success
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// Code for failure
}];
Try this code:
NSMutableDictionary *rus = [[NSMutableDictionary alloc] init];
[rus setValue:#"1211" forKey:#"id"];
[rus setValue:#"33" forKey:#"man"];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:#"http://mysite.co/service.php" parameters:rus success:^(AFHTTPRequestOperation *operation, id responseObject) {
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:#"http://mysite.co/service.php" parameters:rus success:^(AFHTTPRequestOperation *operation, id responseObject) {
// Code for success
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// Code for failure
}];
github's AFNetworking document
https://github.com/AFNetworking/AFNetworking

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 with parameters

i am really new to IOS developments..i just want to get some JSON response from my web service. when i searched about it i found AFnetworking is good for that. so i downloaded it and did a sample application. but i need to pass some parameters to the service . my service takes two parameters [username and password]. my url like this
http://myweb.mobile.com/WebServices/AppointmentService.asmx/GetValidUser
can anyone please give me some code sample how to pass my parameters to this service to get json response ?
i have tried this code.. but it wont take parameters.. some people telling about AFHTTPClient.. but im using AFN 2.0.. there is no class call AFHTTPCLient here .. i'm so conduced here....please help me
NSURL *url = [NSURL URLWithString:#"https://maps.googleapis.com/maps/api/place/textsearch/json?query=restuarants+in+sydney&sensor=false&key=AIzaSyDn9a-EvJ875yMxZeINmUP7CwbO9YT1w2s"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// 2
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
// 3
self.googlePlaces = [responseObject objectForKey:#"results"];
[self.tableView reloadData];
// NSLog(#"JSON RESULT %#", responseObject);
self.weather = (NSDictionary *)responseObject;
self.title = #"JSON Retrieved";
[self.tableView reloadData];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// 4
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error Retrieving Weather"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
}];
// 5
[operation start];
EDIT :
i have sloved my problem using below code segments...
NSDictionary *parameters = [[NSDictionary alloc] initWithObjectsAndKeys:#"47", #"caregiverPersonId", nil];
AFSecurityPolicy *policy = [[AFSecurityPolicy alloc] init];
[policy setAllowInvalidCertificates:YES];
AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];
[operationManager setSecurityPolicy:policy];
operationManager.requestSerializer = [AFJSONRequestSerializer serializer];
operationManager.responseSerializer = [AFJSONResponseSerializer serializer];
[operationManager POST:#"your full url goes here"
parameters:parameters
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", [responseObject description]);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", [error description]);
}
];
Try this
-(void)login
{
NSMutableDictionary *dict=[[NSMutableDictionary alloc]initWithCapacity:3];
[dict setObject:_usernameTextField.text forKey:#"userName"];
[dict setObject:_passwordTextField.text forKey:#"password"];
AFHTTPClient *client=[[AFHTTPClient alloc]initWithBaseURL:[NSURL URLWithString:#""]];
[client registerHTTPOperationClass:[AFJSONRequestOperation class]];
[client setDefaultHeader:#"Accept" value:#"application/json"];
client.parameterEncoding = AFJSONParameterEncoding;
[client postPath:#"GetValidUser" parameters:dict success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSDictionary *op=(NSDictionary *)responseObject;
NSLog(#"%#",op);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:MESSAGE_EN message:#"Unable to login. Please try again." delegate:self cancelButtonTitle:OK_EN otherButtonTitles:nil, nil];
[alert show];
NSLog(#"error.localizedDescription %#",error.localizedDescription);
}];
}
Note : Please do fill the fields with proper values and try.
dict is the Input postdata
I got this one from somewhere in SO question. See this:
- (IBAction)loginButtonPressed {
NSURL *baseURL = [NSURL URLWithString:#"http://myweb.mobile.com/WebServices/AppointmentService.asmx"];
//build normal NSMutableURLRequest objects
//make sure to setHTTPMethod to "POST".
//from https://github.com/AFNetworking/AFNetworking
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:baseURL];
[httpClient defaultValueForHeader:#"Accept"];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
[usernameTextField text], kUsernameField,
[passwordTextField text], kPasswordField,
nil];
NSMutableURLRequest *request = [httpClient requestWithMethod:#"POST"
path:#"http://myweb.mobile.com/WebServices/AppointmentService.asmx/GetValidUser" parameters:params];
//Add your request object to an AFHTTPRequestOperation
AFHTTPRequestOperation *operation = [[[AFHTTPRequestOperation alloc]
initWithRequest:request] autorelease];
//"Why don't I get JSON / XML / Property List in my HTTP client callbacks?"
//see: https://github.com/AFNetworking/AFNetworking/wiki/AFNetworking-FAQ
//mattt's suggestion http://stackoverflow.com/a/9931815/1004227 -
//-still didn't prevent me from receiving plist data
//[httpClient registerHTTPOperationClass:
// [AFPropertyListParameterEncoding class]];
[httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
[operation setCompletionBlockWithSuccess:
^(AFHTTPRequestOperation *operation,
id responseObject) {
NSString *response = [operation responseString];
NSLog(#"response: [%#]",response);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %#", [operation error]);
}];
//call start on your request operation
[operation start];
[httpClient release];
}
Hope this helps .. :)
EDIT
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:URLString parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFormData:[email dataUsingEncoding:NSUTF8StringEncoding]
name:#"email"];
[formData appendPartWithFormData:[pass dataUsingEncoding:NSUTF8StringEncoding]
name:#"password"];
// etc.
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Response: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
Use below code
NSDictionary *paramDictionary = [NSDictionary dictionaryWithObjectsAndKeys:#"first_Object",#"first_Key",#"second_Object",#"second_Key" nil];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:#"YOUR_URL_STRING" parameters:paramDictionary success:^(AFHTTPRequestOperation *operation, id responseObject) {Success responce} failure:^(AFHTTPRequestOperation *operation, NSError *error) {failure responce}];
if you want you can set
manager.responseSerializer = [AFJSONResponseSerializer serializer];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.securityPolicy.allowInvalidCertificates = YES;

How to migrate AFHTTPClient, Afnetworking 1.0 to 2.0

My problem is that I have a old code and I dont know how to change it.
I had 1 class called API (AFHTTPClient) I have problems with 2 methods because I dont know how to put them in 2.0:
This:
-(void)commandWithParams:(NSMutableDictionary*)params onCompletion:(JSONResponseBlock)completionBlock
{
NSMutableURLRequest *apiRequest =
[self multipartFormRequestWithMethod:#"POST"
path:kAPIPath
parameters:params
constructingBodyWithBlock: ^(id formData) {
//TODO: attach file if needed
}];
AFJSONRequestOperation* operation = [[AFJSONRequestOperation alloc] initWithRequest: apiRequest];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
//success!
completionBlock(responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//failure :(
completionBlock([NSDictionary dictionaryWithObject:[error localizedDescription] forKey:#"error"]);
}];
[operation start];
}
and this:
#pragma mark - init
//intialize the API class with the destination host name
-(API*)init
{
//call super init
self = [super init];
if (self != nil) {
//initialize the object
user = nil;
[self registerHTTPOperationClass:[AFJSONRequestOperation class]];
// Accept HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
[self setDefaultHeader:#"Accept" value:#"application/json"];
}
return self;
}
I do a new class called Api, now (AFHTTPRequestOperationManager) is good?
I try with this, but I dont have idea
-(API*)init
{//call super init
self = [super init];
//initialize the object
if (self != nil) {
//initialize the object
user = nil;
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
AFJSONRequestSerializer *a=[AFJSONRequestSerializer serializer];
[a setValue:#"Accept" forHTTPHeaderField:#"application/json"];
[a setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[a setValue:#"content-Type" forHTTPHeaderField:#"text/html"];
[a setValue : # "text / html; charset = UTF-8" forHTTPHeaderField : # "Content-Type" ];
}
return self;
}
-(void)commandWithParams:(NSMutableDictionary*)params onCompletion:(JSONResponseBlock)completionBlock
{
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = params;
NSURL *filePath = [NSURL URLWithString:#"http://162.243.199.147/mujeresquecorren/iReporter/index.php"];
[manager POST:#"api" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileURL:filePath name:#"api" error:nil];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
NSMutableURLRequest *apiRequest = [NSMutableURLRequest requestWithURL:filePath];
AFJSONRequestSerializer *requestSerializer = [AFJSONRequestSerializer serializer];
[requestSerializer setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[requestSerializer setValue:#"application/json" forHTTPHeaderField:#"Accept"];
// operationManagerInstance.requestSerializer = requestSerializer;
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]
initWithRequest:apiRequest];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager POST:#"http://162.243.199.147/mujeresquecorren/iReporter/index.php" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"%#", responseObject);
} failure:nil];
// AFJSONRequestOperation* operation = [[AFJSONRequestOperation alloc] initWithRequest: apiRequest];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
//success!
completionBlock(responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//failure :(
completionBlock([NSDictionary dictionaryWithObject:[error localizedDescription] forKey:#"error"]);
}];
[operation start];
}
and this is one of the errors:
rror: Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL" UserInfo=0xa64f980 {NSErrorFailingURLStringKey=api, NSErrorFailingURLKey=api, NSLocalizedDescription=unsupported URL, NSUnderlyingError=0xa782e10 "unsupported URL"}
Please help, im going to be crazy with that and I need that my code works in my app!
Thanks a lot!!!!
It's all there in the error message. "api" isn't a valid URL. You need to either specify an absolute URL, or initialize your request operation manager with a baseURL, using initWithBaseURL:.

AFNetworking 2.0 - mutable json

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/

Resources