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.
Related
I have trying to download the multiple .mp3 files from a server at time. One complete audio file is divided into 286 parts. I fetch all the urls of the file and now I want to download 286 files. I search a lot but many library stop downloading when I go back to previous controller and if user minimize the app the downloaded stop. Is there any library which can manage multiple downloads and download didn't stop when user go back to previous controller of minimize the app.
I am using Download Manager library but I can't get my desired. Please give me the solution. I am stuck with that from 3 days . Please tell me the solution . Thanks
In my project I'm using AFNetwirking. You can create a singleton object, and here is my method (for example) for downloading files :
- (AFHTTPRequestOperation *)performDownloadWithURLString:(nonnull NSString *)urlString
destinationPath:(NSString *)destinationPath
progress:(void (^)(long long bytesRead, long long totalBytesToRead))progress
apiCallback:(void(^)(BOOL isSuccessful, id object))apiCallback
{
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
NSString *fullPath = [[FCFileManager pathForTemporaryDirectory] stringByAppendingPathComponent:[url lastPathComponent]];
[operation setOutputStream:[NSOutputStream outputStreamToFileAtPath:fullPath append:NO]];
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead)
{
if(progress) {
progress(totalBytesRead, totalBytesExpectedToRead);
}
}];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if(destinationPath && [FCFileManager isFileItemAtPath:destinationPath]) {
NSError *removeError;
[FCFileManager removeItemAtPath:destinationPath error:&removeError];
}
if(destinationPath) {
[FCFileManager moveItemAtPath:fullPath toPath:destinationPath];
}
dispatch_async(dispatch_get_main_queue(), ^{
if(apiCallback) {
apiCallback(YES, destinationPath ?: fullPath);
}
});
});
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSError *removeError;
[FCFileManager removeItemAtPath:fullPath error:&removeError];
if(apiCallback) {
apiCallback(NO, [AZError errorWithNSError:error]);
}
}];
[operation start];
}
Hope it helps you.
I'm using AFNetworking to download more or less 200 images. The problem is that the main thread is blocked during the download, not during the success/failure block.
Here is my code:
imageDownloads=[[NSMutableArray alloc]init];
for(NSString *url in liens){
NSString *totalURL = [NSString stringWithFormat:#"http://%#", url];
[imageDownloads addObject:[[ImageDownload alloc] initWithURL:[NSURL URLWithString:totalURL] filename:nil]];
}
for (int i=0; i < imageDownloads.count; i++)
{
ImageDownload *imageDownload = imageDownloads[i];
[self downloadImageFromURL:imageDownload];
}
- (void)downloadImageFromURL:(ImageDownload *)imageDownload
{
NSURLRequest *request = [NSURLRequest requestWithURL:imageDownload.url];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
imageDownload.totalBytesRead = totalBytesRead;
imageDownload.totalBytesExpected = totalBytesExpectedToRead;
[self updateProgressView];
}];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSAssert([responseObject isKindOfClass:[NSData class]], #"expected NSData");
imageDownload.totalBytesExpected = imageDownload.totalBytesRead;
[self updateProgressView];
//all kind of basic stuff here I left out: I get store the data inside CoreData
NSLog(#"finished %#", imageDownload);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error %#", error);
}];
[operation start];
}
Basically, when I launch the code, the thread is blocked for like 30-40 seconds (the pictures are about 100MB in total), and then suddenly I can see all the NSLog logs appear with the "Finished"... text. So that part if really quick. But I thought AFNetworking wasn't supposed to block the main thread while I was downloading? This also doesn't allow me to track the progress of the download...Am I doing something wrong or misinterpreting something?
You're updating the progress view in the progress block. Because AFNetworking is inherently async anyway, each of these requests will stack and run at the same time. If you're running 200 of them, that's going to freeze up the app. Try using NSOperationQueue's maxConcurrentOperationCount to limit the number of concurrent threads.
Alternatively, you could save all the trouble and just use sdwebimage.
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.
I new to AFNetworking and less experience in iOS development.
I use AFNetworking to download image from the internet, here is the code:
- (void)dowloadPoject {
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer.cachePolicy = NSURLRequestReturnCacheDataElseLoad;
BOOL __block responseFromCache = YES; // yes by default
void (^requestSuccessBlock)(AFHTTPRequestOperation *operation, id responseObject) = ^(AFHTTPRequestOperation *operation, id responseObject) {
if (responseFromCache) {
// response was returned from cache
NSLog(#"RESPONSE FROM CACHE: %#", responseObject);
}
else {
// response was returned from the server, not from cache
NSLog(#"RESPONSE From Server: %#", responseObject);
}
UIImage *downloadedImage = [[UIImage alloc] init];
downloadedImage = responseObject;
// Add & Reload Data
[self.projectImage addObject:downloadedImage];
[self.projectname addObject:#"ABC"];
[self reloadComingSoonProject];
[self reloadNewReleaseProject];
};
void (^requestFailureBlock)(AFHTTPRequestOperation *operation, NSError *error) = ^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"ERROR: %#", error);
};
AFHTTPRequestOperation *operation = [manager GET:#"http://i359.photobucket.com/albums/oo34/SenaSLA/walls/Forward-Arrow-Button.png"
parameters:nil
success:requestSuccessBlock
failure:requestFailureBlock];
operation.responseSerializer = [AFImageResponseSerializer serializer];
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
NSLog(#"bytesRead: %u, totalBytesRead: %lld, totalBytesExpectedToRead: %lld", bytesRead, totalBytesRead, totalBytesExpectedToRead);
[self.viewNavBar.progressbar setProgress:(totalBytesRead/totalBytesExpectedToRead) animated:YES];
}];
[operation setCacheResponseBlock:^NSCachedURLResponse *(NSURLConnection *connection, NSCachedURLResponse *cachedResponse) {
// this will be called whenever server returns status code 200, not 304
responseFromCache = NO;
return cachedResponse;
}];
}
I have been searching on internet and i still no get the right solution. i have tried this solution from rckoenes but this no work for me.
I have succeeded to cache an image like 4kb, but when i'm trying with image like 103kb it doesn't cache. Thank you.
You can try increasing the cache size. Last time I tested this, networking code wouldn't cache if the received data exceeded 5% of the total cache size (though, annoyingly, I have yet to see Apple clearly articulate the rules that are applied during caching).
Anyway, if you look at the app delegate in the sample AFNetworking project, that shows and example of how to specify the cache size:
NSURLCache *cache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 diskCapacity:20 * 1024 * 1024 diskPath:nil];
[NSURLCache setSharedURLCache:cache];
It looks like the default RAM cache is only 0.5mb and the disk cache is 10mb. By increasing that RAM cache to 4mb, like shown above, or larger, and you should be able to cache your 103kb image (assuming that all the other criteria, such as header fields of the response and the like, permit it).
I am new to web services and I have searched it but I couldn't find any documents about it. Is there any way to download images and videos from WCF Service and save the my app's document files? or do I need to use different way for download?
Thanks for your advice and interest.
Try using AFNetWorking: https://github.com/AFNetworking/AFNetworking
This is a sample how I download files from a WCF:
NSMutableURLRequest *reqeust = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:{url}]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:reqeust];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:{path_on_disk} append:NO];
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
//Download progress
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//Download failed
}];
[operation start]