iOS 上用于 swift3 的原生 zlib inflate/deflate
native zlib inflate/deflate for swift3 on iOS
我希望能够 inflate/deflate Swift3 数据结构。我找到了 GzipSwift,但不清楚我是如何将它提供给我的 iOS 应用程序的。我尝试过的天真的事情包括:
正在将 Data+Gzip.swift
文件复制到我自己的项目中。这然后抱怨所述文件顶部的 import zlib
。我认为这与同一来源的 zlib 目录中的模块映射文件有关。但是我不确定在我自己的项目中重新创建什么或如何重新创建它们。
从 github 克隆存储库,打开 XCode 并内置(基本上按下 运行 按钮)。然后尝试将其作为链接库或框架添加到我自己的项目中。我很确定只选择存储库的顶级目录不是我想做的,但我不知道还能尝试什么。
我在那里找到了一些其他代码,但它似乎过时并且相对于 Swift2。
我最近不得不将那个确切的库和文件添加到我的项目中,经过大量故障排除后终于让它工作了,所以让我来指导您完成这些步骤!
好的
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 项目,然后 select 您的目标
- 5a) 在 Build Phases -> Link Binary with Libraries 中,添加
libz.tbd
- 5b) 在构建设置 -> Swift 编译器 - 搜索路径中,将
$(PROJECT_DIR)/Swiftzlib
非递归添加到导入路径
- 5c) 在 Build Settings -> Other Linker Flags 中,添加
-lz
作为标志
6) Select 你在 Xcode 中的项目(可能不是必需的,但我已经在我的项目中完成了并且它有效)
- 6a) 在构建设置 -> Swift 编译器 - 搜索路径中,将
$(PROJECT_DIR)/Swiftzlib
非递归添加到导入路径
7) 在Data+Gzip.swfit
中,将import Swiftzlib
添加到文件的顶部
8) 清理、构建和 运行!
我在 Apple 的本地 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 感兴趣,您可以改用 .inflate()
和 .deflate()
方法。这将节省 18 个字节,因为不会添加 gzip header。
Swift 5 使用 Compression.
实现
我花了几天时间才意识到我必须删除压缩数据的前 2 个字节。
希望它能帮助到别人。
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, [=10=].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
}
我希望能够 inflate/deflate Swift3 数据结构。我找到了 GzipSwift,但不清楚我是如何将它提供给我的 iOS 应用程序的。我尝试过的天真的事情包括:
正在将
Data+Gzip.swift
文件复制到我自己的项目中。这然后抱怨所述文件顶部的import zlib
。我认为这与同一来源的 zlib 目录中的模块映射文件有关。但是我不确定在我自己的项目中重新创建什么或如何重新创建它们。从 github 克隆存储库,打开 XCode 并内置(基本上按下 运行 按钮)。然后尝试将其作为链接库或框架添加到我自己的项目中。我很确定只选择存储库的顶级目录不是我想做的,但我不知道还能尝试什么。
我在那里找到了一些其他代码,但它似乎过时并且相对于 Swift2。
我最近不得不将那个确切的库和文件添加到我的项目中,经过大量故障排除后终于让它工作了,所以让我来指导您完成这些步骤!
好的
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 项目,然后 select 您的目标
- 5a) 在 Build Phases -> Link Binary with Libraries 中,添加
libz.tbd
- 5b) 在构建设置 -> Swift 编译器 - 搜索路径中,将
$(PROJECT_DIR)/Swiftzlib
非递归添加到导入路径 - 5c) 在 Build Settings -> Other Linker Flags 中,添加
-lz
作为标志
6) Select 你在 Xcode 中的项目(可能不是必需的,但我已经在我的项目中完成了并且它有效)
- 6a) 在构建设置 -> Swift 编译器 - 搜索路径中,将
$(PROJECT_DIR)/Swiftzlib
非递归添加到导入路径
7) 在Data+Gzip.swfit
中,将import Swiftzlib
添加到文件的顶部
8) 清理、构建和 运行!
我在 Apple 的本地 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 感兴趣,您可以改用 .inflate()
和 .deflate()
方法。这将节省 18 个字节,因为不会添加 gzip header。
Swift 5 使用 Compression.
实现我花了几天时间才意识到我必须删除压缩数据的前 2 个字节。 希望它能帮助到别人。
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, [=10=].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
}