gianlucabertani/Objective-Zip

Error reading file with 1.0.4 & 1.0.5, working with 1.0.3

timautin opened this issue · 7 comments

Hello,

I'm unable to read the doc.kml file in the following zip file with 1.0.4 & 1.0.5, while it was working fine with 1.0.3: http://ewalk.app/objectivezip-bug.kmz.

By the way, is there a way to catch Objective-zip exception from Swift?

Thanks!

The Error handling section in the README explains how to use Swift's error handling, it should work with its do-try-catch statement. Try it.

Well I'm not sure where should I put the #import "Objective-Zip+NSError.h", as I'm using "import objective_zip" from swift. There's the objective-zip-umbrella.h file already importing both Objective-Zip.h and Objective-Zip+NSError.h. I tried to leave only the latter, same behaviour.

You should create a bridging header. Proceed in the following way:

  • Remove the import objective_zip statement wherever you added it.
  • Add a C header and call it Bridging-Header.h
  • Put the #import statement in the bridging header:
#import <objective_zip/Objective-Zip+NSError.h>
  • Search the "Objective-C Bridging Header" in Project Settings and set it to the bridging header's file name (including any subdirectory).
  • Now anywhere in your code you can use Objective-Zip with its NSError extension. A usage example is as follows:
let zipFile = OZZipFile(fileName: "MyFile.zip", mode:.unzip)
let stream = zipFile.readCurrentFileInZip()
let data = NSMutableData()

do {
    try stream.readData(withBuffer: data, error: ())
        
} catch {
    // ...
}

Alas this library is quite old. It was written in 2009, long before Swift was a thing. I'm very well aware that a rewrite is long overdue. I will do it, I even have some good idea. Promise.

In the meantime, I hope this is of help, at least on error handling.

I was able to successfully unzip the file you linked with version 1.0.5.

This is the code I used:

#define UNZIP_BUFFER_SIZE (65535)

NSString *documentsDir= // ...
NSString *zipFilePath= [documentsDir stringByAppendingPathComponent:@"objectivezip-bug.kmz"];
NSString *unzippedFilePath= [documentsDir stringByAppendingPathComponent:@"doc.kml"];

@try {
    OZZipFile *unzipFile= [[OZZipFile alloc] initWithFileName:zipFilePath mode:OZZipFileModeUnzip];
    NSArray *infos= [unzipFile listFileInZipInfos];
    
    for (OZFileInZipInfo *info in infos)
        NSLog(@"Test 000: - %@ %@ %lu (%ld)", info.name, info.date, (unsigned long) info.size, (long) info.level);
    
    [unzipFile goToFirstFileInZip];
    
    [[NSFileManager defaultManager] createFileAtPath:unzippedFilePath contents:nil attributes:nil];
    NSFileHandle *handle= [NSFileHandle fileHandleForWritingAtPath:unzippedFilePath];
    OZZipReadStream *stream= [unzipFile readCurrentFileInZip];
    NSMutableData *buffer= [NSMutableData dataWithCapacity:UNZIP_BUFFER_SIZE];
    
    do {
        [buffer setLength:UNZIP_BUFFER_SIZE];
        
        NSUInteger bytes= [stream readDataWithBuffer:buffer];
        if (bytes == 0)
            break;
        
        [buffer setLength:bytes];
        [handle writeData:buffer];
        
    } while (YES);
    
    [stream finishedReading];
    
    [handle synchronizeFile];
    [handle closeFile];

    [unzipFile close];

} @catch (OZZipException *ze) {
    NSLog(@"Zip exception caught: %ld - %@", (long) ze.error, [ze reason]);
    
} @catch (NSException *e) {
    NSLog(@"Generic exception caught: %@ - %@", [[e class] description], [e description]);
}

No exception was caught in the process.

I think you may be using a bigger than allowed unzip buffer: the latest version of MiniZip I integrated sets a maximum size of 65535 bytes. You should get an exception if this is the case.

Thanks for your answers! I tried to add the #import <objective_zip/Objective-Zip+NSError.h> in my bridging header, and removed the import objective_zip -> Xcode doesn't find the classes (OZZipFile etc).

Removing all the includes but Objective-Zip+NSError.h from objective-zip-umbrella seems to do the trick, but I have to do it every time I run a pod install, so I'd prefer to get my bridging header working. Still, I had to add "try" statements before most of objective-zip methods, but I'm unable to catch the exception (the app crashes). I guess you can reproduce by trying to load the whole file at once.

Looks you are right about the buffer size: my file has a size of 100064 bytes. Thanks!

PS: I perfectly understand that rewriting the library will take a lot of efforts, and I already greatly appreciate your support!!

I have a test project (Xcode 9.4, Swift, CocoaPods 1.5.3, Objective-Zip 1.0.5) that I can send you. If you don't want to disclose you email, follow me on Twitter (@self_vs_this), I will follow back and we can continue privately there.

Thanks, I followed you on Twitter (@ewalkapp).