如果 JSON 也不滿足你對數據傳輸體積的要求,還可以考慮一下 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章