Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error reading file with 1.0.4 & 1.0.5, working with 1.0.3 #71

Open
timautin opened this issue Jun 9, 2018 · 7 comments
Open

Error reading file with 1.0.4 & 1.0.5, working with 1.0.3 #71

timautin opened this issue Jun 9, 2018 · 7 comments

Comments

@timautin
Copy link

timautin commented Jun 9, 2018

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!

@gianlucabertani
Copy link
Owner

gianlucabertani commented Jun 9, 2018

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.

@timautin
Copy link
Author

timautin commented Jun 9, 2018

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.

@gianlucabertani
Copy link
Owner

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.

@gianlucabertani
Copy link
Owner

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.

@timautin
Copy link
Author

timautin commented Jun 9, 2018

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!!

@gianlucabertani
Copy link
Owner

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.

@timautin
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants