I am Very new to iOS Application Development Platform, I am searching for one thing from Last Few weeks, actually my requirement is I have a UITableview with few Urls,and On didselectRowAtIndexPath That song should run in the Background and it downloading progress shows in another tab.
When I clicked multiple Buttons then multiple songs are downloaded simultaneously and all downloading progress should shown individually in the next Tab and here I have felicity to Pause, resume, and cancel the particular download. this is my requirement. I use AFNetworking But it is not Clear Please Help me and do the needful.
my AFNetworking code below
NSURL *url = [NSURL URLWithString:downLoadedUrlParam];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:3600];
NSString *MUSICFile=[DocumentsDirectory stringByAppendingPathComponent:songName];
self.operation = [[AFDownloadRequestOperation alloc] initWithRequest:request targetPath:MUSICFile shouldResume:YES];
[self.operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Successfully downloaded file to %#", MUSICFile);
//[ProcessingUrlsArray removeObject:videoString];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
if(operation.response.statusCode!= 200) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Alert" message:#"Error While Downloaded" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
}
}];
[httpClient enqueueHTTPRequestOperation:self.operation];
[self.operation setProgressiveDownloadProgressBlock:^(NSInteger bytesRead, long long totalBytesRead, long long totalBytesExpected, long long totalBytesReadForFile, long long totalBytesExpectedToReadForFile) {
float percentDone = totalBytesReadForFile/(float)totalBytesExpectedToReadForFile;
NSLog(#"------%#",[NSString stringWithFormat:#"CUR : %lli M",totalBytesReadForFile/1024/1024]);
NSLog(#"------%#",[NSString stringWithFormat:#"TOTAL : %lli M",totalBytesExpectedToReadForFile/1024/1024]);
NSLog(#"------%f",percentDone);
NSLog(#"------%.0f%%",percentDone*100);
self.myProgressBar.progress=percentDone;
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);
NSLog(#"%#",downLoadedUrlParam);
self.title=downLoadNameParam;
NSMutableArray *stgPerst;
stgPerst=[[NSMutableArray alloc]initWithCapacity:0];
NSDictionary *dicInfo=[NSDictionary dictionaryWithObjects:#[[NSString stringWithFormat:#"%f",percentDone],downLoadNameParam] forKeys:#[#"heProg",#"heName"]];
NSLog(#"dict=%#",dicInfo);
[[NSNotificationCenter defaultCenter] postNotificationName:#"DOWNLOAD_PROGRESS" object:nil userInfo:dicInfo];
}];
Related
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];
}
}
I am downloading an audio file from a server with the help of AFNetworking. The file is getting downloaded successfully as I ma able to see it through a progress block.
I am storing it in the Documents directory but then I am not able to play it.
Here is my code:-
-(void)downloadAudioFileFromUrl:(NSString *)str_url{
[SVProgressHUD show];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:str_url]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"momentsAudioToast.mp3"];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Successfully downloaded file to %#", path);
[SVProgressHUD dismiss];
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
[self playSound:path];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
[SVProgressHUD dismiss];
}];
[operation setDownloadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
//[progressView setProgress: totalBytesWritten*1.0f / totalBytesExpectedToWrite animated: YES];
NSLog(#"downloaded %lld of %lld bytes and progress is %f", totalBytesWritten, totalBytesExpectedToWrite, totalBytesWritten*1.0f / totalBytesExpectedToWrite);
if(totalBytesWritten >= totalBytesExpectedToWrite)
{
//progressView.hidden = YES;
}
}];
[operation start];
}
- (void)playSound:(NSString *)path {
[self.player prepareToPlay];
//UIButton *audioButton = (UIButton *)sender;
//[audioButton setImage:[UIImage imageNamed:#"sound_preview.png"] forState:UIControlStateNormal];
NSData *audioData = [NSData dataWithContentsOfFile:path options: 0 error:nil];
self.player = [[AVAudioPlayer alloc] initWithData:audioData error:nil];
double duration = [self.player duration];
NSLog(#"%f", duration);
NSError * error;
self.player.delegate = self;
self.player.numberOfLoops = 0;
if (error) {
NSLog(#"Error: %#",[error description]);
}
else {
self.player.delegate = self;
[self.player play];
}
}
Please help if I am doing something wrong.
Thanks in advance.
First, ensure that you are keeping strong reference to AVAudioPlayer instance player like this:
#property (nonatomic, strong) AVAudioPlayer *player;
Second, most likely, it would be path related issue. Try rebuilding the path while playing.
Third,, double check if file physically exists and that it plays when you play it in any audio player.
In Your case if you declare audio player perfect.
And Also set delegate & if you get NSData from audio file from web service.
Then you need to insert one more line of code and check again.
[self.player setVolume: 1.0];
I am stuck in Resuming Download. I am using AFDownloadRequestOperation to download the file from Dropbox public link. Everything(Downloading and Resuming) was going fine. But suddenly i don't know what happened that Downloading is working fine but on App Restart Resuming is not working and each time giving "Request Timeout". While with link other then Dropbox(public link) Downloading and Resuming both are working fine. I have also tried same with ASIHTTPRequest and getting same behave. So What can the reason is there any problem with Dropbox public link? or is there any restriction with these library?
Please help i am much worried about my project's Progress. Project progress is stop due to this problem.
Here is my code
__weak typeof(self) weakSelf = self;
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:url.absoluteString.lastPathComponent];
operation = [[AFDownloadRequestOperation alloc] initWithRequest:request targetPath:path shouldResume:YES];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate.downloadQueue removeObject:url.absoluteString];
[weakSelf checkDownloadQueueForMoreDownload];
NSLog(#"Successfully downloaded file to %#", path);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[operation setProgressiveDownloadProgressBlock:^(AFDownloadRequestOperation *operation, NSInteger bytesRead, long long totalBytesRead, long long totalBytesExpected, long long totalBytesReadForFile, long long totalBytesExpectedToReadForFile) {
if (totalBytesExpected != totalBytesExpectedToReadForFile &&( weakSelf.isDefaultProgressSet == NO)) {
long long bytesHasWritten = totalBytesExpectedToReadForFile-totalBytesExpected;
[weakSelf.delegate downloadedNumberOfBytes:((float)bytesHasWritten/
(float)totalBytesExpectedToReadForFile)
forAnnotaionView:annotView];
weakSelf.isDefaultProgressSet = YES;
}
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);
float progress = ((float)totalBytesReadForFile/(float)totalBytesExpectedToReadForFile);
[weakSelf.delegate downloadedNumberOfBytes:progress forAnnotaionView:annotView];
}];
[operation start];
On resuming always going to Failure block.
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];
Using AFNetworking to download files from a server. Here's the code:
self.networkQueue = [[[NSOperationQueue alloc] init] autorelease];
[networkQueue setMaxConcurrentOperationCount:3];
for(NSDictionary* fileDictionary in self.syncArray) {
#autoreleasepool {
if([[fileDictionary allKeys] containsObject:#"downloadZipURL"]) {
NSString* downloadPath = [fileDictionary objectForKey:#"downloadZipURL"];
downloadPath = [downloadPath stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSURLRequest *requestURL = [NSURLRequest requestWithURL:[NSURL URLWithString:downloadPath]];
NSString* localDestPath = [NSString stringWithFormat:#"%#/%#", [FileUtil userDocumentsDirectory], [downloadPath lastPathComponent]];
NSString* localTempPath = [NSString stringWithFormat:#"%#.tmp", localDestPath];
[(NSMutableDictionary*)fileDictionary setObject:localDestPath forKey:#"downloadDestination"];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:requestURL];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:localDestPath append:NO];
operation.userInfo = fileDictionary;
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
if (networkQueue.operationCount == 0)
{
if(hasDownloadError || isCancellingSync) {
return ;
}
[self performSelectorInBackground:#selector(processAllFiles) withObject:nil];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
// [operation setDownloadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
// NSLog(#"Sent %lld of %lld bytes, %#", totalBytesWritten, totalBytesExpectedToWrite, localDestPath);
// float progress = (float)totalBytesWritten/(float)totalBytesExpectedToWrite;
// [(NSMutableDictionary*)operation.userInfo setObject:[NSString stringWithFormat:#"Downloading %.0f%%", progress*100] forKey:#"downloadStatus"];
// [(NSMutableDictionary*)operation.userInfo setObject:[NSNumber numberWithFloat:progress] forKey:#"downloadProgress"];
// [syncViewController onPermitUpdated];
// }];
[networkQueue addOperation:operation];
}
}
}
My problem is that once this code is run, memory slowly gets eaten up and never given back. Now, these can be large files, which is why I used the outputStream.
Any suggestions would be appreciated.
Off the top of my head - I see that you're not using ARC.
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:requestURL]
Are you releasing this operation somewhere?
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
if (networkQueue.operationCount == 0)
{
if(hasDownloadError || isCancellingSync) {
return ;
}
[self performSelectorInBackground:#selector(processAllFiles) withObject:nil];
}
Here, you're using the networkQueue in the completionBlock and the block retains the networkQueue, you then add the operation to the networkQueue, which retains the operation, which leads to neither of them deallocating. Try making a weak variable of the networkQueue and use that in order to break the cycle.
If these don't work - run instruments and make a note of what objects remain in memory and when their reference count is changed.