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

624 views Asked by At

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];
 }


}
1

There are 1 answers

1
Retro On BEST ANSWER

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];