Swift - zip/unzip 内存中的数据,无需任何文件系统交互

Wow*_*nch 5 macos zip foundation swift zipfoundation

我的代码需要解析大量 JSON 文件,这些文件托管在 GitHub 上,并且只能捆绑为 1 个 ZIP 文件。因为 ZIP 文件只有大约 80 MB,所以我想将整个解压缩操作保留在内存中。

我能够将 ZIP 文件作为Data?变量加载到内存中,但我无法找到一种方法来解压缩Data内存中的变量,然后将解压缩的文件/数据分配给其他一些变量。我尝试过使用ZIP Foundation,但其Archive类型的初始值设定项仅采用文件 URL。我没有尝试Zip,但它的文档显示它也需要文件 URL。

这是我的代码:

import Cocoa
import Alamofire

class ViewController: NSViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let zipURL = URL(string: "https://github.com/KSP-CKAN/CKAN-meta/archive/master.zip")!

        AF.request(zipURL).validate().responseData { response in
            var zipData: Data? = response.data
            //  Here I want to unzip `zipData` after unwrapping it.
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

我还考虑过将Data变量作为文件传递,但未能找到方法。


更新(2019-12-01 05:00)

根据ZIPFoundation 上的拉取请求线程,我正在寻找的功能将包含在下一个版本中。我尝试使用该功能的贡献者的 fork,但不知何故 Swift Package Manager 不允许这样做。

在发现这一点之前,我尝试通过PythonKitzipfile提供的 Swift-Python 互操作性来使用 Python 的库,但没有成功,因为Swift 中的 Foundation 无法转换为类型。DataPythonObject

Apple 的压缩框架看起来也很有前途,但它似乎对压缩文件有 1 MB 的软限制。我需要的压缩文件大约有 80 MB,远大于 1 MB。

到目前为止,ZIPFoundation 是我最有希望的解决方案。


更新(2019-12-01 06:00)

在另一次尝试中,我能够通过 Swift Package Manager 安装microtherion 的分支。以下代码应该可以工作:

import Cocoa
import Alamofire
import ZIPFoundation

... //  ignoring irrelevant parts of the code


    let zipURL = URL(string: "https://github.com/KSP-CKAN/CKAN-meta/archive/master.zip")!

    AF.request(zipURL).validate().responseData { response in

        //  a Data variable that holds the raw bytes
        var zipData: Data? = response.data

        //  an Archive instance created with the Data variable
        var zipArchive = Archive(data: zipData!, accessMode: .read)

        //  iterate over the entries in the Archive instance, and extract each entry into a Data variable
        for entry in zipArchive! {
            var unzippedData: Data
            do {
                _ = try zipArchive?.extract(entry) {unzippedData($0)}
            } catch {
                ...
            }
            ...
        }

    }

Run Code Online (Sandbox Code Playgroud)