Abhi
Abhi

Reputation: 95

How to zip files without creating directory inside zip directory?

I am trying to zip files at destination path. Everything works perfectly. My files are zipped at the destination URL. But the problem is when I unzip, my files are inside the directory. I don't want my files inside a directory. When I unzip, I want to see my files.

This is my code:

func zipData() {
    let  path=NSSearchPathForDirectoriesInDomains(.documentDirectory,.userDomainMask,true).first!
    let fileManager = FileManager()

    var sourceURL = URL(fileURLWithPath: path)
    sourceURL.appendPathComponent("/cropsapdb_up_\(useridsaved)")

    var destinationURL = URL(fileURLWithPath: path)
    destinationURL.appendPathComponent("/cropsapdb_up_\(useridsaved).zip")
    do {
        let fm = FileManager.default
        let items = try fm.contentsOfDirectory(atPath: sourceURL.path)
        guard let archive = Archive(url: destinationURL, accessMode: .create) else  {
            print("returning")
            return
        }

        for item in items {
            sourceURL = sourceURL.appendingPathComponent("/\(item)")

            try archive.addEntry(with: sourceURL.lastPathComponent, relativeTo: sourceURL.deletingLastPathComponent())
            guard let archive = Archive(url: destinationURL, accessMode: .update) else  {
                print("returning")
                return
            }

            sourceURL.deleteLastPathComponent()
        }
    } catch {
}

Upvotes: 2

Views: 2622

Answers (1)

Thomas Zoechling
Thomas Zoechling

Reputation: 34253

I am the author of ZIP Foundation, the library you are using.

If I understand your code correctly you want to recursively add the contents of a directory to a ZIP archive.
To achieve this, you can use the convenience method zipItem which is implemented as extension to FileManager in ZIP Foundation.
By default, it behaves like the Archive Utility on macOS and includes the last directory name of the sourceURL as root directory of the archive. To alter that behaviour (as pointed out by Leo Dabus in the comments), you can pass the optional shouldKeepParent: false parameter:

func zipData() {
    let useridsaved = 1
    
    let fileManager = FileManager.default
    let path = NSSearchPathForDirectoriesInDomains(.documentDirectory,.userDomainMask,true).first!
    var sourceURL = URL(fileURLWithPath: path)
    sourceURL.appendPathComponent("cropsapdb_up_\(useridsaved)")
    var destinationURL = URL(fileURLWithPath: path)
    destinationURL.appendPathComponent("cropsapdb_up_\(useridsaved).zip")
    do {
        try fileManager.zipItem(at: sourceURL, to: destinationURL, shouldKeepParent: false)
    } catch {
        print(error)
    }
}

(I added a fictional let useridsaved = 1 local variable to make your sample compilable)

To verify that the archive does indeed not include a root directory, you can use the zipinfo command line utility shipping with macOS.
It is also possible, that the ZIP code on your server implicitly creates a directory when unpacking your archive.

Upvotes: 8

Related Questions