SoFunction
Updated on 2025-04-10

iOS implements file download function

This article shares the specific code for iOS implementation file download for your reference. The specific content is as follows

illustrate:

1). Obtain the network file size;

2). Open the loop, calculate the start and end positions of each position, and obtain the file data stream by block through the Range header field;

3). Use NSFileHandle append method to write NSData file data to the local file.

1. Use HEAD request to obtain the network file size:

/*
 Get network file size
 */
- (long long)getNetFileLen:(NSURL *)url{
    //1. Create a request    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:10];
    //Set the request method to HEAD, only obtain header information     = @"HEAD";
    
    //2. Define the object used to receive network data    NSURLResponse *response = nil;
    
    //3. Synchronize the request network and store the results into the response    [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:NULL];
    
    //Return file size    return ;
}

2. Turn on the asynchronous thread and request the network to download the file:

/*
 Download the file
 */
- (void)downloadFile:(NSString *)urlStr done:(void (^)())done{
    
    //1. Obtain the system's own global queue    // Parallel queue, multiple threads execute concurrently: DISPATCH_QUEUE_PRIORITY_DEFAULT    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    //2. Asynchronous execution    dispatch_async(queue, ^{
        //Create URL object        NSURL *url = [[NSURL alloc] initWithString:urlStr];
        NSLog(@"url: %@", urlStr);
        
        //Get local downloaded file size        long long localFileLen = [self getLocalFileLen];
        NSLog(@"localFileLen : %lld", localFileLen);
        
        //Get network file size        long long netFileLen = [self getNetFileLen:url];
        NSLog(@"netFileLen : %lld", netFileLen);
        
        if(localFileLen == netFileLen){//It means it exists            return;
        }
        
        //The file data size obtained from the server each time        long long itemSize = 1024 * 20;
        
        //The position of the start of a piece of data        long long startPos = 0;
        
        //The end position of a piece of data        long long endPos = 0;
        
        while (startPos < netFileLen) {
            // Calculate the end position            endPos = startPos + itemSize - 1;
            
            //Assemble the range field for request header            NSString *range = [NSString stringWithFormat:@"Bytes=%lld-%lld", startPos, endPos];
            
            NSLog(@"range : %@", range);
            
            //Recalculate the next data and start position            startPos = startPos + itemSize;
            
            /*
 Cache policy
                   NSURLRequestUseProtocolCachePolicy = 0, default, memory cache
                   NSURLRequestReloadIgnoringLocalCacheData = 1, Ignoring local memory cache
                       NSURLRequestReloadIgnoringLocalCacheData = NSURLRequestReloadIgnoringLocalCacheData,
                   NSURLRequestReturnCacheDataElseLoad = 2,
                   NSURLRequestReturnCacheDataDontLoad = 3,
 */
            
            //(1) Create a request            NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10];
            
            //Set the Range request header            [request setValue:range forHTTPHeaderField:@"Range"];
            
            //(2) Define the object used to receive network information            NSURLResponse *response = nil;
            
            //(3) Synchronous request network            NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:NULL];
            
            //(4) Write data to file            [self appendFile:data];
        }
        
        //3. Switch back to the main thread        dispatch_async(dispatch_get_main_queue(), ^{
            //Calling the completion method            done();
        });
        
    });
}

3. Get the local file size:

/*
 Get the local file size
 */
- (long long)getLocalFileLen{
    //Directory path    NSString *cacheDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    //File path    NSString *filePath = [cacheDir stringByAppendingPathComponent:@""];
    //Get local file NSDictionary information    NSDictionary *map = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:NULL];
    //Get local file size and convert to longlong type    return [map[NSFileSize] longLongValue];
}

4. Append NSData data to file:

/*
 Append NSData data to file
 */
- (void)appendFile:(NSData *)data{
    //Directory path    NSString *cacheDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    //File path    NSString *filePath = [cacheDir stringByAppendingPathComponent:@""];
    
    NSLog(@"filePath : %@", filePath);
    
    //Create file operation class, NSFileHandle supports append write method    NSFileHandle *file = [NSFileHandle fileHandleForWritingAtPath:filePath];
    
    if(!file){//When the file does not exist, write it directly overwrite the method        [data writeToFile:filePath atomically:YES];
        return;
    }
    //Skip to the end of the file    [file seekToEndOfFile];
    
    //Write data    [file writeData:data];
    
    //Close the file stream    [file closeFile];
}

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.