本文作者:丁同舟,来自金蝶随手记技术团队。

1、引言

接上篇《金蝶随手记团队的Protobuf应用实践(原理篇)》,本文将以iOS端的Objective-C代码为例,图文并茂地向您菔救绾卧趇OS工程中快速使用Protobuf,希望对你有帮助。

 

学习交流:

(本文已同步发布于:http://www.52im.net/thread-4133-1-1.html

2、系列文章

本文是系列文章中的第 9 篇,本系列总目录如下:

另外:如果您还打算系统地学习IM开发,建议阅读《新手入门一篇就够:从零开发移动端IM》。

3、基本介绍

 

Protobuf(全称 Protocol buffers) 是 Google 提出的一种跨平台、多语言支持且开源的序列化数据格式。相对于类似的 XML 和 JSON,Protobuf 更为小巧、快速和简单。相对于传统的 XML 和 JSON, Protobuf 的优势主要在于:更加小、更加快,其语法目前分为proto2和proto3两种格式。

如果你没不了解Protobuf是什么,建议先阅读本系列的前几篇《Protobuf从入门到精通,一篇就够!》、《快速理解Protobuf的背景、原理、使用、优缺点》、《金蝶随手记团队的Protobuf应用实践(原理篇)》,本篇就不再重复介绍了。

目前 Google 官方的 Protobuf最新 release 版本为3.21.12,但本文写作时用的是3.5.1,以下截图都是基于此版本的环境搭建,如果你使用最新版本,差异并不大,因为只是小版本更新。

关于 Protobuf的使用可以查阅官方文档:https://developers.google.com/protocol-buffers/docs/overview,建议养成阅读文档的习惯。

4、准备工作

4.1环境要求

最低开发环境要求:

  • 1)Objective-C 2.0 Runtime (32bit & 64bit iOS, 64bit OS X)
  • 2)Xcode 7.0 以上版本

注意:Protobuf 出于性能考虑没有使用 ARC,但在 ARC 下是可以使用的。

4.2下载安装

