AFNetworking caching Image without displaying it in ImageView in Swift - ios

I understand that AFNetworking has a function that caches an image as it is loaded to an ImageView.
However, I want to cache the Image without displaying it in an ImageView and I was unable to find any functions for that.

Use [NSBundle mainBundle] resourcePath] to get cache path then use NSFileManager and write file/object/doc etc.

Something like (Objective C not Swift - but you get the idea)
AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest];
requestOperation.responseSerializer = [AFImageResponseSerializer serializer];
[requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
[self savePNGImage:responseObject withFilename:imageUrl];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"%#", [error description]);
}];
[requestOperation start];
Implement savePNGImage to save your image locally.

Related

Download folder using AFNetworking in ios

I would like to download a folder which consists several kind of files(png,jpg,mov,txt and pdf). I am using AFNetworking. I have used below code for downloading,
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[Utilities urlencode:imageURL]]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:str_path append:NO];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
{
//NSLog(#"Successfully downloaded file to %#", str_path);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"Error: %# =====%# =======%#", error.localizedDescription,str_path,imageURL);
}];
[operation setDownloadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToRead)
{
float progress = totalBytesWritten / (float)totalBytesExpectedToRead;
NSLog(#"Download Percentage: %f %%", progress*100);
}];
[operation start];
The above code works fine for individual files. But i have got error code of 21 while downloading folder. Any help would be greatly appreciated.
HTTP does not support downloading multiple files in one request. This is pretty much the same question asked here in reverse.
If you have FTP access you can use the CFFTP API to download the contents of a directory.

AFNetworking and downloading images

I want to know is there way to download images with my code one by one ? Now async
NSString *urlString = link;
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest];
requestOperation.responseSerializer = [AFImageResponseSerializer serializer];
[requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
completion(operation, responseObject, nil);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[RequestAPI sharedInstance].downloadsCount -= 1;
DDLogError(#"FAIL download image: %#",error);
}];
[requestOperation start];
Try this solution
Create a NSObject class for downloading the images. Lets call this DownloadImages. The class has an array of images to be downloaded arrayOfImagesURL.
Create a delegate for the class DownloadImages to make a call back when you finish downloading an image. View how to this in detail here.
Implement AFNetworking as you like, you can also accomplish this by using the iOS 7 API NSURLSession. So in the completion block of your download task, you need to do 2 things:
Continue downloading the next URL in arrayOfImagesURL.
Do a call back with the delegate to the parent controller for processing.
Tell me if there's something need to be more clarify.

iOS: manage a AFHTTPRequestOperationManager

In my app I should download some JSON files, then I store these URL in a plist as you ca see in my code. After I create an 'AFHTTPRequestOperationManager' and I create a loop where I add some operation for the numbers of my 'url_list'.
NSString* plistPath = [[NSBundle mainBundle] pathForResource:#"url_json" ofType:#"plist"];
NSArray *url_list = [NSArray arrayWithContentsOfFile:plistPath];
self.manager = [AFHTTPRequestOperationManager manager];
for (id element in url_list){
NSURL *url = [NSURL URLWithString:element];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
op.responseSerializer = [AFHTTPResponseSerializer serializer];
[op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[self.manager.operationQueue addOperation:op];
}
Now this code should be fine, but I want to have two information:
what's the way to know the progress value of my 'manager'?, because I want to know the state of all operation in a single progress value
I want to know when an operation finish, because when an operation finish I should pass 'responseObject' to a method that parse this data
Can you help me?
Take a look at AFNetworking batching documentation:
https://github.com/AFNetworking/AFNetworking#batch-of-operations
It gives you an option to assign progress block which is called on single operation completion and on top of that you can assign completion block which will be called when all operations are completed.
If you need you can still assign completion block to single operation to parse responseObjects.

How to create block with patameters? ios7 [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 8 years ago.
Improve this question
I create block like this:
1) Define your own completion block,
typedef void(^myCompletion)(BOOL);
2) Create a method which takes your completion block as a parameter,
-(void) myMethod:(myCompletion) compblock{
//do stuff
compblock(YES);
}
3)This is how you use it,
[self myMethod:^(BOOL finished) {
if(finished){
NSLog(#"success");
}
}];
How can I send array in block and then get new array from block?
//here I get array of image id's and go in loop for download it all,
NSString *URLString = [NSString stringWithFormat: #"%#", requestString];
NSURL * url = [NSURL URLWithString:URLString];
NSURLRequest * urlRequest = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest];
requestOperation.responseSerializer = [AFImageResponseSerializer serializer];
[requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
userWithImage = [responseObject copy];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Image error: %#", error);
}];
[requestOperation start];
//here I save it to mutable array and send as completion block,
yep, I think it will be better to send 1 image id and return in block 1 image. And in method there I will call the block - make action with photo separately. so, Is it possible to do?
I can do something like this with NSNotifications, but it will be more widely when it can be in blocks..
1) Define your own completion block
typedef void(^myCompletion)(BOOL finished, NSArray *myArray);
2) Create a method which takes your completion block as a parameter,
-(void)myMethod:(myCompletion)compblock {
//do stuff
NSArray *myArray = ...;
compblock(YES, myArray);
}
3)This is how you use it,
[self myMethod:^(BOOL finished, NSArray *myArray) {
if (finished){
NSLog(#"success");
}
}];
If you just want to write a wrapper around the AFNetworking request you could write a method like this:
- (void)downloadImageWithPath:(NSString *)path completion:(void (^)(AFHTTPRequestOperation *operation, UIImage *image, NSError *error))completion __attribute__((nonnull(2)));
{
NSParameterAssert(completion);
NSURL *url = [NSURL URLWithString:path];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest];
requestOperation.responseSerializer = [AFImageResponseSerializer serializer];
[requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
completion(operation, responseObject, nil);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
completion(operation, nil, error);
}];
[requestOperation start];
}
You would invoke this with something like:
[self downloadImageWithPath:#"http://url/to/image.jpg"
completion:^(AFHTTPRequestOperation *operation, UIImage *image, NSError *error) {
if (error) {
// handle error
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
// Update UI with image
});
}];

Moving to the next View Controller after Authenticating

I am using AFnetworking for authentication, but after Authenticating user I need to move to the next View controller. It's moving, but also it moves when there's an error too. How can I make use of the responseObject in AFNetworking to my need...... Below is my CODE
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
//[operation setCredential:credential];
[operation setResponseSerializer:[AFJSONResponseSerializer alloc]];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
//This is where if the response is successful it should move
if ([responseObject objectForKey:#"Success"]) {
MainView *home = [self.storyboard instantiateViewControllerWithIdentifier:#"MainViewController"];
[self.navigationController pushViewController:home animated:YES];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failure: %#", error);
}];
[manager.operationQueue addOperation:operation];
To check if success or not, you are using :
if ([responseObject objectForKey:#"Success"])
I don't know your service and the retrieve Diccionary, however I think you always have an object for the key #"Success", and because #"Success" exists is passing in all the scenarios.
Try to check the value, e.g.:
if ([[responseObject objectForKey:#"Success"] isEqualsToString #"ok"])

Resources