GZIP is a very popular data compression format for use on the Internet, or a file format. Using GZIP to reduce storage space, and then transfer files over the network, you can reduce the transmission time.
Large-flow Web sites often use the gzip compression technology, the content of the Web page compressed into a visiting Computer browser display (generally plain text content can be compressed to the original size of 40%), greatly improve the transmission speed.
In the development of iOS, our clients can also use GZIP to do data compression, such as network request, the data volume than large parameters for compression and retransmission, can save traffic, improve speed.
First, use gzip to compress nsdata data
For ease of operation, we can use nsdata+gzip.swift this third party extension class (internal use is zlib library). It expands the NSData to support gzip compression and decompression.
GitHub Address: Https://github.com/1024jp/NSData-GZIP
1, configuration instructions
(1) Click the plus sign in build phases-> Link Binary with libraries to add LIBZ.TBD to the project
(2) Create Bridge header file Bridge.h, zlib Library Reference in
#include <zlib.h>
(3) Add the downloaded Nsdata+gzip.swift to the project. Remove the import zlib.
//Import zlib
2, using the sample
The gzip compression of any data has to be converted to the NSData type first, with a few examples to compare the compression efficiency below.
(1) Compression and decompression of strings
Let str = "Welcome to hangge.com. Air song, do the best opener knowledge platform. Welcome to hangge.com. Hang Ge, do the best opener knowledge platform. Welcome to hangge.com. Song, the best open knowledge platform. Welcome to hangge.com."
//Raw data
Let data = str.data(using: String.Encoding.utf8)!
Print("size before compression: \(data.count) bytes")
/ / compressed data
Let compressedData = try! data.gzipped()
Print("compressed size: \(compressedData.count) bytes")
//unzip
Let originalData = try! compressedData.gunzipped()
Let originalStr = String(data: originalData, encoding: String.Encoding.utf8)
(2) Compression and decompression of JSON data
Let parameters:[String : Any] = [
"name": "hangge",
"age": 10,
"score": 98.5,
"phones": [123,442,432,132,444],
"numbers": [10,87,69,99,93,123,123],
"address": "People's Republic of China",
"slogan": "hangge.com - the best developer knowledge platform",
"others":[
["paramName":"a" , "value":99],
["paramName":"s" , "value":77],
["paramName":"v" , "value":87],
["paramName":"t" , "value":99]
]
]
//Raw data
Let data = try! JSONSerialization.data(withJSONObject: parameters, options: [])
Print("size before compression: \(data.count) bytes")
/ / compressed data
Let compressedData = try! data.gzipped()
Print("compressed size: \(compressedData.count) bytes")
//unzip
Let originalData = try! compressedData.gunzipped()
Let originalJSON = try? JSONSerialization
.jsonObject(with: originalData, options:.allowFragments)
(3) Compression and decompression of files
Let path = Bundle.main.path(forResource: "readme", ofType: "txt")!
Let url = URL(fileURLWithPath: path)
//Raw data
Let data = try! Data(contentsOf: url)
Print("size before compression: \(data.count) bytes")
/ / compressed data
Let compressedData = try! data.gzipped()
Print("compressed size: \(compressedData.count) bytes")
//unzip
Let originalData = try! compressedData.gunzipped()
Second, when a network request, use gzip compression to send the JSON data
Here to use Alamofire this network library for example, detailed configuration and use methods can look at my original article (Swift-http Network Operation library Alamofire use detailed)
Suppose we have the following data to send:
let params = [
"Name": "Www.111cn.net",
"Books": ["Swift", "Objective-c", "PHP"],
"Bar": [
"Baz": "Qux"
]
]
Alamofire supports the transfer of parameters using JSON format encoding:
let url = "http://www.hangge.com/json.php"
Alamofire.request(url, method: .post, parameters: params, encoding: JSONEncoding.default)
However, it does not support gzip compression and can be implemented using custom encoding.
1, define a custom encoding that enables GZIP compression
Struct JSONGzipEncoding: ParameterEncoding {
/ / Return a `JSONGzipEncoding` instance object
Public static var `default`: JSONGzipEncoding { return JSONGzipEncoding() }
/ / Implement the encoding method
Func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws
-> URLRequest {
Var urlRequest = urlRequest.urlRequest!
/ / First json coding
urlRequest = try JSONEncoding().encode(urlRequest, with: parameters)
/ / Then gzip compression
Let gzippedData = try urlRequest.httpBody?.gzipped()
urlRequest.httpBody = gzippedData
If urlRequest.httpBody != nil {
urlRequest.setValue("gzip", forHTTPHeaderField: "Content-Encoding")
}
Return urlRequest
}
}
2, send data using gzip encoding
let url = "http://hangge.com/json.php"
Alamofire.request(url, method: .post, parameters: params, encoding: JSONGzipEncoding.default)
.responseString { response in
print(response.result.value!)
}
3, service-side receive page (json.php) code
<?
$gunzip = gzdecode(file_get_contents("php://input"));
$postdata = json_decode($gunzip,TRUE);
Echo "The books received are:";
$books= $postdata["books"];
Foreach ($books as $book){
Echo $book."|";
}
?>
4, the client received a return message such as the following, indicating that the server received and resolved the normal data.