System API for generating ZIP-compatible archive?

The Archive Framework implements compression algorithms and supports for example the LZMA compression format. Unfortunately I was not able to find a way to generate a ZIP-kompatible archive using the Archive Framework though iOS / iPadOS seems to be able to do that, because the Files app and the Shortcuts app support this kind of compression.

Is there a way on iOS/iPadOS to generate an LZMA compressed archive with ZIP container using only apple provided APIs or other system services?

PS: I don't need full support for all possible ZIP features. I only need to create a simple archive containing some files which can be opened using any zip decompression program.

https://developer.apple.com/documentation/accelerate/compressing_file_system_directories

Accepted Reply

I only need to create a simple archive containing some files which can be opened using any zip decompression program.

While ebainville is correct that you can’t create zip archives using Apple Archive, it is possible to create a basic one using NSFileCoordinator. Here’s a quick example:

let originalURL: URL = … your input directory …
let coordinator = NSFileCoordinator()
let zipIntent = NSFileAccessIntent.readingIntent(with: originalURL, options: [.forUploading])
coordinator.coordinate(with: [zipIntent], queue: .main) { errorQ in
    if let error = errorQ {
        … handle the error …
        return
    }
    let zipURL = zipIntent.url
    … work with the URL before returning …
    … if necessary, copying it elsewhere …
}

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

  • Thank you very much. That was exactly the solution I was looking for!

Add a Comment

Replies

The AppleArchive library produces archives in the AppleArchive format, optionally compressed (with LZMA, LZFSE, LZ4 depending on your needs for speed/compression ratio) or encrypted using our new AppleEncryptedArchive format.

To generate ZIP archives, use third party libraries like libarchive.

I only need to create a simple archive containing some files which can be opened using any zip decompression program.

While ebainville is correct that you can’t create zip archives using Apple Archive, it is possible to create a basic one using NSFileCoordinator. Here’s a quick example:

let originalURL: URL = … your input directory …
let coordinator = NSFileCoordinator()
let zipIntent = NSFileAccessIntent.readingIntent(with: originalURL, options: [.forUploading])
coordinator.coordinate(with: [zipIntent], queue: .main) { errorQ in
    if let error = errorQ {
        … handle the error …
        return
    }
    let zipURL = zipIntent.url
    … work with the URL before returning …
    … if necessary, copying it elsewhere …
}

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

  • Thank you very much. That was exactly the solution I was looking for!

Add a Comment

@eskimo: Your solution would be enough for me, if the parent directory would not be stored in the zip file.

If the URL is .documentDirectory then the extracted zip includes a "Documents" folder.

After some time of researching, I don't think, there is a solution for my problem. I don't want to use a big third party library, only to remove the "Documents" folder.

After some time of researching, I don't think, there is a solution for my problem.

I presume you’re working on iOS here. If so, the .forUploading technique is the only platform API available to you. It has no mechanism to remove that top-level path entry. If you need to do that, the only alternative is to use a third-party zip library (or write such a library yourself, which is not super hard).

Also, I’d appreciate you filing an enhancement request for a full-feature zip archive API. While we have seen similar requests many times before, a fresh bug report will allow you to express your needs in your own terms, and allow iOS engineering to gauge the level of demand.

Please post your bug number, just for the record

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks for you comment.

I talked to the backend guys and they will accept nested files in a ZIP, so we don't need third party libraries.

Add a Comment