Swift libcompression wrapper as an extension for the Data type (GZIP, ZLIB, LZFSE, LZMA, LZ4, deflate, RFC-1950, RFC-1951, RFC-1952)
Data
typeLibrary Version | Swift Version |
---|---|
3.8.0 | 5.7 (Xcode 14) |
3.6.0 | 5.1 (Xcode 11) |
3.5.0 | 5.0 |
3.1.0 | 4.2 |
3.0.0 | 3.0 -> 4.1 |
2.0.1 | < 3.0 |
let raw: Data! = String(repeating: "There is no place like 127.0.0.1", count: 25).data(using: .utf8)
print("raw => \(raw.count) bytes")
for algo: Data.CompressionAlgorithm in [.zlib, .lzfse, .lz4, .lzma] {
let compressedData: Data! = raw.compress(withAlgorithm: algo)
let ratio = Double(raw.count) / Double(compressedData.count)
print("\(algo) => \(compressedData.count) bytes, ratio: \(ratio)")
assert(compressedData.decompress(withAlgorithm: algo)! == raw)
}
Will print something like:
raw => 800 bytes
zlib => 40 bytes, ratio: 20.00
lzfse => 69 bytes, ratio: 11.59
lz4 => 181 bytes, ratio: 4.42
lzma => 100 bytes, ratio: 8.00
.deflate()
and .inflate()
let data: Data! = "https://www.ietf.org/rfc/rfc1951.txt".data(using: .utf8)
let deflated: Data! = data.deflate()
let inflated: Data? = deflated?.inflate()
assert(data == inflated)
.gzip()
and .gunzip()
let data: Data! = "https://www.ietf.org/rfc/rfc1952.txt".data(using: .utf8)
let gzipped: Data! = data.gzip()
let gunzipped: Data? = gzipped.gunzip()
assert(data == gunzipped)
Note: Compressed data in gzip format will always be 18 bytes larger than raw deflated data and will append/perform a crc32 checksum based data integrity test .
.zip()
and .unzip()
let data: Data! = "https://www.ietf.org/rfc/rfc1950.txt".data(using: .utf8)
let zipped: Data! = data.zip()
let unzipped: Data? = zipped.unzip()
assert(data == unzipped)
Note: Compressed data in zip format will always be 6 bytes larger than raw deflated data and will append/perform a adler32 checksum based data integrity test .
The easiest way is using the already installed gzip command line tool. Assuming you have a file called file.txt, after calling
gzip -9 file.txt
the file should have been compressed to file.txt.gz. You can now load and uncompress the contents of your file with:
let compressedData = try? Data(contentsOf: URL(fileURLWithPath: "/path/to/your/file.txt.gz"))
if let uncompressedData = compressedData?.gunzip() {
print(String(data: uncompressedData, encoding: .utf8) ?? "Can't decode UTF-8")
}
Unrelated to compression but for convenience Crc32 and Adler32 methods are also exposed on the Data
type which may come in handy.
let classicExample = "The quick brown fox jumps over the lazy dog".data(using: .utf8)!
let crc32 = classicExample.crc32()
let adler32 = classicExample.adler32()
print("crc32: \(crc32), adler32: \(adler32)")
Will print:
crc32: 414fa339, adler32: 5bdc0fda
To integrate DataCompression into your Xcode project using CocoaPods, add it to your Podfile
:
target '<your_target_name>' do
pod 'DataCompression'
end
Then, run the following command:
$ pod install
You then will need to add import DataCompression
at the top of your swift source files to use the extension.
Note: DataCompression versions < 3.3.0 are not compatible with carthage. That means Swift 5 only.
To integrate DataCompression into your Xcode project using Carthage, add it as a dependency to your Cartfile
. Just add:
github "mw99/DataCompression"
You will then have to add the framework paths in the carthage copy-frameworks
run script phase of your Xcode project.
The paths may differ depending on you have setup your project in relation to Carthage.
$(SRCROOT)/Carthage/Build/iOS/DataCompression.framework
$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/DataCompression.framework
You then will need to add import DataCompression
at the top of your swift source files to use the extension.
To integrate DataCompression into your Xcode project using the swift package manager, add it as a dependency to your Package.swift
file:
import PackageDescription
let package = Package(
name: "<your_package_name>",
dependencies: [
.Package(url: "https://github.com/mw99/DataCompression.git", majorVersion: 3)
]
)
You then will need to add import DataCompression
at the top of your swift source files to use the extension.
The next time you run swift build
, the new dependencies will be resolved.
$ swift build
You only need one file located at Sources/DataCompression.swift
. Drag and drop it into the Xcode project navigator.
3.7.0
to 3.8.0
.unzip()
, because of unaligned pointer loading caused by internal changes in Swift 5.7.3.6.0
to 3.7.0
3.5.0
to 3.6.0
3.4.0
to 3.5.0
3.3.0
to 3.4.0
3.2.0
to 3.3.0
3.1.0
to 3.2.0
3.0.0
to 3.1.0
2.0.X
to 3.0.0
skipCheckSumValidation:
parameter of .unzip()
was removed..LZMA
→ .lzma
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.