ProtocolBuffer for Objective-C 运

作者: Xcoder_ | 来源:发表于2016-01-11 14:38 被阅读8723次

    一 、前言

    最近要做一个新的项目需要用到Google的Protocol Buffer,所以最近两天一直在学习这个。在网上看了很多人写的相关博客,发现他们写的配置环境的步骤不尽相同,并且不需要那么复杂,所以就想写一篇最新的文章。 配置环境:mac OS 10.11.1 本文若有叙述错误之处,欢迎指点。

    二 、Protocol Buffer简介

    Protocolbuffer(简称Protobuf或PB)是由Google推出的一种数据交换格式,它独立于语言,独立于平台。Google 提供了三种语言的实现:java、c++ 和 python,每一种实现都包含了相应语言的编译器以及库文件。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。与传统的XML和JSON不同的是,它是一种二进制格式,免去了文本格式转换的各种困扰,并且转换效率非常快,由于它的跨平台、跨编程语言的特点,让它越来越普及,尤其是网络数据交换方面日趋成为一种主流。

    PB目前托管在GitHub,链接地址:https://github.com/google/protobuf,源码的主要功能可以分为两部分:

    PB基础库:完成对象->二进制数据的序列化、二进制数据->对象的反序列化这两个转换过程的支持;
    PB编译器:源码生成器,将PB格式定义文件。proto(PB数据格式的一种定义文件)转换为对象源码(支持C++,JAVA,Python等格式)。

    截止目前PB的最新版本为3.0.0-beta-2,已经加入了对Objective-C的支持(其它之前低版本中也已经有OC扩展支持)。
    在使用cocoaPods的项目里使用pod search ProtocolBuffers进行搜索,搜索结果如下:


    pod search ProtocolBuffers

    注意:本文是以ProtocolBuffers:https://github.com/alexeyxo/protobuf-objc.git 为例进行演示的,因为它生成的代码支持ARC。

    三、Mac环境配置

    安装很简单,对着README操作一遍即可,我贴出自己在终端的命令行。需要输入的命令行依次为:
    1)打开终端,查看mac里面有没有装Homebrew,键入以下命令

    brew -v

    2)如果没有安装Homebrew就使用下面的命令安装

    ruby -e “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)”

    3)安装protobuf编译器和所需的工具

    brew install automake
    brew install libtool
    brew install protobuf

    具体演示:(省略部分命令)

    Last login: Fri Jan  8 09:59:02 on ttys001
    wushangkundeiMac:~ wushangkun$ brew -v
    -bash: brew: command not found
    wushangkundeiMac:~ wushangkun$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
    **==>**** This script will install:**
    /usr/local/bin/brew
    Press RETURN to continue or any other key to abort
    **==>**** /usr/bin/sudo /bin/chmod g+rwx /usr/local/. /usr/local/bin**
    Password:
    **==>**** /usr/bin/sudo /usr/sbin/chown wushangkun /usr/local/. /usr/local/bin**
    **==>**** /usr/bin/sudo /usr/bin/chgrp admin /usr/local/. 
    remote: Counting objects: 3934, done.
    remote: Compressing objects: 100% (3777/3777), done.
    remote: Total 3934 (delta 34), reused 2251 (delta 22), pack-reused 0
    Receiving objects: 100% (3934/3934), 3.43 MiB | 888.00 KiB/s, done.
    Resolving deltas: 100% (34/34), done.
    From https://github.com/Homebrew/homebrew
     * [new branch]      master     -> origin/master
    Checking out files: 100% (3936/3936), done.
    HEAD is now at ef28579 ipfs: update 0.3.10 bottle.
    **==>**** Installation successful!**
    **==>**** Next steps**
    Run `brew help` to get started
    wushangkundeiMac:~ wushangkun$ brew install automake
    **==>**** Installing dependencies for automake: ****autoconf**
    **==>**** Installing automake dependency: ****autoconf**
    ######################################################################## 100.0%
    In order to prevent conflicts with Apple's own libtool we have prepended a "g"
    so, you have instead: glibtool and glibtoolize.
    **==>**** Summary**
    🍺  /usr/local/Cellar/libtool/2.4.6: 69 files, 3.6M
    wushangkundeiMac:~ wushangkun$ brew install protobuf
      mkdir -p /Users/wushangkun/Library/Python/2.7/lib/python/site-packages
      echo 'import site; site.addsitedir("/usr/local/lib/python2.7/site-packages")' >> /Users/wushangkun/Library/Python/2.7/lib/python/site-packages/homebrew.pth
    **==>**** Summary**
    🍺  /usr/local/Cellar/protobuf/2.6.1: 118 files, 6.9M
    wushangkundeiMac:~ wushangkun$ ```
     
    4)以上步骤进行完之后,开始Clone this repository,在桌面新建protobuf-objc 文件夹,在终端里进入该文件下下载代码
    >git clone [https://github.com/alexeyxo/protobuf-objc.git](https://github.com/alexeyxo/protobuf-objc.git)
    
    5)Build it !
    >./scripts/build.sh
    
    具体演示:
    ```objc
    Last login: Fri Jan  8 10:06:15 on ttys001
    wushangkundeiMac:~ wushangkun$ cd /Users/wushangkun/Desktop/protobuf-objc 
    wushangkundeiMac:protobuf-objc wushangkun$ git clone https://github.com/alexeyxo/protobuf-objc.git
    Cloning into 'protobuf-objc'...
    remote: Counting objects: 2788, done.
    remote: Total 2788 (delta 0), reused 0 (delta 0), pack-reused 2788
    Receiving objects: 100% (2788/2788), 32.92 MiB | 683.00 KiB/s, done.
    Resolving deltas: 100% (1761/1761), done.
    Checking connectivity... done.
    wushangkundeiMac:protobuf-objc wushangkun$ ls
    protobuf-objc
    wushangkundeiMac:protobuf-objc wushangkun$ cd protobuf-objc/
    wushangkundeiMac:protobuf-objc wushangkun$ ./scripts/build.sh
    + ./autogen.sh
    glibtoolize: putting auxiliary files in '.'.
    glibtoolize: copying file './ltmain.sh'
     ********* ********* ********* *********
                省略部分。。。
     ********* ********* ********* *********
    mv -f .deps/objectivec-descriptor.pb.Tpo .deps/objectivec-descriptor.pb.Po
    mv -f .deps/objc_message.Tpo .deps/objc_message.Po
    /bin/sh ../../libtool  --tag=CXX   --mode=link g++  -I/usr/local/include -lprotobuf -lprotoc -L/usr/local/lib -o protoc-gen-objc main.o objc_enum_field.o objc_file.o objc_message_field.o objc_enum.o objc_generator.o objc_primitive_field.o objc_extension.o objc_helpers.o objc_field.o objc_message.o objectivec-descriptor.pb.o  
    libtool: link: g++ -I/usr/local/include -o protoc-gen-objc main.o objc_enum_field.o objc_file.o objc_message_field.o objc_enum.o objc_generator.o objc_primitive_field.o objc_extension.o objc_helpers.o objc_field.o objc_message.o objectivec-descriptor.pb.o -Wl,-bind_at_load  -lprotobuf -lprotoc -L/usr/local/lib
    make[2]: Nothing to be done for `all-am'.
    + make install
    Making install in src/compiler
     ../.././install-sh -c -d '/usr/local/bin'
      /bin/sh ../../libtool   --mode=install /usr/bin/install -c protoc-gen-objc '/usr/local/bin'
    libtool: install: /usr/bin/install -c protoc-gen-objc /usr/local/bin/protoc-gen-objc
    make[2]: Nothing to be done for `install-data-am'.
    make[2]: Nothing to be done for `install-exec-am'.
    make[2]: Nothing to be done for `install-data-am'.
    wushangkundeiMac:protobuf-objc wushangkun$ 
    

    运行完成后,最终会生成一个protoc-gen-objc插件,被安装到/usr/local/bin/目录下。如果没有错误的话,以后便可以用这个命令将.proto文件转换为不同语言的源代码文件。

    四、为工程添加PB依赖库#

    添加PB依赖库有两种方式,可以直接把/src/runtime/ProtocolBuffers.xcodeproj作为子项目添加到你的工程里,具体添加方式和注意事项可自行参阅相关文档解决。我现在使用CocoaPod来添加依赖库:
    1)在终端中进入你项目的文件夹,利用vim创建一个名为Podfile的文件,输入i进入vim编辑模式 ;
    2)在你的Podfile中添加:

    platform:ios,’7.0’
    pod ‘ProtocolBuffers’, ‘~> 1.9.9.2’

    按ESC后取消编辑状态,输入:wq回车退出。需要注意的几点:platform那一行,ios三个字母都要小写,而且与前面的冒号之间不能有间隔,后面的版本号也可以不写,但是有些开源库对版本是有要求的,比如要在6.0以上才能运行,遇到这样的开源库就需要写上版本号。

    3)在Terminal中执行 :pod install,完成后退出工程,再次进入就会看到PB依赖库了。以后使用的时候切记如下两点:
    ① 从此以后需要使用Cocoapods生成的 .xcworkspace文件来打开工程,而不是使用以前的.xcodeproj文件。
    ② 每次更改了Podfile文件,都需要重新执行一次pod update命令。

    补充: 当执行pod install之后,除了Podfile,还会生成一个名为Podfile.lock的文件,它会锁定当前各依赖库的版本,之后即使多次执行pod install也不会更改版本,只有执行pod update才会改变Podfile.lock在多人协作的时候,这样可以防止第三方库升级时候造成大家各自的第三方库版本不一致。所以在提交版本的时候不能把它落下,也不要添加到.gitignore中。

    wushangkundeiMac:~ wushangkun$ cd /Users/wushangkun/Desktop/J1Test/J1Hospital 
    wushangkundeiMac:J1Hospital wushangkun$ vim Podfile
    wushangkundeiMac:J1Hospital wushangkun$ pod install
    Updating local specs repositories
    Analyzing dependencies
    Downloading dependencies
    Installing ProtocolBuffers (1.9.9.2)
    Generating Pods project
    Integrating client project
    [!] Please close any current Xcode sessions and use `J1Hospital.xcworkspace` for this project from now on.Sending stats
    
    Pod installation complete! There is 1 dependency from the Podfile and 1 total
    pod installed.
    wushangkundeiMac:J1Hospital wushangkun$ 
    

    注意: 在使用的时候你可能会碰到在代码里导入(#import)头文件没有提示,虽然自己手写出来也能使用,但总觉得不方便。在stackoverflow上找到了解决办法:把pods目录添加到用户头文件检索的路径即可。具体实现方法如下:
    选择target ——- BuildingSettings ——– User Header Search Paths,双击空白区域点击“+”号,输入“$(PODS_ROOT)”,选择recursive(会在相应的目录递归搜索文件)。

    这样设置完成后,再导入第三方库就会有提示了。

    头文件引用修改

    五、使用PB编译器编译.proto文件

    为了验证ProtocolBuffer环境已经搭建好了,我们就做个测试。在桌面建一个prototest文件夹,直接拷贝电脑里一个已有的User.proto文件做测试

    User.proto

    然后通过以下命令来生成model的源代码文件:

    protoc --plugin=/usr/local/bin/protoc-gen-objc User.proto --objc_out="./"

    在当前目录下便可以看到User.pb.h和User.pb.m这两个文件了(需要注意的是生成的代码是支持ARC的!!)。将生成的 .h 和 .m 文件添加到工程中,编译。
    这里会提示找不到GeneratedMessageProtocol。你只需要将其注释掉就行了。

    相关文章

      网友评论

      • helloPluto:没有生成protoc-gen-objc这个插件
      • helloPluto:楼主我操作到./scripts/build.sh执行sh脚本到时候出现大量的报错 这种问题您有遇到过吗
        Xcoder_:@helloPluto ./scripts/build.sh 命令没错,遇到的是什么错
      • 请叫我喵_喵:error: no template named 'numeric_limits'; did you mean
        'std::numeric_limits'?
        } else if (value == -numeric_limits<float>::infinity()) {
        ^~~~~~~~~~~~~~
        std::numeric_limits
        /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/limits:441:28: note:
        'std::numeric_limits' declared here
        class _LIBCPP_TEMPLATE_VIS numeric_limits
        您好,./scripts/build.sh时出现的,error,怎么破啊? 谢谢..
      • br_MorningStar:请问 protobuf-swift 如何搭建环境? .proto文件生成出现protoc-gen-swift: Plugin failed with status code 1 的错误
        Xcoder_:@br_MorningStar OK
        br_MorningStar:问题解决了!我的环境版本过低了!
        Xcoder_:@br_MorningStar https://github.com/alexeyxo/protobuf-swift#how-to-install-protobuf 按照readme中操作的吗
      • cl9000:Are you sure that can build???
      • 洛阳如是:按照你说的步骤 总是出现这个问题
        lgdeMac-mini:~ LJH$ cd /Users/LJH/Desktop/PB文件/protocbuf/原始PB文件
        lgdeMac-mini:原始PB文件 LJH$ protoc --plugin=/usr/local/bin/protoc-gen-objc ProtocOrderInfo.protoc--objc_out="/Users/LJH/Desktop/PB文件/protocbuf/原始PB文件/oc文件"
        Missing output directives.
        lgdeMac-mini:原始PB文件 LJH$

        求解答
        洛阳如是:好了 搞定了 谢谢你了
        洛阳如是:@Xcoder_ lgdeMac-mini:原始PB文件 LJH$ protoc --plugin=/usr/local/bin/protoc-gen-objc ProtocOrderInfo.protoc--objc_out="./oc文件"
        Missing output directives.
        lgdeMac-mini:原始PB文件 LJH$

        还是不行:joy:
        Xcoder_:@洛阳如是 Missing output directives.报的是文件输出路径错误, 我看你的命令,你应该是是想把生成的OC类文件放在“oc文件”这个文件夹下面对吧? 你把最后一句命令改成protoc --plugin=/usr/local/bin/protoc-gen-objc ProtocOrderInfo.proto --objc_out="./oc文件"试试
      • 养頭渔:请问楼主,是从服务器请求下来protocol buffer的数据,然后转模型再使用吗??不知道我理解的对不对??新公司要求使用protocol buffer和xmlrpc,迫切需要学习,还希望能够指明方向,谢谢🙏
        养頭渔:好的,谢谢,会使用了,还是需要慢慢深入了解
        Xcoder_:不好意思现在才看到你的评论,其实protocol buffer就是一种结构化数据格式,可以像json和xml一样的理解,只是它是一种二进制格式,数据转化效率更高,最核心的功能其实还是完成对象到二进制数据的序列化转化,以及二进制数据到对象的反序列化转化过程。使用时你可以理解成model来处理
      • AgoniNemo:楼主,这个库是后台用的吧
        Xcoder_:@AgoniNemo 本文提到的是iOS端用的库,但PB实际上是一种数据存储格式,理论上与平台无关,与语言无关,前端和后台都是可以使用的。
      • DevChan:请教一下
        在./scripts/build.sh 之后出后错误
        如下

        ./google/protobuf/objectivec-descriptor.pb.h:17:2: error: This file was
        generated by an older version of protoc which is
        #error This file was generated by an older version of protoc which is
        ^
        ./google/protobuf/objectivec-descriptor.pb.h:18:2: error: incompatible with your
        Protocol Buffer headers. Please
        #error incompatible with your Protocol Buffer headers. Please
        ^
        ./google/protobuf/objectivec-descriptor.pb.h:19:2: error: regenerate this file
        with a newer version of protoc.
        #error regenerate this file with a newer version of protoc.
        ^
        3 errors generated.
        make[2]: *** [objc_primitive_field.o] Error 1
        3 errors generated.
        make[2]: *** [objc_file.o] Error 1
        6 errors generated.
        make[2]: *** [objc_helpers.o] Error 1
        make[1]: *** [all-recursive] Error 1
        make: *** [all] Error 2
        93b3d3ccb7e6:@DevChan thank you
        DevChan:@明镜亦非台_ 我后来看的这个 http://www.cocoachina.com/bbs/read.php?tid=1716607
        93b3d3ccb7e6:我执行 ./scripts/build.sh 之后也提示这些错误
      • 韶华笑:vim Podfile 也可以使用 pod init
      • 甲丁乙_:你好,此文只有环境配置,有关于API 调用的文章输出么?
        Xcoder_:GitHub上有很多相关的代码吧,可以下载下来看看
      • 谈daxia:楼主,请教一个问题,我按照你的步骤,但是生成*.pbobjc.m报错,引用的头文件在第三方库“ProtocolBuffers”里找不到
        Xcoder_:@谈daxia GPBProtocolBuffers_RuntimeSupport.h这个文件我没有碰到,但是当提示找不到GeneratedMessageProtocol时,只需要将其注释掉就行了,你参考下
        谈daxia:@谈daxia
        这个文件在第三方库“ProtocolBuffers”库里没有,然后生成的*.pbobjc.m文件一直编译通过不了
        谈daxia:@谈daxia
        #import "GPBProtocolBuffers_RuntimeSupport.h"
      • xws留影:你好 ,这是什么原因呢
        xuwenshandeMacBook-Pro:protobuf-objc xuwenshan$ git clone https://github.com/alexeyxo/protobuf-objc.git
        Cloning into 'protobuf-objc'...
        remote: Counting objects: 2896, done.
        error: RPC failed; curl 18 transfer closed with outstanding read data remaining
        fatal: The remote end hung up unexpectedly
        fatal: early EOF
        fatal: index-pack failed
        xuwenshandeMacBook-Pro:protobuf-objc xuwenshan$ git clone https://github.com/alexeyxo/protobuf-objc.git
        Cloning into 'protobuf-objc'...
        remote: Counting objects: 2896, done.
        remote: Total 2896 (delta 0), reused 0 (delta 0), pack-reused 2895
        Receiving objects: 100% (2896/2896), 33.50 MiB | 50.00 KiB/s, done.
        Resolving deltas: 100% (1833/1833), done.
        Checking connectivity... done.
        xuwenshandeMacBook-Pro:protobuf-objc xuwenshan$ ls
        protobuf-objc
        xuwenshandeMacBook-Pro:protobuf-objc xuwenshan$ cd protobuf-objc/
        xuwenshandeMacBook-Pro:protobuf-objc xuwenshan$ ./scripts/build.sh
        + ./autogen.sh
        ./autogen.sh: line 7: autoreconf: command not found
        xuwenshandeMacBook-Pro:protobuf-objc xuwenshan$
        Xcoder_:@xws留影 因为没有安装automake 工具,请使用 brew install automake 安装
      • 节奏不对啊:你好,问一下我最后生成的文件怎么用啊?看着像一个model?
        Xcoder_:@节奏不对啊 你本来就可以把它当做model来用
      • 62055fedc45a:按照楼主的一步步做了 ,在配置mac环境时 ,除了下面的错误,没找到解决办法
        In file included from objc_helpers.cc:27:
        ./google/protobuf/objectivec-descriptor.pb.h:17:2: error: This file was
        generated by an older version of protoc which is
        #error This file was generated by an older version of protoc which is
        ^
        ./google/protobuf/objectivec-descriptor.pb.h:18:2: error: incompatible with your
        Protocol Buffer headers. Please
        #error incompatible with your Protocol Buffer headers. Please
        ^
        ./google/protobuf/objectivec-descriptor.pb.h:19:2: error: regenerate this file
        with a newer version of protoc.
        #error regenerate this file with a newer version of proton.
        Xcoder_:@繁神 第二个链接是一篇博客
        62055fedc45a:@Xcoder_ 谢谢 第一个链接 不是我要的答案 ,第二个链接打开是一个风水网站。
        Xcoder_:@繁神 你参考下这两个链接:
        http://stackoverflow.com/questions/23946203/protobuf-cant-be-serialized

        http://blog.csdn.net/ahbbshenfeng/article/details/52065676
      • d3ff1d98a1aa:问一下我按照你说的做了,却出现User.proto: No such file or directory,请问是怎么回事
        Xcoder_:@swcheng 这个User.proto文件是需要自己创建的,你也可以创建个proto文件测试一下。
      • 囚砚:1.9.11版 只支持 64位
      • 水晶屋_Crystal:很不错,👍☝️
      • shineDeveloper:👍🏻👍🏻👍🏻
      • 拂晓的云:写的很不错,继续努力:+1:

      本文标题:ProtocolBuffer for Objective-C 运

      本文链接:https://www.haomeiwen.com/subject/nkwqkttx.html