GZIP 是為Internet 上使用非常普遍的一種資料壓縮格式,或者說一種檔案格式。使用 GZIP 一來可以減少儲存空間,二來通過網路傳輸檔案時,可以減少傳輸的時間。
大流量的WEB網站常常使用GZIP壓縮技術,將網頁內容壓縮後傳輸到來訪的電腦瀏覽器中顯示出來(一般對純文字內容可壓縮到原大小的40%),大大提高了傳輸速度。
在iOS開發中,我們用戶端也是可以利用 GZIP 來進行資料壓縮的,比如網路請求時,將資料量比較大的參數進行壓縮再傳輸,可以節約流量,提高速度。
一,使用gzip壓縮NSData資料
為方便操作,我們可以使用 NSData+GZIP.swift 這個第三方擴充類(內部使用的是 zlib 庫)。它對 NSData 進行了擴充,使其支援gzip壓縮與解壓縮。
GitHub地址:https://github.com/1024jp/NSData-GZIP
1,配置說明
(1)在Build Phases -> Link Binary With Libraries中點擊加號,添加 libz.tbd 到項目中來
原文:Swift - 使用gzip壓縮NSData資料(附:請求時將JSON資料進行壓縮)
(2)建立橋接標頭檔 bridge.h,將 zlib 庫引用進來
1
#include <zlib.h>
(3)將下載下來的 NSData+GZIP.swift 添加到項目中。把其中的 import zlib 給去掉。
1
//import zlib
2,使用範例
對任何資料進行gzip的壓縮都要先將其轉換成 NSData 類型,下面提供幾個範例大家可以比較下壓縮效率。
(1)字串的壓縮與解壓縮
let str = "歡迎來到www.111cn.net 。航歌,做最好的開放者知識平台。歡迎來到www.111cn.net 。航歌,做最好的開放者知識平台。歡迎來到www.111cn.net 。航歌,做最好的開放者知識平台。歡迎來到www.111cn.net 。"
//未經處理資料
let data:NSData = str.dataUsingEncoding(NSUTF8StringEncoding)!
print("壓縮前的大小:\(data.length)位元組")
//壓縮後資料
let compressedData:NSData = try! data.gzippedData()
print("壓縮後的大小:\(compressedData.length)位元組")
//解壓縮
let originalData = try! compressedData.gunzippedData()
let originalStr:String = NSString(data: originalData,
encoding: NSUTF8StringEncoding) as! String
原文:Swift - 使用gzip壓縮NSData資料(附:請求時將JSON資料進行壓縮)
(2)JSON資料的壓縮與解壓縮
let parameters = [
"name":"hangge",
"age":10,
"score":98.5,
"phones":[123,442,432,132,444],
"numbers":[10,87,69,99,93,123,123],
"address":"中華人民共和國",
"slogan":"www.111cn.net - 做最好的開發人員知識平台",
"others":[
["paramName":"a" , "value":99],
["paramName":"s" , "value":77],
["paramName":"v" , "value":87],
["paramName":"t" , "value":99]
]
]
//未經處理資料
let data = try! NSJSONSerialization.dataWithJSONObject(parameters, options: [])
print("壓縮前的大小:\(data.length)位元組")
//壓縮後資料
let compressedData:NSData = try! data.gzippedData()
print("壓縮後的大小:\(compressedData.length)位元組")
//解壓縮
let originalData = try! compressedData.gunzippedData()
let originalJSON:AnyObject! = try? NSJSONSerialization
.JSONObjectWithData(data, options:.AllowFragments)
(3)檔案的壓縮與解壓縮
let path = NSBundle.mainBundle().pathForResource("readme", ofType: "txt")!
//未經處理資料
let data = NSData(contentsOfFile: path)!
print("壓縮前的大小:\(data.length)位元組")
//壓縮後資料
let compressedData:NSData = try! data.gzippedData()
print("壓縮後的大小:\(compressedData.length)位元組")
//解壓縮
let originalData = try! compressedData.gunzippedData()
二,網路請求時,使用gzip壓縮發送的JSON資料
這裡以使用 Alamofire 這個網路程式庫為例,詳細的配置和使用方法可以看我原來寫的文章(Swift - HTTP網路操作庫Alamofire使用詳解)
假設我們有如下的資料要發送:
let params = [
"name": "www.111cn.net ",
"books": ["Swift","Objective-C","PHP"],
"bar": [
"baz": "qux"
]
]
Alamofire支援將參數使用 JSON 格式編碼進行傳輸:
Alamofire.request(.POST, "http://www.111cn.net /json.php", parameters: params, encoding: .JSON)
但它不支援gzip壓縮,我們可以使用自訂(Custom)的編碼方式來實現。
1,首先,定義一個實現gzip壓縮的自訂編碼方式
let gzipEncoding = ParameterEncoding.Custom { request, parameters in
let jsonEncoding = Alamofire.ParameterEncoding.JSON
let (jsonEncodedRequest, _) = jsonEncoding.encode(request, parameters: parameters)
let mutableRequest = jsonEncodedRequest.mutableCopy() as! NSMutableURLRequest
var gzipEncodingError: NSError? = nil
do {
let gzippedData = try mutableRequest.HTTPBody?.gzippedData()
mutableRequest.HTTPBody = gzippedData
if mutableRequest.HTTPBody != nil {
mutableRequest.setValue("gzip", forHTTPHeaderField: "Content-Encoding")
}
} catch {
gzipEncodingError = error as NSError
}
return (mutableRequest, gzipEncodingError)
}
2,使用gzip編碼方式發送資料
let url = "http://www.111cn.net /json.php"
Alamofire.request(.POST, url , parameters: params, encoding: gzipEncoding)
.responseString { response in
print(response.result.value!)
}
3,服務端接收頁面(json.php)代碼
<?
$gunzip = gzdecode(file_get_contents("php://input"));
$postdata = json_decode($gunzip,TRUE);
echo "收到的書籍有:";
$books= $postdata["books"];
foreach ($books as $book){
echo $book."|";
}
?>
4,用戶端收到的返回訊息如下,說明服務端正常接收並解析了資料。