tartsigam
tartsigam

Reputation: 71

SSZipArchive "failed to open zip file" -- url.path is not the solution

Edit 2:

I tried Zip from marmelroy (https://github.com/marmelroy/Zip) and it failed on the zip-file created witch ZipArchive too.

Then I created another zip-file with Zip and this one worked fine for unzipping.

There seems to be a problem with ZipArchive for me. I will use Zip instead and thats it for me ...

Thx for the answers !!

End edit 2.

I need to unzip certain files so I manually installed SSZipArchive. Copied all 3 folders (SSZipArchive, minizip, aes) to project, added #import "ZipArchive.h" in my bridging.h and all builds nicely.

Edit:

Used Carthage as recommended, but same behavior.

End edit.

I use Xcode 8 / Swift 3

After a few tests with no unzipping any file, I created my own zip using SSZipArchive.

    let file = "file.txt"

    let text = "some text" //just a text
    
    let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
    
    let path = dir?.appendingPathComponent(file)
        
    //writing
    do {
        try text.write(to: path!, atomically: false, encoding: String.Encoding.utf8)
    }
    catch {
        print("Failed writing")
    }

Here I print() the Documentsdirectory: ["file.txt"]

    let zipPath = tempZipPath() //tempZipPath is taken from the SSZipArchiveExample except it uses DocumentDirectory instead of Cache...
    
    print("zipPath: \(zipPath)")

print zipPath: /var/mobile/Containers/Data/Application/EB439A61-07B9-4910-BF28-03E85C50B292/Documents/93428A1B-E5B6-434F-B049-632B7519B126.zip
    
    let success = SSZipArchive.createZipFile(atPath: zipPath, withContentsOfDirectory: (dir?.absoluteString)!)
    if success {
        print("zipped")
        
    } else {
        print(" NOT zipped")
    }
    

Again the Documentsdirectories entries: ["93428A1B-E5B6-434F-B049-632B7519B126.zip", "file.txt"]

    // this is again taken from the original Example
    guard let unzipPath = tempUnzipPath() else {
        return
    }
    
    print("unzipPath: \(unzipPath)")

print unzipPath: /var/mobile/Containers/Data/Application/EB439A61-07B9-4910-BF28-03E85C50B292/Documents/E4FC7DE6-F21B-46D8-9953-DCBF86E2268E

Reading the entries of this new directory: []

    let filePath = zipPath
    var fileSize : UInt64 = 0
    
    do {
        let attr : NSDictionary? = try FileManager.default.attributesOfItem(atPath: filePath) as NSDictionary?
        
        if let _attr = attr {
            fileSize = _attr.fileSize();
            print("fileSize: \(fileSize)")
        }
    } catch {
        print("Error: \(error)")
    }

this writes 22. I also tried to read the zip-file which works fine

From this part on I was desperate what to do

    let url = URL(fileURLWithPath: zipPath)
    
    print("url: \(url)")
    print("url.path: \(url.path)")
    print("url.absoluteString: \(url.absoluteString)")
    print("url.absoluteURL: \(url.absoluteURL)")
    print("url.absoluteURL.absoluteString: \(url.absoluteURL.absoluteString)")

The output of these lines look all good for me:

url: file:///var/mobile/Containers/Data/Application/EB439A61-07B9-4910-BF28-03E85C50B292/Documents/93428A1B-E5B6-434F-B049-632B7519B126.zip

url.path: /var/mobile/Containers/Data/Application/EB439A61-07B9-4910-BF28-03E85C50B292/Documents/93428A1B-E5B6-434F-B049-632B7519B126.zip

url.absoluteString: file:///var/mobile/Containers/Data/Application/EB439A61-07B9-4910-BF28-03E85C50B292/Documents/93428A1B-E5B6-434F-B049-632B7519B126.zip

url.absoluteURL: file:///var/mobile/Containers/Data/Application/EB439A61-07B9-4910-BF28-03E85C50B292/Documents/93428A1B-E5B6-434F-B049-632B7519B126.zip

url.absoluteURL.absoluteString: file:///var/mobile/Containers/Data/Application/EB439A61-07B9-4910-BF28-03E85C50B292/Documents/93428A1B-E5B6-434F-B049-632B7519B126.zip

And then I tried them all (Strings of course. No url allowed)

    var success2 = SSZipArchive.unzipFile(atPath: zipPath, toDestination: unzipPath)
    if !success2 {
        print("zipPath")
    }
    success2 = SSZipArchive.unzipFile(atPath: url.path, toDestination: unzipPath)
    if !success2 {
        print("url.path")
    }
    success2 = SSZipArchive.unzipFile(atPath: url.absoluteString, toDestination: unzipPath)
    if !success2 {
        print("url.absoluteString")
    }
    success2 = SSZipArchive.unzipFile(atPath: url.absoluteURL.path, toDestination: unzipPath)
    if !success2 {
        print("url.absoluteURL.path")
    }
    

And it prints every line, so they all failed. At the end here comes the "long" way with unipFileAtPath. I tried this one too with zipPath, ... All the same results.

    do {
        success2 = try SSZipArchive.unzipFileAtPath(url.path, toDestination: unzipPath, overwrite: true, password: nil, delegate: nil)
        if !success2 {
            return
        }
    } catch {
        print("error \(error)")
        print("error \(error.localizedDescription)")
    }
    

error Error Domain=SSZipArchiveErrorDomain Code=-1 "failed to open zip file" UserInfo={NSLocalizedDescription=failed to open zip file} error failed to open zip file

Here the to func to get the path-strings. btw. I modified tempZipPath so returns an URL or an URL.path

but hey: I was desperate

func tempZipPath() -> String {
    var path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
    path += "/\(UUID().uuidString).zip"
    return path
}

func tempUnzipPath() -> String? {
    var path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
    path += "/\(UUID().uuidString)"
    let url = URL(fileURLWithPath: path)
    
    do {
        try FileManager.default.createDirectory(at: url, withIntermediateDirectories: true, attributes: nil)
    } catch {
        return nil
    }
    
    return url.path
}

Any suggestions? Is there something to consider manually installing SSZipArchive?

The tip "use .path instead of .absoluteString" didn't work for me as u can see above.

a desperate tartsigam

Upvotes: 2

Views: 4689

Answers (3)

neowinston
neowinston

Reputation: 7764

In my case, using ObjC and manual installation, I forgot to Add the following GCC_PREPROCESSOR_DEFINITIONS:

$(inherited) HAVE_INTTYPES_H HAVE_PKCRYPT HAVE_STDINT_H HAVE_WZAES HAVE_ZLIB

After adding these GCC_PREPROCESSOR_DEFINITIONS it worked as expected.

Upvotes: 0

Tucano2000
Tucano2000

Reputation: 1

Before zip don't extract file and return false.

After put this in Build Settings / Apple CLang Prepocessing / Preprocessor Macros Debug e Release works here

GCC_PREPROCESSOR_DEFINITIONS: HAVE_INTTYPES_H HAVE_PKCRYPT HAVE_STDINT_H HAVE_WZAES HAVE_ZLIB MZ_ZIP_NO_SIGNING $(inherited)

Upvotes: 0

Florian Cremer
Florian Cremer

Reputation: 139

I had the problem, too. If you use url.path instead of url.absolutString, it works. Thanks to vadian for the hint!

Upvotes: 2

Related Questions