在iOS上为Swift 3提供本地的zlib解压缩/压缩功能。

8
我想要能够膨胀/收缩Swift 3的数据结构。我找到了GzipSwift,但是不清楚如何将它添加到我的iOS应用中。我尝试过的一些幼稚的方法包括:
  1. Data+Gzip.swift文件复制到我的项目中。然后该文件会抱怨顶部的import zlib语句。我认为这与相同源文件夹中zlib目录中的modulemap文件有关。但我不确定如何在我的项目中重新创建它们。
  2. 从GitHub克隆了存储库,打开XCode并进行构建(基本上是按下运行按钮)。然后尝试将其作为链接库或框架添加到我的项目中。我相当确定只选择存储库的顶级目录不是我想要做的事情,但我不知道还能尝试什么。
我发现了一些其他的代码,但看起来已过时,并且是针对Swift 2的。
4个回答

19

Swift 5使用Compression的实现。

花了我几天时间才意识到我必须删除压缩数据的前两个字节。希望能帮助其他人。

import Foundation
import Compression

func decompress(_ data: Data) -> String {
    let size = 8_000_000
    let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: size)
    let result = data.subdata(in: 2 ..< data.count).withUnsafeBytes ({
        let read = compression_decode_buffer(buffer, size, $0.baseAddress!.bindMemory(to: UInt8.self, capacity: 1),
                                             data.count - 2, nil, COMPRESSION_ZLIB)
        return String(decoding: Data(bytes: buffer, count:read), as: UTF8.self)
    }) as String
    buffer.deallocate()
    return result
}

1
@The_Androctonus size 是分配缓冲区的大小,即保留要使用的字节数量。如果您不知道未压缩时期望多少字节,则通常可以使用较大的数字。 - vicegax
我花了几天时间找到了这个相同的东西... 感谢这个答案。 - Cinn
我本来会为了解决这个问题而抓狂的!感谢@vauxhall! - Rafthecalf
你救了我的命!经过几天的寻找,我终于找到了这个答案。但我在想为什么? - Roger
太棒了,谢谢。现在这个功能已经原生支持了:compressed(using:)decompressed(using:) - amq

16

我最近不久也刚刚把这个库和文件添加到我的项目中,在经过大量的故障排除之后,终于让它正常工作了,所以让我带着您完成以下步骤吧!

好的,接下来:

1)在Finder中前往您项目的顶级目录,并创建一个名为Swiftzlib或者其他您想要导入命名的模块名称的新文件夹。(我们将会将zlib库添加为一个模块,就像导入Foundation或者其他一些模块一样)。需要澄清的是,这个Swiftzlib文件夹最终将成为包含您的*.xcodeproj*.xcworkspace文件的同一个目录的子目录。

2)在您创建的文件夹里面,再创建两个文件:

  • include.h
  • module.modulemap

3)在您的include.h文件中,输入以下内容:

#include<zlib.h>

4) 在你的module.modulemap文件中输入以下内容:

module Swiftzlib [system] {
    header "include.h"
    export *
}

其中,Swiftzlib与您创建的文件夹名称相同。

5) 打开Xcode项目并选择目标

  • 5a)在Build Phases -> Link Binary with Libraries中,添加libz.tbd
  • 5b) 在Build Settings - > Swift Compiler - Search Paths中,将$(PROJECT_DIR)/Swiftzlib非递归地添加到导入路径中
  • 5c) 在Build Settings - > Other Linker Flags中,添加-lz作为标志

6)在Xcode中选择您的项目(可能不是必要的,但我已在我的项目中执行并且有效)

  • 6a)在Build Settings -> Swift Compiler - Search Paths中,将$(PROJECT_DIR)/Swiftzlib非递归地添加到导入路径中

7)在中,将import Swiftzlib添加到文件顶部

8)清理、构建、运行!


我按照你的步骤做了,但是没有成功...请指导我...在我的Data_Gzip.swift文件中找不到Error和Data类。 - H Raval
@HRaval,这听起来像是您在非Swift 3项目中导入了Data+Gzip.swift类的Swift 3版本。 - pbush25
我正在使用Swift 2.3。 - H Raval
@HRaval,你需要获取Swift 2.3版本的NSData+gzip而不是Data+Gzip。 - pbush25
非常感谢。您能否提供一个链接给我? - H Raval
显示剩余7条评论

4
我维护一个围绕苹果原生的libcompression框架的小型Swift 3+包装器,位于:

https://github.com/mw99/DataCompression

gzip用法示例:
let data: Data! = "https://www.ietf.org/rfc/rfc1952.txt".data(using: .utf8)
let gzipped: Data! = data.zip()
let gunzipped: Data? = gzipped.unzip()
assert(data == gunzipped)

但如果你只对经典的压缩和解压感兴趣,你可以使用 .inflate().deflate() 方法。这样可以节省18个字节,因为不会添加gzip头。


请在此处添加链接的详细信息。 - Panther
我仍然在使用deflate()时遇到了不正确的头部检查错误。 - jaytrixz

0

我根据 @vauxhall 的回答制作了一个小的 SPM 扩展

https://github.com/mezhevikin/Zlib

import Zlib

// Decompressed data
print(data.decompressed)

// Decompressed string
print(data.decompressedString)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接