如果 JSON 也不滿足你對數據傳輸體積的要求,還可以考慮一下 protobuf

MartinShimp 7年前發布 | 29K 次閱讀 JSON iOS開發 移動開發 protobuf

protobuf 是 Google 推出的一種數據傳輸格式,采用純二進制數據傳輸,傳輸體積比 JSON 要小很多。

數據傳輸格式

如果你在開發一款 APP,就免不了要讀取服務端的數據。 現在大家比較流行的做法是使用 JSON 作為數據傳輸格式。 JSON 的好處是數據結構清晰,并且可讀性強。相比 XML 數據的體量要小很多。

正是這么多的優點,讓 JSON 幾乎成為了現在數據傳輸格式的標配。

接下來我們進入正題,說說我們這次要介紹的 protobuf。 既然 JSON 那么多優點,為什么還要出來個 protobuf 呢? 雖然 JSON 的數據體量已經比較小了,但它的整體文本結構還是純文本形式的。也就是說在傳輸數據的時候,會一并把數據的組織格式也進行傳輸。比如:

{
    "name" : "swift",
    "age" : 23
}

上面是一個簡單的 JSON 對象。 雖然這個數據的格式已經很簡單了,但它依然把屬性名稱,比如 name 和 age, 以及大括號,引號這些用于表示數據格式的信息也進行傳輸了。

當然,如果你對 APP 的網絡傳輸沒那么高的要求,這也不成問題。 但如果有一天你想提升你 APP 的傳輸性能了,那么 protobuf 就是你可以采納的解決方案之一了。

protobuf

protobuf 的全稱是 Protocol Buffer。 protobuf 的主要特性就是二進制傳輸,并且它只傳輸”數據”,不會傳輸數據的”格式”。要使用 protobuf, 首先要定義數據的格式, 通過一個擴展名為 .proto 的文件來定義:

syntax = "proto3";

message Person {
    string name = 1;
    int32 age = 2;
}

這個 proto 文件看起來應該很熟悉。 第一行 syntax 定義了這個文件的語法格式。 因為 protobuf 有 2 和 3 兩個主流版本,這里指定當前文件用的是哪個版本。

接下來就是消息格式的定義了,顯而易見,我們定義了 Person 類型,有兩個屬性 name 和 age。 分別是 string 和 int32 類型。

協議格式定義好之后,用 protobuf 自帶的命令可以將協議文件轉換成 objective-c 的類文件:

$ protoc ./person.proto --objc_out ./

上面這個命令是把當前目錄的 person.proto 文件,轉換成 objc 類,然后輸出到當前目錄。成功運行命令后, 我們就會看到兩個生成的代碼文件了,把它們添加到 XCode 工程中即可。

然后我們就可以在代碼中直接使用 Person 類來進行數據交互了:

Person *person = [[Person alloc] init];
person.name = @"swift";
person.age = 22;

NSData *dataWillSend = [person data];

這里可以看到, Person 類的屬性和我們之前在 person.proto 中定義的完全一樣,它還提供了一個 data 方法,將數據直接序列化成 NSData, 這樣我們在發送請求的時候,直接發送這個 NSData 就可以了。

如果是從服務端接收的請求返回, Person 類同樣提供了解析數據的方法:

[Person parseFromData:dataWillReceived error:nil];

這樣,我們的數據傳輸就真正做到了只發送數據本身,而不發送數據的格式了。因為數據的格式和解析規則都保留在客戶端和服務端本地了。

總結

protobuf 給我們提供的就是這樣一個更高效的數據傳輸協議。它自然有利有弊。 好處就是我們前面說的,讓數據的傳輸效率最大化。相比 JSON 數據格式,它的數據傳輸體積更小。它只傳輸數據本身,不會傳輸格式信息。

但同樣,它也有一些不便,比如 .proto 數據格式文件必須同時在客戶端和服務端保存。 如果數據格式發生變化,兩邊同時調整的代價就會比較大。

總的來說,protobuf 給我們提供了一個新的選擇,如果你的 APP 已經到了需要非常細致的優化性能的時候,那么 protobuf 也是一個不錯的方案。 關于 protobuf 更詳細完整的文檔,大家可以參考它的 Github 主頁: https://github.com/google/protobuf

如果你覺得這篇文章有幫助,還可以關注微信公眾號 swift-cafe,會有更多我的原創內容分享給你~

 

來自:http://swiftcafe.io/2017/02/26/protobuffer/

 

 本文由用戶 MartinShimp 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!