下载 Protobuf 代码包(https://github.com/protocolbuffers/protobuf/releases/tag/v21.12),因文章截图时用的是v3.5.1,所以我这里的为了保持一致选择的是 protobuf-objectivec-3.5.1.tar.gz,版本区别不大,建议依此类推。

4.3解压代码包

编译 Protobuf,这里可能需要安装部分工具:

$ brew install autoconf

$ brew install automake

$ brew install libtool

运行下面脚本进行编译:

$ ./autogen.sh

$ ./configure

$ make

$ makeinstall

检查protobuf是否安装成功:

$ protoc --version

如果成功打印版本号则安装成功:

libprotoc 3.5.1

5、在 iOS 中使用 Protobuf

5.1创建.proto文件

这里使用官方文档上的一份示例数据结构创建Person.proto:

syntax = "proto3";

message Person {

string name = 1;

int32 id = 2;

string email = 3;

enumPhoneType {

MOBILE = 0;

HOME = 1;

WORK = 2;

}

message PhoneNumber {

string number = 1;

PhoneType type = 2;

}

repeated PhoneNumber phone = 4;

}

使用命令行编译Person.proto为objective-c的文件,编译出来的文件为Person.pbobjc.h和Person.pbobjc.m:

protoc Person.proto --objc_out=./

5.2引入 Protobuf 运行时资源

Google 官方的文档提供了两种引入方式,但使用第一种的时候编译不能通过,所以这里选择了第二种。

具体就是:复制protobuf目录下的:objectivec/*.h, objectivec/google/protobuf/*.pbobjc.h, objectivec/google/protobuf/*.pbobjc.m, 以及除去 objectivec/GPBProtocolBuffers.m 后的objectivec/*.m。

这里直接用命令行操作。

首先进入protobuf下objectivec的目录:

$ cdprotobuf-3.5.1/objectivec

然后复制符合规则的文件到指定的工程目录下:

$mkdir~/ProtobufDemo/ProtocolBuffers~/ProtobufDemo/ProtocolBuffers/google~/ProtobufDemo/ProtocolBuffers/google/protobuf

$ cp*.h *.m ~/ProtobufDemo/ProtocolBuffers

$ cpgoogle/protobuf/*.pbobjc.h google/protobuf/*.pbobjc.m ~/ProtobufDemo/ProtocolBuffers/google/protobuf

注意:上面的命令并没有排除 GPBProtocolBuffers.m 文件,引入时需要手动排除。

现在把ProtocolBuffers目录下所有文件以及上面编译出来的 Person.pbobjc.h 和 Person.pbobjc.m 都引入到工程中。

现在工程目录结构大概是长这样:

 

注意:由于protobuf没有使用 ARC,因此需要为所有.m文件加上-fno-objc-arc来关闭 ARC。

结果如下:

提示:需要留意工程中的 Header Search Paths 要增加 $(PROJECT_DIR)/ProtocolBuffers(具体的路径视情况而定)

5.3直接引入 ProtocolBuffers 工程

如果觉得手动引入文件的方式过于复杂,可以直接引入ProtocolBuffers工程作为依赖项。

1)进入解压后的protobuf目录下,复制objective目录下的所有文件到ProtobufDemo/ProtocolBuffers目录下。

2)在ProtobufDemo工程中引入ProtocolBuffers_iOS工程:

3)在Build Phases中加入依赖关系并链接库:

 

4)引入Person.pbobjc.hPerson.pbobjc.m文件并为.m加上-fno-objc-arc

5)修改工程配置中部分路径为 $(PROJECT_DIR)/ProtocolBuffers

5.4运行测试

首先引入头文件:

#import "Person.pbobjc.h"

生成Person对象并进行编码和解码:

Person *p = [[Person alloc] init];

p.id_p = 1;

p.name = @"person1";

p.email = @"123@qq.com";

//encode

NSData*data = [p data];

NSLog(@"Protocol Buffers:\n%@\nData: %@\nData Length: %lu", p, data, data.length);

//decode

Person *newP = [[Person alloc] initWithData:data error:nil];

NSLog(@"Decoded: %@", newP);

运行程序,打印日志如下:

Protocol Buffers:

<;Person 0x60c0000da2b0>: {

name: "person1"

id: 1

email: "123@qq.com"

}

Data: <0a077065 72736f6e 3110011a 0a313233 4071712e 636f6d>

Data Length: 23

Decoded: <;Person 0x6040000d9c90>: {

name: "person1"

id: 1

email: "123@qq.com"

}

6、参考资料

[1] Protobuf 官方开发者指南(中文译版)

[2] Protobuf官方手册

[3] Protobuf从入门到精通,一篇就够!

[4] 如何选择即时通讯应用的数据传输格式

[5] 强列建议将Protobuf作为你的即时通讯应用数据传输格式

[6] APP与后台通信数据格式的演进:从文本协议到二进制协议

[7] 面试必考,史上最通俗大小端字节序详解

[8] 移动端IM开发需要面对的技术问题(含通信协议选择)

[9] 简述移动端IM开发的那些坑:架构设计、通信协议和客户端

[10] 理论联系实际:一套典型的IM通信协议设计详解

[11] 58到家实时消息系统的协议设计等技术实践分享

[12] 金蝶随手记团队的Protobuf应用实践(原理篇)

[13] 新手入门一篇就够:从零开发移动端IM

Coffee time!

(本文已同步发布于:http://www.52im.net/thread-4133-1-1.html

IM通讯协议专题学习(九):手把手教你如何在iOS上从零使用Protobuf的更多相关文章

  1. 2020年,手把手教你如何在CentOS7上一步一步搭建LDAP服务器的最新教程

    同步滚动:关 什么是LDAP 什么是LDAP? 要想知道一个概念,最简单的办法就是wikipedia,当然也可以百科. LDAP全称是轻型目录访问协议(Lightweight Directory Ac ...

  2. 手把手教你如何搭建iOS项目基本框架

    手把手教你如何搭建iOS项目基本框架 今天我们来谈谈如何搭建框架,框架需要做一些什么. 第一步:找到我们的目标我们的目标是让其他开发人员拿到手后即可写页面,不再需要考虑其他的问题. 第二步:我们需要做 ...

  3. SpringCloud学习之手把手教你用IDEA搭建入门项目(三)

    本篇博客是承接上一篇<手把手教你用IDEA搭建SpringCloud入门项目(二)>,不清楚的请到我的博客空间查看后再看本篇博客,上面两篇博客成功创建了一个简单的SpringCloud项目 ...

  4. SpringCloud学习之手把手教你用IDEA搭建入门项目(二)

    本篇博客是承接上一篇<手把手教你用IDEA搭建SpringCloud入门项目(一)>,不清楚的请到我的博客空间查看后再看本篇博客 1)先创建一个Eureka服务注册中心模块,用来作为服务的 ...

  5. SpringCloud学习之手把手教你用IDEA搭建入门项目(一)

    SpringCloud简单搭建 jdk:1.8开发工具:IDEA注:需要了解springcloud 1.创建最简单的Maven项目 1)开始创建一个新的项目 ​ 2)创建一个空模板的maven项目,用 ...

  6. 手把手教你如何在Ubuntu系统中安装Pycharm

    前几天带大家一起安装了Ubuntu14.04系统,没来得及上车的伙伴可以戳这篇文章:手把手教你在VMware虚拟机中安装Ubuntu14.04系统.今天小编带大家一起在Ubuntu14.04中安装Py ...

  7. 手把手教你 在Pytorch框架上部署和测试 关键点人脸检测项目DBFace,成功实现人脸检测效果

    这期教向大家介绍仅仅 1.3M 的轻量级高精度的关键点人脸检测模型DBFace,并手把手教你如何在自己的电脑端进行部署和测试运行,运行时bug解决. 01. 前言 前段时间DBFace人脸检测库横空出 ...

  8. TensorFlow-谷歌深度学习库 手把手教你如何使用谷歌深度学习云平台

    自己的电脑跑cnn, rnn太慢? 还在为自己电脑没有好的gpu而苦恼? 程序一跑一俩天连睡觉也要开着电脑训练? 如果你有这些烦恼何不考虑考虑使用谷歌的云平台呢?注册之后即送300美元噢-下面我就来介 ...

  9. 不用写代码就能实现深度学习?手把手教你用英伟达 DIGITS 解决图像分类问题

    2006年,机器学习界泰斗Hinton,在Science上发表了一篇使用深度神经网络进行维数约简的论文 ,自此,神经网络再次走进人们的视野,进而引发了一场深度学习革命.深度学习之所以如此受关注,是因为 ...

  10. SpringCloud学习之手把手教你用IDEA搭建入门项目【番外篇】(一)

    之前的文章里,我曾经搭建了一个Springcloud项目,但是那个时候我对于SpringCloud架构的很多组件不甚清楚,只是通过查找资料然后动手稀里糊涂的把一个项目成功搭建起来了,其中有很多不合理和 ...

随机推荐

  1. 史上最全 Terraform 入门教程,助你无坑入门!

    在云计算的浪潮中,基础设施管理变得越来越复杂.如何高效地配置和管理云资源,成为了每个开发者和运维工程师必须面对的挑战.Terraform,作为一种强大的基础设施即代码(IaC)工具,为我们提供了一种简 ...

  2. 制作一个ai丛雨(附Python代码)

    绫,再一次,再一次创造一个有你的世界 开一个随笔记录一下我的第一版ai老婆,目前只有普通对话和切换背景的功能(后面可能会加一个选人物功能) 先放一个效果图(看起来还行) 代码和注意事项都放在了下面,应 ...

  3. Nuxt.js 应用中的 nitro:build:before 事件钩子详解

    title: Nuxt.js 应用中的 nitro:build:before 事件钩子详解 date: 2024/11/4 updated: 2024/11/4 author: cmdragon ex ...

  4. Dash 2.18.2版本更新:模式匹配回调性能大提升

    本文示例代码已上传至我的Github仓库:https://github.com/CNFeffery/dash-master Gitee同步仓库地址:https://gitee.com/cnfeffer ...

  5. 3-3 C++ vector类型

    目录 3.3.0 模板(Template) vector说明 模板简介 3.3.1 vector的定义和初始化 初始化的方式 总结初始化 3.3.2 往vector中添加元素 3.3.3 vector ...

  6. DDCA —— 缓存(Cache):缓存体系结构、缓存操作

    1. 存储器层次(The Memory Hierarchy) 1.1 现代系统中的存储器 其中包括L1.L2.L3和DRAM 1.2 存储器的局限 理想存储器的需求如下: 零延迟 容量无限 零成本 带 ...

  7. AT开发HTTP应用:Air780EP低功耗4G模组

    ​ 已经写了一篇基于Air780EP模组AT开发的FOTA远程升级指南,有客户朋友询问能否讲讲HTTP应用部分?本期特别安排--涵盖HTTP基本应用流程.GET/POST/SSL请求示例.断点续传.常 ...

  8. ABP-VNext 用户权限管理系统实战06---多租户集成

    一.集成 1.引用安装包 Volo.Abp.AspNetCore.MultiTenancy 2.配置租户key Configure<AbpAspNetCoreMultiTenancyOption ...

  9. golang 判断文件或文件夹是否存在

    //判断文件是否存在 存在返回 true 不存在返回false func checkFileIsExist(filename string) bool { var exist = true if _, ...

  10. 读书笔记-C#8.0本质论-07

    19. 平台互相操作性和不安全代码 19.1 在托管平台调用非托管代码--P/Invoke模式 CLI通过P/Invoke功能对非托管DLL所导出的函数执行API调用.和类的所有普通方法一样,必须在类 ...