I am trying to use AFHTTPRequestOperationManager to make an HTTP request. I need to use AFHTTPRequestOperationManager because I want to be able to cancel all operations if necessary. I can't get this working for some reason. The completion blocks aren't called. Am I missing something?
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"https://twitter.com/%#", username]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setValue:#"MyUserAgent (iPhone; iOS 7.0.2; gzip)" forHTTPHeaderField:#"User-Agent"];
[request setHTTPMethod:#"GET"];
[self.manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSString *html = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
if ([html containsString:#"var h = decodeURI(l.hash.substr(1)).toLowerCase();"]) {
completion(YES, nil);
} else {
completion(NO, nil);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
completion(NO, error);
}];
This is working code, you need to use GET or POST method there.
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *params = #{#"email":emailfield.text};
[manager GET:#"http://example.com/api" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
While everyone else is right -- you should be using the modern AFNetworking constructs instead of the legacy features -- there is a quick way to get done what you're looking to get done.
By the looks of it, the method - (??? *) HTTPRequestOperationWithRequest:success:failure likely returns an AFHTTPRequestOperation. If I'm correct, you just need to actually start the operation. See below for your code, corrected.
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"https://twitter.com/%#", username]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setValue:#"MyUserAgent (iPhone; iOS 7.0.2; gzip)" forHTTPHeaderField:#"User-Agent"];
[request setHTTPMethod:#"GET"];
AFHTTPRequestOperation *op = [self.manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSString *html = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
if ([html containsString:#"var h = decodeURI(l.hash.substr(1)).toLowerCase();"]) {
completion(YES, nil);
} else {
completion(NO, nil);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
completion(NO, error);
}];
[op start];
HTTPRequestOperationWithRequest method returns AFHTTPRequestOperation. You have to add it to some operation queue to start it. For example
AFHTTPRequestOperation *operation = [self.manager HTTPRequestOperationWithRequest:request .........
[[NSOperationQueue currentQueue] addOperation:operation];
You can use AFHTTPSessionManager which is a little better than AFHTTPRequestOperationManager and cancel requests using method cancel of NSURLSessionDataTask. You can find some code examples here - AFNetworking 2.0 cancel specific task
Check this will work
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:#"application/json", nil];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager POST:url parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
Related
I've implemented the JSON parsing using AFNetworking many time in some previous apps as:
NSString *string = [NSString stringWithFormat:#"%#?get_all_data", BaseURLString];
NSURL *url = [NSURL URLWithString:string];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
{
//performing parsing here
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//error message displayed here
}
But as of today I started working on an app after a while I came to use AFNetworking again and I installed in using pods so as I write this same code as I use to write before it gives me the error saying Unknown Receiver AFHTTPRequestOperation. Do you mean AFHTTPRequestSerializer?
After searching about it I found that it's AFNetworking 2 or 3 era now and they have somehow changed the scenerio. I didn't find the exact solution on how to implement it now. So can anyone write the code in the answer below that works with the latest version of AFNetworking.
This is the new approach of AFNetworking 3.x to parse data:
NSString *path = #"yourapilink";
NSString *escapedPath = [path stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager GET:escapedPath parameters:nil progress:nil success:^(NSURLSessionTask *task, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(NSURLSessionTask *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
Hope it help !
I'm using AFNetworking in my iOS project, and this is my code:
NSURL *url = [NSURL URLWithString: [signinUrl stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager POST:signinUrl parameters:dicParam success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSString *myString = [[NSString alloc] initWithData:operation.request.HTTPBody encoding:NSUTF8StringEncoding];
NSLog(#"Error: %#", myString);
}];
This code let to make connection with server correctly and I receive an answer, but I need to catch the code status with their description, I mean... catch something like that:
status_code: 406 custom message
I can get status code but it is an integer, anyone have idea how I can get this custom message?
I am trying to create a POST request by using AFNetworking library.
[self.manager POST:url parameters:parameters success:^(AFHTTPRequestOperation *operation, id response)
{
// CODE
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
// CODE
}];
Is there a way to post a simple string (not a JSON one) as a request body parameters by using AFNetworking?
Yes this is how you do it:
NSString *someString = #"SomeString";
NSData* stringData = [someString dataUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:#"someUrlString"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20];
[request setHTTPMethod:#"POST"];
[request setHTTPBody: stringData ];
AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
//Success Block
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//failure Block
}];
[op start];
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:.
I am updating an old application code which used ASIHTTPRequest with AFNetworking. In my case, I am sending a bench of data to API, these data are different types: Image and other.
Here is the code I adopt so far, implementing an API client, requesting a shared instance, prepare the params dictionary and send it to remote API:
NSMutableDictionary *params = [NSMutableDictionary dictionary];
[params setValue:#"Some value" forKey:aKey];
[[APIClient sharedInstance]
postPath:#"/post"
parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
//some logic
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//handle error
}];
What would be the case when I want to add an image to the params dictionary?
With ASIHTTPRequest, I used to do the following:
NSData *imgData = UIImagePNGRepresentation(anImage);
NSString *newStr = [anImageName stringByReplacingOccurrencesOfString:#"/"
withString:#"_"];
[request addData:imgData
withFileName:[NSString stringWithFormat:#"%#.png",newStr]
andContentType:#"image/png"
forKey:anOtherKey];
I digged into AFNetworking documentation and found they appending the image in an NSMutableRequest like this:
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
NSData *imageData = UIImageJPEGRepresentation([UIImage imageNamed:#"avatar.jpg"], 0.5);
NSMutableURLRequest *request = [httpClient multipartFormRequestWithMethod:#"POST" path:#"/upload" parameters:nil constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
[formData appendPartWithFileData:imageData name:#"avatar" fileName:#"avatar.jpg" mimeType:#"image/jpeg"];
}];
How should I mix this together on a neat way to integrate my image data into the APIClient request? Thanx in advance.
I have used same AFNetworking to upload image with some parameter. This code is fine working for me. May be it will help out
NSData *imageToUpload = UIImageJPEGRepresentation(uploadedImgView.image, 1.0);//(uploadedImgView.image);
if (imageToUpload)
{
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:keyParameter, #"keyName", nil];
AFHTTPClient *client= [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:#"http://------"]];
NSMutableURLRequest *request = [client multipartFormRequestWithMethod:#"POST" path:#"API name as you have" parameters:parameters constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
[formData appendPartWithFileData: imageToUpload name:#"image" fileName:#"temp.jpeg" mimeType:#"image/jpeg"];
}];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSDictionary *jsons = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:nil];
//NSLog(#"response: %#",jsons);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
if([operation.response statusCode] == 403)
{
//NSLog(#"Upload Failed");
return;
}
//NSLog(#"error: %#", [operation error]);
}];
[operation start];
}
Good Luck !!
With AFNetworking 2.0.1 this code worked for me.
-(void) saveImage: (NSData *)imageData forImageName: (NSString *) imageName {
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSString *imagePostUrl = [NSString stringWithFormat:#"%#/v1/image", BASE_URL];
NSDictionary *parameters = #{#"imageName": imageName};
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:#"POST" URLString:imagePostUrl parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:imageData name:#"image" fileName:imageName mimeType:#"image/jpeg"];
}];
AFHTTPRequestOperation *op = [manager HTTPRequestOperationWithRequest:request success: ^(AFHTTPRequestOperation *operation, id responseObject) {
DLog(#"response: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
DLog(#"Error: %#", error);
}];
op.responseSerializer = [AFHTTPResponseSerializer serializer];
[[NSOperationQueue mainQueue] addOperation:op];
}
If JSON response is needed use:
op.responseSerializer = [AFJSONResponseSerializer serializer];
instead of
op.responseSerializer = [AFHTTPResponseSerializer serializer];