swift

ProtocolBuffer在Swift中的应用

2019-02-16  本文已影响3人  阿凡提说AI

一、ProtocolBuffer简介

ProtocolBuffer(也称PB/GPB): google 的一种数据交换的格式, 可以实现跨平台, 方便的序列化&反序列化

二、安装

安装过程可以参考:https://github.com/alexeyxo/protobuf-swift

brew install protobuf-swift

如果没有安装brew可以先执行以下指令

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

三、ProtocolBuffer在Swift中的应用

syntax = "proto2";

message Person {
    required int64 id = 1;
    required string name = 2;
    optional string email = 3;
}

1.syntax = "proto2"; 为定义使用的版本号, 目前常用版本proto2/proto3
2.message是消息定义的关键字,等同于C++/Swift中的struct/class,或是Java中的class
3.Person为消息的名字,等同于结构体名或类名
4.required前缀表示该字段为必要字段,既在序列化和反序列化之前该字段必须已经被赋值
5.optional前缀表示该字段为可选字段, 既在序列化和反序列化时可以没有被赋值
6.repeated通常被用在数组字段中
7.int64和string分别表示整型和字符串型的消息字段
8.id和name和email分别表示消息字段名,等同于Swift或是C++中的成员变量名
9.标签数字1和2则表示不同的字段在序列化后的二进制数据中的布局位置, 需要注意的是该值在同一message中不能重复

enum UserStatus {
    OFFLINE = 0;  //表示处于离线状态的用户
    ONLINE = 1;   //表示处于在线状态的用户
}

message UserInfo {
    required int64 acctID = 1;
    required string name = 2;
    required UserStatus status = 3;
}
enum UserStatus {
    OFFLINE = 0;
    ONLINE = 1;
}
message UserInfo {
    required int64 acctID = 1;
    required string name = 2;
    required UserStatus status = 3;
}

message LogonRespMessage {
    required LoginResult logonResult = 1;
    required UserInfo userInfo = 2;
}
protoc xxx.proto --swift_out="./"

四、案例:直播中的聊天室
IMMessage.proto

syntax = "proto2";

message UserInfo {
    required string name = 1;
    required int64 level = 2;
}

message TextMessage {
    required UserInfo user = 1;
    required string text = 2;
}

message GiftMessage {
    required UserInfo user = 1;
    required string giftname = 2;
    required string giftURL = 3;
    required string giftCount = 4;
}

进入IMMessage.proto所在的路径,执行

protoc IMMessage.proto --swift_out="./"

生成Immessage.proto.swift
然后在应用中,这样使用

func sendJoinRoom() {
        // 1.获取消息的长度
        let msgData = (try! userInfo.build()).data()
        
        // 2.发送消息
        sendMsg(data: msgData, type: 0)
    }
    
    func sendLeaveRoom() {
        // 1.获取消息的长度
        let msgData = (try! userInfo.build()).data()
        
        // 2.发送消息
        sendMsg(data: msgData, type: 1)
    }
    
    func sendTextMsg(message : String) {
        // 1.创建TextMessage类型
        let chatMsg = ChatMessage.Builder()
        chatMsg.text = message
        
        // 2.获取对应的data
        let chatData = (try! chatMsg.build()).data()
        
        // 3.发送消息到服务器
        sendMsg(data: chatData, type: 2)
    }
    
    func sendGiftMsg(giftName : String, giftURL : String, giftCount : Int) {
        // 1.创建GiftMessage
        let giftMsg = GiftMessage.Builder()
        giftMsg.giftname = giftName
        giftMsg.giftUrl = giftURL
        giftMsg.giftcount = Int32(giftCount)
        
        // 2.获取对应的data
        let giftData = (try! giftMsg.build()).data()
        
        // 3.发送礼物消息
        sendMsg(data: giftData, type: 3)
    }
    
    func sendMsg(data : Data, type : Int) {
        // 1.将消息长度, 写入到data
        var length = data.count
        let headerData = Data(bytes: &length, count: 4)
        
        // 2.消息类型
        var tempType = type
        let typeData = Data(bytes: &tempType, count: 2)
        
        // 3.发送消息
        let totalData = headerData + typeData + data
        tcpClient.send(data: totalData)
    }
上一篇 下一篇

猜你喜欢

热点阅读