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