Swift Protobuf 初探 —— 繼 XML 後,JSON 也要被淘汰了嗎

Binboy_王興彬發表於2019-03-04

Protocol Buffers 是什麼?

Protocol buffers are Google`s language-neutral, platform-neutral, extensible mechanism for serializing structured data – think XML, but smaller, faster, and simpler. —— Google Official Definition

簡單地說,Protocol Buffers 就是一種輕量高效的結構化資料交換格式,語言無關、平臺無關、可擴充套件。理解地直白粗暴一點就是“更厲害更面向未來的 JSON”,那麼接下來我們就將通過 Swift 官方實現的 Protobuf 來一探究竟。

Swift Protobuf

從去掉軟盤到幹掉光碟機,從擯棄 Flash 推廣 HTML5 ,到現在乾脆把標準音訊介面抹去,蘋果一向善於引領科技時尚,那麼在面向未來的資料交換格式上自然不會落後,因此 Swift Protobuf 應運而生。

開始動手嘗試吧

本來我想拿照官方示例來走一遍的,但這次正好有個絕佳的示例,既有客戶端又有服務端,可以“做”享其成一次,其中還涉及到 Go 語言,趁此機會也可以把玩一番。

ProtoBufExample 克隆至本地

➜ git clone https://github.com/KyoheiG3/ProtobufExample.git
➜ cd ProtobufExample複製程式碼

配置客戶端

➜ cd ./ProtobufClient
➜ pod install複製程式碼

初始化服務端

➜ cd ./ProtobufServer
➜ swift build
// 建立工程檔案,以便在 Xcode 下編輯
➜ swift package generate-xcodeproj複製程式碼

啟動 API

➜ ./.build/debug/api複製程式碼

配置並啟動服務 with Go

➜ go get github.com/golang/protobuf/protoc-gen-go
➜ go run server/api.go複製程式碼
  • 有必要的話,先下載安裝 Go 語言環境,並配置 $GOPATH
    ➜ mkdir ~/go
    ➜ export GOPATH=~/go
    ➜ export PATH=$PATH:$GOPATH/bin複製程式碼

體會 .proto

安裝 protobuf

➜ brew install protobuf複製程式碼

用 Swift 編譯 protobuf

➜ cd ./ProtobufServer
➜ swift build
➜ protoc --plugin=protoc-gen-swift=.build/debug/protoc-gen-swift --swift_out=../protos --proto_path=../protos ../protos/DataModel.proto複製程式碼

此時我們就能在 protos 這個輸出目錄下就可以看到剛剛生成的對應 .pb.swift 檔案了。

/*
 * Generated by the protocol buffer compiler.
 * Source: DataModel.proto
 */

import Foundation
import SwiftProtobuf

public struct BookInfo: ProtobufGeneratedMessage {
  public var swiftClassName: String {return "BookInfo"}
  public var protoMessageName: String {return "BookInfo"}
  public var protoPackageName: String {return ""}
  public var jsonFieldNames: [String: Int] {return [
    "id": 1,
    "title": 3,
    "author": 2,
  ]}
  public var protoFieldNames: [String: Int] {return [
    "id": 1,
    "title": 3,
    "author": 2,
  ]}

  public var id: Int64 = 0

  public var title: String = ""

  public var author: String = ""

  public init() {}
  ......
  ......
  ......
  if !keys.isEmpty {
      try visitor.visitMapField(fieldType: ProtobufMap<ProtobufString,ProtobufString>.self, value: keys, protoFieldNumber: 4, protoFieldName: "keys", jsonFieldName: "keys", swiftFieldName: "keys")
    }
  }

  public func _protoc_generated_isEqualTo(other: MyLibrary) -> Bool {
    if id != other.id {return false}
    if name != other.name {return false}
    if books != other.books {return false}
    if keys != other.keys {return false}
    return true
  }
}複製程式碼

其中還包括了一些對 JSON 的友好相容,感興趣的朋友可以自己動手玩一下。

探索更多

Google Protocol Buffers

Swift Protobuf

ProtobufExample – Github

深入理解 ProtoBuf

Google Protocol Buffer 的使用和原理 – IBM

相關文章