File existence after AFNetworking download - afnetworking

I'm having some issues with finding my file after downloading it with AFNetworking...
The download itself goes fine, but when I check for the existence of the file afterwards, I can't find it... So I'm hoping someone can help me out...
In my code, I download the file, and in the completion block, I check for the existence (this is only done since I'm having issues finding it, it will be removed afterwards)...
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"url to file removed"]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"filename removed"];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:#"filename removed" append:NO];
//Track the progress
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead)
{
if (totalBytesExpectedToRead > 0)
{
dispatch_async(dispatch_get_main_queue(), ^{
NSString *progress = [NSString stringWithFormat:#"Downloaded %lld of %lld bytes",
totalBytesRead,
totalBytesExpectedToRead];
NSLog(#"%#", progress);
});
}
}];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(#"File downloaded to %#", path);
//Check for existence
NSFileManager *filemgr = [NSFileManager defaultManager];
if([filemgr fileExistsAtPath:path])
{
NSLog(#"File found");
} else
{
NSLog(#"File not found");
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"Error: %#", error);
}];
[operation start];
Any ideas where it might be going wrong? As the download itself goes fine, the problem must lie with saving the file / the file system in iOS...

Does the directory you're trying to write to exist? If not you may find [NSOutputStream outputStreamToFileAtPath:#"filename removed" append:NO] is returning nil.
Try creating the directory first:
NSFileManager *fm = [NSFileManager defaultManager];
NSString *folder = [#"filename removed" stringByDeletingLastPathComponent];
if (![fm fileExistsAtPath:folder]) {
[fm createDirectoryAtPath:folder
withIntermediateDirectories:YES
attributes:nil
error:nil];
}
I hope that helps.

Related

Is it necessary to manually clear the Incomplete folder generated by AFNetworking? [duplicate]

This question already has answers here:
iPhone storage in tmp directory
(2 answers)
Closed 7 years ago.
As title, I am handling a case that when downloading a large zip file using AFNetworking 2.5.4 framework, the user quit the app accidentally. I would like to know if it is necessary to manually clear the Incomplete folder (<app_name>/tmp/Incomplete) generated by AFNetworking, as the zip file downloading is quite large. Will iOS handle this folder if it find the folder size if growing?
P.S. My downloading logic is by using NSOperationQueue and the below AFDownloadRequestOperation:
- (AFDownloadRequestOperation *)operation
{
if (_operation) {
return _operation;
}
_operation = [[AFDownloadRequestOperation alloc] initWithRequest:self.downloadRequest
targetPath:self.targetPath
shouldResume:YES];
#ifdef DEBUG
_operation.securityPolicy.allowInvalidCertificates = YES;
#endif
[_operation setProgressiveDownloadProgressBlock:self.progressBlock];
[_operation setCompletionBlockWithSuccess:self.completionBlock
failure:self.failureBlock];
_operation.deleteTempFileOnCancel = YES;
return _operation;
}
you can resume the incomplete download with this
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"....zip"]];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"....zip"];
AFDownloadRequestOperation *operation = [[AFDownloadRequestOperation alloc] initWithRequest:request targetPath:path shouldResume:YES];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Successfully downloaded file to %#", path);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[operation setProgressiveDownloadProgressBlock:^(NSInteger bytesRead, long long totalBytesRead, long long totalBytesExpected, long long totalBytesReadForFile, long long totalBytesExpectedToReadForFile) {
NSLog(#"Operation%i: bytesRead: %d", 1, bytesRead);
NSLog(#"Operation%i: totalBytesRead: %lld", 1, totalBytesRead);
NSLog(#"Operation%i: totalBytesExpected: %lld", 1, totalBytesExpected);
NSLog(#"Operation%i: totalBytesReadForFile: %lld", 1, totalBytesReadForFile);
NSLog(#"Operation%i: totalBytesExpectedToReadForFile: %lld", 1, totalBytesExpectedToReadForFile);
}];
[operations addObject:operation];
OR you can delete temp files
+ (void)clearTmpDirectory
{
NSArray* tmpDirectory = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:NSTemporaryDirectory() error:NULL];
for (NSString *file in tmpDirectory) {
[[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:#"%#%#", NSTemporaryDirectory(), file] error:NULL];
}
}

Couldn't save data in given path of document directory by NSOutputStream

How to save downloaded content/data in the given path in document directory by NSOutputStream. If i append file name with DD then it works (ex- DD/contentPath.zip), But if i append a path like DD/hello/contentPath.zip then it doesn't work. Why ? I tried like below -
- (void) downloadCarContents:(NSString *)url forContent:(NSString *)contentPath {
//NSString *destinationPath = [self.documentDirectory getDownloadContentPath:contentPath];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
AFHTTPRequestOperation *op = [manager GET:url
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//NSLog(#"Error : %#", error.localizedDescription);
}];
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *dest = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"hello/%#.zip", contentPath]];// It doesn't work
//NSString *dest = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.zip", contentPath]];// It works
op.outputStream = [NSOutputStream outputStreamToFileAtPath:dest append:NO];
[op setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
float percentage = (float) (totalBytesRead * 100) / totalBytesExpectedToRead;
[self.delegate downloadProgression:percentage];
}];
}
The API doesn't create the folder for you. Your code needs to ensure it exists before you try to use it. NSFileManager can help with createDirectoryAtPath:withIntermediateDirectories:attributes:error:

