Compressing and Decompressing Data with Input and Output Filters

Overview

In this article, you’ll learn how to use InputFilter and OutputFilter to compress and decompress a String instance. The article walks you through the following steps:

Create the sample source data.

Specify the page size, in bytes.

Create the destination buffer.

Create the output filter that will compress the sample source data.

Compress the sample source data and handle any errors.

Create the input filter that will decompress the compressed result from the previous step.

Decompress the compressed data.

Create a string from the decompressed data from the previous step.

Although the article uses a string to provide a simplified example, use this API when working with data that’s streamed to or from memory. For example, when reading from or writing to a file.

If you’re compressing and decompressing data that’s held entirely in memory, consider using compressed(using:) and decompressed(using:). These functions provide a simple API to compress and decompress data in a single step.

Create the Source Data

Typically, your app dynamically generates the source data that it compresses, but for this example, the source data is a hard-coded string:

On return, sourceData contains the UTF-8 representation of the source string.

Specify the Page Size

InputFilter and OutputFilter instances compress and decompress pages of data. Specify the number of bytes in each page that are read from or written to a stream. Smaller values allow your app to report progress or perform other tasks at higher frequencies than larger values. However, larger values allow your app to compress or decompress using fewer steps, possibly in less time.

Compress the Data

Iterate over the source data and call the subdata(in:) method to copy pageSize chunks to subdata. The write(_:) method compresses each chunk and uses the closure specified in the OutputFilter initializer to write the result to compressedData.