I have a file URL and want to download it in my iPhone in document directory. So that I can use this downloaded file within other application like, share it on whatsApp, in email attachment etc.
I am using ASIHTTPRequest, what Destination path I should set?
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:self.ImageURL];
[request setDownloadDestinationPath:#"What Path I should Set"];
[request startSynchronous];
Here is a sample url of file which I want to download:
http://www.fourspan.com/apps/agentreview/public/img/ads/1441791507_Muhammad.jpg
Firstly, ASIHTTPRequest is obsolete, please avoid using it.
Here is the code using AFNetworking to download any file and save it to any location you want (savePath)
#define kDocumentsDirPath [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]
- (void)downloadFile:(NSString *)filePath
{
AFURLSessionManager *sessionManager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:filePath]];
NSURLSessionDownloadTask *downloadTask = [sessionManager downloadTaskWithRequest:request
progress:nil
destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
NSString *savePath = [kDocumentsDirPath stringByAppendingPathComponent:fileName];
return [NSURL fileURLWithPath:savePath];
}
completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
if (error)
{
NSLog(#"Download failed for %#: %#", fileName, error.localizedDescription);
[[[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:#"Failed to download %#", fileName]
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"Uh Oh"
otherButtonTitles:nil] show];
}
else {
NSLog(#"File downloaded: %#", fileName);
}
}];
[downloadTask resume];
}
Related
I have an array which contains different URLs. I want to download one file with a progress bar, than start the next one and so on.
Here is my code that I have so far;
-(void) func:(NSArray *) arry
{
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
configuration.timeoutIntervalForRequest = 900;
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSMutableArray * downloadedUrl = [[NSMutableArray alloc] init];
for (NSString * str in arry) {
NSURL *URL = [NSURL URLWithString:str];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSessionDownloadTask downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL (NSURL targetPath, NSURLResponse response) {
NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
return [tmpDirURL URLByAppendingPathComponent:[response suggestedFilename]];
} completionHandler:^(NSURLResponse response, NSURL filePath, NSError *error) {
if(error)
{
NSLog(#"File Not Dowloaded %#",error);
}
}];
[downloadTask resume];
}
}
How would you download one file at a time with a progress bar and then remove the url from array?
Declare one global NSMutableArray of file and used that in the function like below.
-(void) downloadFile {
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
configuration.timeoutIntervalForRequest = 900;
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURL *URL = [NSURL URLWithString:[self.fileArr firstObject]]; //Here self.fileArr is your global mutable array
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSessionDownloadTask downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL (NSURL targetPath, NSURLResponse response) {
NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
return [tmpDirURL URLByAppendingPathComponent:[response suggestedFilename]];
} completionHandler:^(NSURLResponse response, NSURL filePath, NSError *error) {
if(error)
{
NSLog(#"File Not Dowloaded %#",error);
[self downloadFile];
}
else {
[self.fileArr removeObjectAtIndex:0];
if (self.fileArr.count > 0) {
[self downloadFile];
}
}
}];
[downloadTask resume];
}
Now call this function but before that initialize self.fileArr and after that call downloadFile method.
Hope this will help you.
Give limit the queue to one Operation at a time,
For that, Try to adding dependencies between each operation before you queue them.
If you add dependency between two operations say operation1 and operation2 before adding to queue then the operation2 will not start until operation1 is finished or cancelled.
Do it like:
NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
// Make operation2 depend on operation1
[operation2 addDependency:operation1];
[operationQueue addOperations:#[operation1, operation2, operation3] waitUntilFinished:NO];
UPDATE
// Create a http operation
NSURL *url = [NSURL URLWithString:#"http://yoururl"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
// Print the response body in text
NSLog(#"Response: %#", [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
// Add the operation to a queue
// It will start once added
NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
[operationQueue addOperation:operation];
hope it help you..!
hello friends i m trying to upload audio file which is record by me its self but i m unable to upload that audio file into server. can any one suggest me proper way to upload that below have the code written by me.
player = [[AVAudioPlayer alloc] initWithContentsOfURL:recorder.url error:nil];
NSURL *audioURL = recorder.url;
NSString *str = [NSString stringWithFormat:#"%#",audioURL];
[mainAudioAddressArray addObject:str];
NSLog(#"%#",str);
NSLog(#"%#",mainAudioAddressArray);
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURL *URL = [NSURL URLWithString:#"http://192.168.1.4:8080/D:/Test/"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURL *filePath = [NSURL fileURLWithPath:#"str"];
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];
I have the following scenario: in my DocumentsDirectory there are user-created pdf-files. Now I want to upload them all to a webserver. When successfully done, i want to remove the file from the device.
My first problem is, that I do not know, when the upload is successful for a specific file. Additionally I get errors on some files.
At first some code:
-(void)uploadPDFs
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSArray *contents = [fileManager contentsOfDirectoryAtPath:docsDir error:nil];
for (NSString *filename in contents) {
if([filename.pathExtension isEqualToString:#"pdf"])
{
NSURL *docsDirURL = [NSURL fileURLWithPath:[docsDir stringByAppendingPathComponent:filename]];
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
[config setTimeoutIntervalForResource:10];
NSURLSession *upLoadSession = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://%#/api/putPdf?name=%#&folder=", [defaults objectForKey:#"serverAdresse"], filename]];
NSData *pdfData = [NSData dataWithContentsOfFile:docsDirURL.path];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setValue:#"application/pdf" forHTTPHeaderField:#"Content-Type"];
[request setHTTPMethod:#"POST"];
[request setValue:[NSString stringWithFormat:#"%lu", (unsigned long)[pdfData length]] forHTTPHeaderField:#"Content-Length"];
[request setTimeoutInterval:60];
// UploadTask is a NSURLSessionUploadTask
self.uploadTask = [upLoadSession uploadTaskWithRequest:request fromData:pdfData];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
[self.uploadTask resume];
}
}
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
});
if (!error) {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"NO ERROR");
// CAN I GET HERE THE UPLOADED FILENAME?
});
} else {
NSLog(#"ERROR: %#", error);
}
}
The error I get especially when there are many uploads:
(-[ViewController URLSession:task:didCompleteWithError:]) (ViewController.m:4025) ERROR: Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo=0x7fa3957028f0 {NSErrorFailingURLKey=http://192.168.100.150/api/putPdf?name=2015-03-26_AN_14.pdf&folder=, NSLocalizedDescription=The request timed out., NSErrorFailingURLStringKey=http://192.168.100.150/api/putPdf?name=2015-03-26_AN_14.pdf&folder=}
Use the taskDescription property of an NSURLSessionUploadTask. `
For example;
task.taskDescription = filePath;
`
The error was resulting out of an too short timeout. I increased this, and the problem disappeared.
still new to objective C i have discover the amazing AFNetworking network class.
Using the dic i have my code which download my file and write into the NSDocumentDirectory
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURL *URL = [NSURL URLWithString:#"http://myAdress/Menu.plist"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response)
{
NSURL *documentsDirectoryPath = [NSURL fileURLWithPath:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]];
return [documentsDirectoryPath URLByAppendingPathComponent:[response suggestedFilename]];
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
NSLog(#"File downloaded to: %#", filePath);
NSDictionary *dicMenuPlist = [NSDictionary dictionaryWithContentsOfFile:[filePath path]];
NSLog(#"Dic Menu Plist = %#",dicMenuPlist);
}];
[downloadTask resume];
this works fine but when i change something in my Menu.plist file the changes does not appear, i have to delete my app then download the file that has changed.
I do not understand why i have to do this.
Can someone help me please ?
The answer given here.
Delete the existing file in the destination block.
destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
NSURL *documentsDirectoryPath = [NSURL fileURLWithPath:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]];
NSURL *fileURL = [documentsDirectoryPath URLByAppendingPathComponent:[response suggestedFilename]];
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if ([httpResponse statusCode] == 200) {
// delete existing file (using file URL above)
}
return fileURL;
}
Default method AFNetworking 3.0 don't refresh that you downloader files.
If you want rewrite this file in Objective-C +iOS9.0, you need do that:
- (NSURLSessionDownloadTask *) downloadDocsFromUrl:(NSString *) url withSuccesBlock:(DocModelBlock) docModelBlock withErrorBlock:(ErrorBlock) errorBlock {
NSURL *URL = [NSURL URLWithString:url];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSessionDownloadTask *downloadTask = [self.sessionManager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSURL *documentsDirectoryURL = [fileManager URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:&error];
if ([httpResponse statusCode] == 200) {
NSURL *urlPath = [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
if ([fileManager fileExistsAtPath:urlPath.path]) {
[fileManager removeItemAtPath:urlPath.path error:&error];
}
}
return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
if (error) {
errorBlock(error);
} else {
docModelBlock(filePath);
}
}];
[downloadTask resume];
return downloadTask;
}
I'm creating a download task as indicated in the AFNetworking docs (https://github.com/AFNetworking/AFNetworking#creating-a-download-task).
When the NSURLSessionDownloadTask reached the block completionHandler the error is null, so there's no error. Also, the filePath returns a valid NSURL, such as /var/mobile/Applications/id-of-the-app/Documents/section/section13.png.
The problem is that it's not saving the file in the specified folder (the folder exists, and the file to be downloaded too).
Any ideas? Here's the code:
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:fileUrl]];
NSString *filename = [NSString stringWithFormat:#"section%#.%#", section.sectionId, [request.URL pathExtension]];
NSURL *saveUrl = [FilesManager urlForResourceType:ResourceTypeSection andFilename:filename];
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request
progress:nil
destination:^NSURL *(NSURL *targetPath, NSURLResponse *response)
{
return saveUrl;
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
NSLog(#"path - %#", filePath);
if (!error) {
NSLog(#"we're good");
}
}];
[downloadTask resume];