How to prevent download with same request from AFHTTPRequestOperation?multiple download occurs for same file

I am using AFHTTPRequestOperation to download a file from remote server now my problem is AFHTTPRequestOperation starts to download same request multiple time so i want to prevent the download process to execute for same request.
so basically what i want is however if downloadFile: function call multiple time with same request i can prevent the download process to start if any process running with same request already.
following is my code
AFHTTPRequestOperation *operation;
-(void)downloadFile:(NSURL *)videoUrl{
NSURLRequest *request = [NSURLRequest requestWithURL:videoUrl];
operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:VIDEO_DIRECTORY_NAME];
NSString *downloadPath = [dataPath stringByAppendingPathComponent:[NSString stringWithFormat:#"TEMP_%#",[videoUrl lastPathComponent]]];
NSString *fullPath = [dataPath stringByAppendingPathComponent:[videoUrl lastPathComponent]];
// NSLog(#"Full Path For Download Video %#",fullPath);
NSError *error=[[NSError alloc]init];
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error]; //Create folder
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:fullPath];
if (!fileExists)
{
NSLog(#"Full Path For Download Video Started%#",fullPath);
[operation setOutputStream:[NSOutputStream outputStreamToFileAtPath:downloadPath append:NO]];
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
// NSLog(#"bytesRead: %lu, totalBytesRead: %lld, totalBytesExpectedToRead: %lld", (unsigned long)bytesRead, totalBytesRead, totalBytesExpectedToRead);
}];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSError *error;
if (error) {
NSLog(#"ERR: %#", [error description]);
} else {
CustomAlertView *alert=[[CustomAlertView alloc]init];
NSUserDefaults *userDefaults=[NSUserDefaults standardUserDefaults];
//check for Available Space
if([ALDisk freeDiskSpaceInBytes] >= [operation.response expectedContentLength])
{
NSLog(#"Content-lent: %lld", [operation.response expectedContentLength]);
[alert ShowNotificationInParentView:nil WithTitle:NSLocalizedString(#"Video_title", nil) Message:NSLocalizedString(#"Video_downloaded_succesfully", nil) IsSuperUser:[userDefaults boolForKey:IS_SUPER_USER] TypeOfNotification:ALERT_TYPE_ERROR IsLoggedIn:YES];
[assetManager.assetManagerDelegate didAssetManagerSucceedObject:nil ErrorCode:#"" Result:YES ResponseId:VIDEO_DOWNLOAD_RESPONSE_ID];
}
else {
[alert ShowNotificationInParentView:nil WithTitle:#"Memory Full" Message:NSLocalizedString(#"video_cannot_be_downloaded", nil) IsSuperUser:[userDefaults boolForKey:IS_SUPER_USER] TypeOfNotification:ALERT_TYPE_ERROR IsLoggedIn:YES];
[assetManager.assetManagerDelegate didAssetManagerFailedResponseWithError:[NSError errorWithDomain:#"Memory Full" code:[MEMORY_OUT_OF_STORAGE intValue] userInfo:nil]];
}
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"ERR: %#", [error description]);
[assetManager.assetManagerDelegate didAssetManagerFailedResponseWithError:error];
}];
[operation start];
}
}
Please guide me with any suggestion or solution.

Using append:YES with operation.outputStream AFHTTPRequestOperation doesn't work

I am trying to download a text file and if this download is paused I am trying to append the rest of the file.
The problem is that i am starting to download the rest from the right point but the file is not appending it overrides the previous file.
Here is my source code:
+ (void) downloadFile:(NSManagedObject *)file {
NSString *url = [file valueForKey:#"path"];
NSString *fileName = [[file valueForKey:#"path"] lastPathComponent]; // TODO chnage to file ID (it will be good to add id before file name)
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:fileName];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
BOOL append = NO;
unsigned long long size = 0;
BOOL resumeOperation = NO;
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
resumeOperation = YES;
NSError *error = nil;
NSDictionary *dict = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:&error];
size = [[dict objectForKey:NSFileSize] longLongValue];
if (!error) {
error = nil;
[[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
if (error) {
NSLog(#"Error removing old file: %#", [error localizedDescription]);
}
NSString *val = [NSString stringWithFormat:#"bytes=%lld-", size];
append = YES;
[request setValue:val forHTTPHeaderField:#"Range"];
}
}
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request] ;
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:filePath append:YES];
//gives more 10 minuts when the app is minimmized
[operation setShouldExecuteAsBackgroundTaskWithExpirationHandler:^{
[operation pause];
}];
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
totalBytesRead += size;
float percent = ((float)totalBytesRead) / (totalBytesExpectedToRead + size);
// TODO update database with bytes amount
NSLog(#"%.2f%% - [%d]", percent * 100, [[CoreDataManager getQueue] count]);
}];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"File downloaded succesffully!");
[self reportEndDownload:file withStatusCode:[NSNumber numberWithInt:DOWNLAOD_STATUS_COMPLETE]];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// NSLog(#"Error while downloading file: %#", [error localizedDescription]);
// ? ask about server corrupted files - here is a loop -----> Itay OK
[self reportEndDownload:file withStatusCode:[NSNumber numberWithInt:DOWNLOAF_STATUS_CONNECTION_ERROR]];
}];
if (resumeOperation ) {
[operation resume];
}else{
[operation start];
}
}
You can use AFDownloadRequestOperation to do this.
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"....zip"]];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"....zip"];
AFDownloadRequestOperation *operation = [[AFDownloadRequestOperation alloc] initWithRequest:request targetPath:path shouldResume:YES];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Successfully downloaded file to %#", path);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[operation setProgressiveDownloadProgressBlock:^(NSInteger bytesRead, long long totalBytesRead, long long totalBytesExpected, long long totalBytesReadForFile, long long totalBytesExpectedToReadForFile) {
NSLog(#"Operation%i: bytesRead: %d", 1, bytesRead);
NSLog(#"Operation%i: totalBytesRead: %lld", 1, totalBytesRead);
NSLog(#"Operation%i: totalBytesExpected: %lld", 1, totalBytesExpected);
NSLog(#"Operation%i: totalBytesReadForFile: %lld", 1, totalBytesReadForFile);
NSLog(#"Operation%i: totalBytesExpectedToReadForFile: %lld", 1, totalBytesExpectedToReadForFile);
}];
[operations addObject:operation];

Couldn't download from url in my app with AFNetwotking

Im noob in AFNetworking and I learning it now. I want download file from url and save in my app (Document Folder) but it dosen't work.I have one button that when click it start download.
this is my code for download file :
- (IBAction)downloads:(id)sender
{
NSLog(#"start downloads");
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://192.168.1.100/mamal/filemanager.php"]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:[path stringByAppendingPathComponent:#"filemanager.php"] append:NO];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Successfully downloaded file to %#", path);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
}
in this code when click on button take me this massage = 'start downloads' but dont show me 'Successfully downloaded file to %#' why?? my code not complete???
You didn't start the operation. Use the following line to start the operation :
[operation start];

Resources