I'm using this code when downloading images in one of my current projects and it's not working with AFNetworking 2.0. I tried going thru AFImageResponseSerializer but I can't find the right code to use.
[cell.posterImage setImageWithURLRequest:urlRequest placeholderImage:[UIImage imageNamed:#"placeholder.png"] success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
cell.posterImage.image = image;
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
NSLog(#"Request failed with error: %#", error);
}];
Any suggestions on the new code used in AFNetworking 2.0? Thanks!
I made it work using this code:
AFHTTPRequestOperation *posterOperation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest];
posterOperation.responseSerializer = [AFImageResponseSerializer serializer];
[posterOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Response: %#", responseObject);
_posterImageView.image = responseObject;
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Image request failed with error: %#", error);
}];
[[NSOperationQueue mainQueue] addOperation:posterOperation];
[posterOperation start];
But I got into another problem with placeholder images using this. Any ideas?
You're looking for UIImageView (AFNetworking) category.
#import "UIImageView+AFNetworking.h"
//...
[cell.posterImage setImageWithURLRequest:urlRequest placeholderImage:[UIImage imageNamed:#"placeholder.png"] success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
cell.posterImage.image = image;
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
NSLog(#"Request failed with error: %#", error);
}];
cell.posterImage must be an UIImageView not an UIImage.
With the updated AFNetworking 2.0 (in case your files are accessible for download-only basis, so are not accessible by a simple URL) :
NSString * methodURL = #"http://www.yourserver.com/pathToImageDownloadMethod";
NSInteger someIDYouHaveOfAnImage = 13;
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFImageResponseSerializer serializer];
NSDictionary * parameterDictionary = #{#"Parameter" : [NSNumber numberWithInteger:someIDYouHaveOfAnImage]};
[manager GET:methodURL parameters:parameterDictionary success:^(AFHTTPRequestOperation *operation, id responseObject) {
if ([responseObject isKindOfClass:[UIImage class]]) {
UIImage * image = responseObject;
// Here is your image object
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"failure getting the file : %#", error.localizedDescription);
}];
Hope it helps.
https://github.com/AFNetworking/AFNetworking/archive/master.zip is including UIKit+AFNetworking directory
Related
So I am working on a project and I must use AFImageDownloader in order to download some images that we need to use in our project. I use the following code:
-(void) downloadImage:(NSURL*) url
{
AFHTTPSessionManager *sessionManager = [[AFHTTPSessionManager alloc] init];
AFImageDownloader *imgDownloader = [[AFImageDownloader alloc] initWithSessionManager:sessionManager downloadPrioritization:AFImageDownloadPrioritizationFIFO maximumActiveDownloads:1 imageCache:nil];
AFHTTPResponseSerializer *responseSerializer = [AFHTTPResponseSerializer serializer];
responseSerializer.acceptableContentTypes = [NSSet setWithObjects:#"application/json", #"text/json",#"binary/octet-stream",nil];
sessionManager.responseSerializer = responseSerializer;
NSURLRequest *req = [NSURLRequest requestWithURL:url];
[imgDownloader downloadImageForURLRequest:req success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *responseObject){
self.image = responseObject;
[self.delegate updateImageWithImage:self.image]; // ** CRASH **
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error){
NSLog(#"Error");
}];
}
The delegate is of course not nil and code of the updateImageWithImage is:
-(void) updateImageWithImage:(UIImage*) img {
self.image.image = img;
}
So basically when I try to get the UIImage I get it as a response and assign it to the UICollectionViewCell and it crashes! I guess that I should do some kind of "copy" of the responseObject before using it in order parts of my program, but I am not really sure what the problem is. Any ideas?
I figured it out. I was basically using AFImagedownloader wrong, this is the proper way to use this Class:
[self.imageView setImageWithURLRequest:jpegURLRequest
placeholderImage:placeholder
success:^(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image){
NSLog(#"Success");
completionBlock(image);
}
failure:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, NSError * _Nonnull error) {
NSLog(#"ERROR!!!");
}];
I'm a newbie in iOS development and I'm trying to figure out how to send GET request with AFNetworking.
I used the example provided in Tutorial on Using AFNetworking 2.0 and placed it in main expecting a error:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:#"http://samwize.com/api/poos/"
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
...and I've got nothing, so I tried to point to the webservice that returns a valid JSON and also got nothing. Why none of blocks (success or failure) are executed?
Your code does not execute blocks (success or failure) beacause somthing went wrong.
but if you use try catch block then it will go into catch block try once.
code:
try {
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:#"http://samwize.com/api/poos/"
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
}#catch (NSException *exception) {
**// you will get error here**
}
Use following function and just send your URL in Argument
- (void)callWebservice : (NSString *)strURL{
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL urlWithEncoding:strURL]];
[httpClient registerHTTPOperationClass:[AFJSONRequestOperation class]];
[httpClient setDefaultHeader:#"Accept" value:#"application/json"];
[httpClient setParameterEncoding:AFJSONParameterEncoding];
NSMutableURLRequest *request = [httpClient requestWithMethod:#"GET" path:#"" parameters:nil];
[request setTimeoutInterval:180];
[AFJSONRequestOperation addAcceptableContentTypes:[NSSet setWithObject:#"text/html"]];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON)
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSLog(#"Success");
} failure:^ (NSURLRequest *request, NSURLResponse *response, NSError *error, id json){
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSLog(#"Failure");
}];
[GlobalManager setOperationInstance:operation];
[operation start];
}
It was strange, I just created another project (iOS instead of OSX) and called the same code from the IBAction and it worked easily. In Podfile I specified a new version of AFNetworking (2.5 instead of 2.4). I don't know if this is relevant.
Thank you everyone for trying to help me.
Try following code to do that.
#try {
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager GET:stringURL parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject){
NSLog(#"JSON: %#", responseObject);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
}
#catch (NSException *exception) {
NSLog(#"Exception - %#", [exception debugDescription]);
}
#finally {
}
And make sure you have a valid JSON.
How to post a image using AFNetworking.i am using below code to post an image.but image is not uploading to server.After posting image i am getting this link in result "http://thisisswitch.com:8084/SmartSwitchService/UserImages/69684177-4601-4665-8890-5424e3fbff73.png".
Can anyone tell me what the problem in code ?
Here is my Code:
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:BaseUrl]];
NSMutableURLRequest *request = [httpClient multipartFormRequestWithMethod:#"POST" path:posturl parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFormData:imgData name:#"image"];
}];
[httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSDictionary *dict = (NSDictionary *)JSON;
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
}];
[operation start];
From the Github read me:
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURL *URL = [NSURL URLWithString:#"http://example.com/upload"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURL *filePath = [NSURL fileURLWithPath:#"file://path/to/image.png"];
NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request fromFile:filePath progress:nil completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
NSLog(#"Error: %#", error);
} else {
NSLog(#"Success: %# %#", response, responseObject);
}
}];
[uploadTask resume];
Here's how I'm doing it (in AFNetworking 2.x):
- (void)requestWithFormData:(void (^)(id <AFMultipartFormData> formData))formBlock
withParams:(NSDictionary *)params
webservicePath:(NSString *)webservicePath
success:(void (^)(AFHTTPRequestOperation *operation, id jsonDictionary))successBlock
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failureBlock
{
// Handle request for file upload
AFHTTPRequestOperation *op = [self.manager POST:webservicePath
parameters:params
constructingBodyWithBlock:formBlock
success:success
failure:failureBlock];
[op start];
}
Then I use it as per the following:
void (^formBlock)(id <AFMultipartFormData> formData) = ^(id <AFMultipartFormData>formData)
{
NSData *data1 = UIImagePNGRepresentation(profileImage);
[formData appendPartWithFileData:data1 name:#"file" fileName:#"picture.png" mimeType:#"image/png"];
};
[networkingUtil requestWithFormData:formBlock
withParams:params
webservicePath:#"myserver.com/upload"
success:successBlock
failure:failureBlock];
Your server should handle the form data and look for file.
I'm trying to add a photo to a POST using the AFNetworking 2.0.
This ios App sends a post an a photo to a blog.
I can'f figure out why the images don't load.
Here is what I got so far:
// publish text and image
-(void)publishTextAndImage:(NSString*)resultDisplay and:(NSString*)subject with:(NSString*)nonce
{
imageData = UIImageJPEGRepresentation(selectedImage, 0.7); // create a data object from selected image
NSString *myUUID = [[NSUUID UUID] UUIDString]; // create a UUID
NSString *formatString = [NSString stringWithFormat:#"<img src=\"/wp-content/uploads/%#\"/>",myUUID];
NSString *contentString = [formatString stringByAppendingString:resultDisplay];
NSString *moodString = [NSString stringWithFormat:#"%d",self.moodNumber];
NSDictionary *parameters = #{#"title":subject,
#"content":contentString,
#"status":#"publish",
#"author":#"wordpress",
#"user_password":#"xrayyankee",
#"nonce":nonce,
#"categories":moodString,
#"attachment":#"image/jpeg"};
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:#"http://thrills.it/?json=posts/create_post"
parameters:parameters
constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
{
if (selectedImage)
{
[formData appendPartWithFileData:imageData name:#"photo" fileName:myUUID mimeType:#"image/jpeg"];
}
}
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"JSON: %#", responseObject);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"Error: %#", error);
}];
}
Thanks a bunch
I use the AFNetworking in this way :
AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:#"http://thrills.it/?json=posts"]];
NSURLRequest *request = [client multipartFormRequestWithMethod:#"POST" path:#"create_post" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
{
if (selectedImage)
{
[formData appendPartWithFileData:imageData name:#"photo" fileName:myUUID mimeType:#"image/jpeg"];
}
} ];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON)
{
NSLog(#"JSON: %#", responseObject);
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
NSLog(#"Error: %#", error);
}];
[operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
float progressValue = (float)((double)totalBytesWritten/(double)totalBytesExpectedToWrite);
NSLog(#"%f", progressValue);
}];
[self.queue addOperation:operation];
.
#property (nonatomic, strong) NSOperationQueue *queue;
My client is created earlier but it's created like that.
I hope that will help.
I got it, the code was fine it was an issue with the naming of the parameters, here it is:
// publish text and image
-(void)publishTextAndImage:(NSString*)resultDisplay and:(NSString*)subject with: (NSString*)nonce
{
imageData = UIImageJPEGRepresentation(selectedImage, 0.7); // create a data object from selected image
NSString *myUUID = [[NSUUID UUID] UUIDString]; // create a UUID
NSString *formatString = [NSString stringWithFormat:#"<img src=\"/wp- content/uploads/%#\"/>",myUUID];
NSString *contentString = [formatString stringByAppendingString:resultDisplay];
NSString *moodString = [NSString stringWithFormat:#"%d",self.moodNumber];
NSDictionary *parameters = #{#"title":subject,
#"content":contentString,
#"status":#"publish",
#"author":#"wordpress",
#"user_password":#"xrayyankee",
#"nonce":nonce,
#"categories":moodString};
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:#"http://thrills.it/?json=posts/create_post"
parameters:parameters
constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
{
if (selectedImage)
{
[formData appendPartWithFileData:imageData name:#"attachment" fileName:myUUID mimeType:#"image/jpeg"];
}
}
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"JSON: %#", responseObject);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"Error: %#", error);
}];
so basically I removed the "attachment" parameter from the parameters dictionary and changed the name of the appended imageData to #"attachment". it was an issue of wordpress json api being very picky (:
I am implementing a code that downloads images and saves them in the database of the app,
I have an array of objects, each object contains the image url and some other information. To Download the images I'm using the class library AFImageRequestOperation.h AFNetworking.
My code downloads and saves the data in the database, but need to notify the user which image is downloaded, eg: if I have an array containing 5 objects (quoted just above what each object), will have to do downloading the same order that is in the array, but as AFImageRequestOperation makes downloading asynchronously item 4 can be downloaded before the first item.
In short, I want to have control and only release for the next download when the previous one is completed.
I have a for that runs through the array of objects and calls a function for each position, the function has the following code:
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[arrImagem valueForKey:#"urlimagem"]]];
AFImageRequestOperation *operation = [AFImageRequestOperation imageRequestOperationWithRequest:request imageProcessingBlock:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image){
Imagens *imagem = (Imagens *)[NSEntityDescription insertNewObjectForEntityForName:#"IMAGENS" inManagedObjectContext:managedObjectContext];
// Save Image
NSData *imageData = UIImageJPEGRepresentation(image, 90);
[imagem setCategoria:cat];
[imagem setTitulo:[arrImagem valueForKey:#"titulo"]];
[imagem setDescricao:[arrImagem valueForKey:#"descricao"]];
[imagem setImagem:imageData];
NSError *error;
if(![managedObjectContext save:&error]){
NSLog(#"houve um erro muito grave");
//return false;
}else{
NSLog(#"Salvou imagem");
}
}failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error){
NSLog(#"%#", [error localizedDescription]);
}];
[operation start];
I do not know if my question was very clear, but basically my question is similar to this link
AFImageRequestOperation is a subclass of NSOperation so you can use:
- (void) addDependency: (NSOperation*) operation
to make sure that one operation finishes before the other.
For example:
NSOperation *op1 = [[NSOperation alloc]init];
NSOperation *op2 = [[NSOperation alloc]init];
[op1 addDependency: op2];
This way op1 won't start before op2 is finished.
You can create a method in your class where you call the download code and add a block as parameter which receives the downloaded UIImage, the image url (and other infos that you need) or you can implement a delegate with the same params from the block. It can lock something like:
-(void)downloadImageWithSuccess:(void (^)(UIImage *image, NSString *url, OtherParms here))success
failure:(void (^)(NSError *error)failure {
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[arrImagem valueForKey:#"urlimagem"]]];
AFImageRequestOperation *operation = [AFImageRequestOperation imageRequestOperationWithRequest:request imageProcessingBlock:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image){
Imagens *imagem = (Imagens *)[NSEntityDescription insertNewObjectForEntityForName:#"IMAGENS" inManagedObjectContext:managedObjectContext];
// Save Image
NSData *imageData = UIImageJPEGRepresentation(image, 90);
[imagem setCategoria:cat];
[imagem setTitulo:[arrImagem valueForKey:#"titulo"]];
[imagem setDescricao:[arrImagem valueForKey:#"descricao"]];
[imagem setImagem:imageData];
NSError *error;
if(![managedObjectContext save:&error]){
NSLog(#"houve um erro muito grave");
//return false;
}else{
NSLog(#"Salvou imagem");
}
success(imagem, [request.URL absoluteString], otherParams);
}failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error){
NSLog(#"%#", [error localizedDescription]);
failure(error);
}];
[operation start];
}
}
And when you call the method from your code you can do something like(using blocks):
[catalog downloadImageWithSuccess:^(UIImage *image, NSString *url, OtherParms here) {
//NOTIFY USER THAT THE IMAGE WITH URL HAS BEEN DOWNLOADED
}
failure:^(NSError *error) {
//NTOFIY USER THAT THE IMAGE FAILED
}
];
managed to solve my problem, sorry for the delay in posting the solution, follow the code below:
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:strUrl]];
AFImageRequestOperation *operation = [AFImageRequestOperation imageRequestOperationWithRequest:request imageProcessingBlock:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image){
//your implementation
dispatch_group_leave(group); //<== NOTICE THIS
}failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error){
//your implementation
NSLog(#"%#", [error localizedDescription]);
}];
[operation start];
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
Thus the downloads ocorerão in order, if this code is inside a case, the next download will only be called when the method success^: or failure^: is called