Search code examples
iosobjective-csqliteunzipssziparchive

Unzipping .sqlite file using SSZipArchive OBJ-C


I have a requirement of downloading .zip file from server and use it to project after extracting it. I have successfully downloaded the .sqlite file and i am able to extract it using right click(manually) but when i am trying to extract it using minizip and SSZipArchive or ZipArchive it's giving an error "Can't open the file".

If i extract .sqlite manually and compress .sqlite file by right clicking in mac then my code is extracting it completely but whenever i try to extract downloaded file directly then this issue is occurring.

I have applied below name formats for writing and extracting file.

  1. While writing file the name was XYZ.sqlite.zip but it is also giving error
  2. XYZ.zip and contained file name is XYZ.sqlite. This also giving error
  3. I also have written file with name XYZ.sqlite.zip and then rename it with XYZ.zip and then extracted but that was also not working.

Below is the code.

For Downloading the file:

 NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:zipURL]];
  NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
 NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:[zipURL lastPathComponent]];
operation = [[AFDownloadRequestOperation alloc] initWithRequest:request targetPath:path shouldResume:YES];
 [operation.securityPolicy setAllowInvalidCertificates:YES];
 [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
 [self unzipDBFile: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) {

     NSArray *progress = [NSArray arrayWithObjects:obj_Pro,[NSNumber numberWithFloat:totalBytesReadForFile/(float)totalBytesExpectedToReadForFile], nil];

     [self performSelectorOnMainThread:@selector(updateProgressBar:) withObject:progress waitUntilDone:NO];
 }];
[operation start];

For Extracting the file:

-(void)unzipDBFile:(NSString *)filePath
{

 NSString *documentDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                             NSUserDomainMask, YES) objectAtIndex:0];
   NSString *outputPath = [documentDir stringByAppendingPathComponent:@"/DBFolder"];
   BOOL isExtracted =[SSZipArchive unzipFileAtPath:outputPath toDestination:documentDir];

  // NSString *filepath = [[NSBundle mainBundle] pathForResource:@"ZipFileName" ofType:@"zip"];
 //    ZipArchive *zipArchive = [[ZipArchive alloc] init];
 //    [zipArchive UnzipOpenFile:filePath];

 //    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//    NSString *path = [paths objectAtIndex:0];
//    BOOL isExtracted=[zipArchive UnzipFileTo:path overWrite:YES];
//    NSLog(@"PATH=%@",path);
   if (!isExtracted)
    {
     UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@"Error in extracting" message:@"" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
      [alert show];
      [alert release];
   }else{
     UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@"Extract Success" message:@"" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
     [alert show];
     [alert release];
   }
//    [zipArchive UnzipCloseFile];
//    [zipArchive release];
}

Below is the code for update progressbar:

- (void)updateProgressBar:(NSArray *)progress
{
 UIProgressView *pgr = (UIProgressView *)[progress objectAtIndex:0];
 [pgr setProgress:[[progress objectAtIndex:1] floatValue]];
}

Solution

  • I have examined the issue and found that .net developer, Who created .zip has used gzip compression so minizip is not able to extract it.

    For decompress it, I have used iOS zlib framework and below code and that has solved my problem. You have to add below two things in the header before implementing this method.

    #import <zlib.h>
    #define CHUNK 16384
    
    -(BOOL)unzipDBFile:(NSString *)filePath
    {
    NSString *documentDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                                 NSUserDomainMask, YES) objectAtIndex:0];
    documentDir=[documentDir stringByAppendingPathComponent:DATABASE_FILE_NAME];
    
        gzFile file = gzopen([filePath UTF8String], "rb");
        FILE *dest = fopen([documentDir UTF8String], "w");
        unsigned char buffer[CHUNK];
        int uncompressedLength;
        while ((uncompressedLength = gzread(file, buffer, CHUNK)) ) {
            // got data out of our file
            if(fwrite(buffer, 1, uncompressedLength, dest) != uncompressedLength || ferror(dest)) {
    
                return FALSE;
            }
        }
        fclose(dest);
        gzclose(file);
    
    return TRUE;
    }