一 、前言
最近要做一個(gè)新的項(xiàng)目需要用到Google的Protocol Buffer,所以最近兩天一直在學(xué)習(xí)這個(gè)。在網(wǎng)上看了很多人寫的相關(guān)博客,發(fā)現(xiàn)他們寫的配置環(huán)境的步驟不盡相同,并且不需要那么復(fù)雜,所以就想寫一篇最新的文章。 配置環(huán)境:mac OS 10.11.1 本文若有敘述錯(cuò)誤之處,歡迎指點(diǎn)。
二 、Protocol Buffer簡(jiǎn)介
Protocolbuffer(簡(jiǎn)稱Protobuf或PB)是由Google推出的一種數(shù)據(jù)交換格式,它獨(dú)立于語(yǔ)言,獨(dú)立于平臺(tái)。Google 提供了三種語(yǔ)言的實(shí)現(xiàn):java、c++ 和 python,每一種實(shí)現(xiàn)都包含了相應(yīng)語(yǔ)言的編譯器以及庫(kù)文件。可以把它用于分布式應(yīng)用之間的數(shù)據(jù)通信或者異構(gòu)環(huán)境下的數(shù)據(jù)交換。與傳統(tǒng)的XML和JSON不同的是,它是一種二進(jìn)制格式,免去了文本格式轉(zhuǎn)換的各種困擾,并且轉(zhuǎn)換效率非???,由于它的跨平臺(tái)、跨編程語(yǔ)言的特點(diǎn),讓它越來(lái)越普及,尤其是網(wǎng)絡(luò)數(shù)據(jù)交換方面日趨成為一種主流。
PB目前托管在GitHub,鏈接地址:https://github.com/google/protobuf,源碼的主要功能可以分為兩部分:
PB基礎(chǔ)庫(kù):完成對(duì)象->二進(jìn)制數(shù)據(jù)的序列化、二進(jìn)制數(shù)據(jù)->對(duì)象的反序列化這兩個(gè)轉(zhuǎn)換過(guò)程的支持;
PB編譯器:源碼生成器,將PB格式定義文件。proto(PB數(shù)據(jù)格式的一種定義文件)轉(zhuǎn)換為對(duì)象源碼(支持C++,JAVA,Python等格式)。
截止目前PB的最新版本為3.0.0-beta-2,已經(jīng)加入了對(duì)Objective-C的支持(其它之前低版本中也已經(jīng)有OC擴(kuò)展支持)。
在使用cocoaPods的項(xiàng)目里使用pod search ProtocolBuffers進(jìn)行搜索,搜索結(jié)果如下:
注意:本文是以ProtocolBuffers:https://github.com/alexeyxo/protobuf-objc.git 為例進(jìn)行演示的,因?yàn)樗傻拇a支持ARC。
三、Mac環(huán)境配置
安裝很簡(jiǎn)單,對(duì)著README操作一遍即可,我貼出自己在終端的命令行。需要輸入的命令行依次為:
1)打開(kāi)終端,查看mac里面有沒(méi)有裝Homebrew,鍵入以下命令
brew -v
2)如果沒(méi)有安裝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)以上步驟進(jìn)行完之后,開(kāi)始Clone this repository,在桌面新建protobuf-objc 文件夾,在終端里進(jìn)入該文件下下載代碼
>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$
運(yùn)行完成后,最終會(huì)生成一個(gè)protoc-gen-objc插件,被安裝到/usr/local/bin/目錄下。如果沒(méi)有錯(cuò)誤的話,以后便可以用這個(gè)命令將.proto文件轉(zhuǎn)換為不同語(yǔ)言的源代碼文件。
四、為工程添加PB依賴庫(kù)#
添加PB依賴庫(kù)有兩種方式,可以直接把/src/runtime/ProtocolBuffers.xcodeproj作為子項(xiàng)目添加到你的工程里,具體添加方式和注意事項(xiàng)可自行參閱相關(guān)文檔解決。我現(xiàn)在使用CocoaPod來(lái)添加依賴庫(kù):
1)在終端中進(jìn)入你項(xiàng)目的文件夾,利用vim創(chuàng)建一個(gè)名為Podfile的文件,輸入i進(jìn)入vim編輯模式 ;
2)在你的Podfile中添加:
platform:ios,’7.0’
pod ‘ProtocolBuffers’, ‘~> 1.9.9.2’
按ESC后取消編輯狀態(tài),輸入:wq回車退出。需要注意的幾點(diǎn):platform那一行,ios三個(gè)字母都要小寫,而且與前面的冒號(hào)之間不能有間隔,后面的版本號(hào)也可以不寫,但是有些開(kāi)源庫(kù)對(duì)版本是有要求的,比如要在6.0以上才能運(yùn)行,遇到這樣的開(kāi)源庫(kù)就需要寫上版本號(hào)。
3)在Terminal中執(zhí)行 :pod install,完成后退出工程,再次進(jìn)入就會(huì)看到PB依賴庫(kù)了。以后使用的時(shí)候切記如下兩點(diǎn):
① 從此以后需要使用Cocoapods生成的 .xcworkspace文件來(lái)打開(kāi)工程,而不是使用以前的.xcodeproj文件。
② 每次更改了Podfile文件,都需要重新執(zhí)行一次pod update命令。
補(bǔ)充: 當(dāng)執(zhí)行pod install之后,除了Podfile,還會(huì)生成一個(gè)名為Podfile.lock的文件,它會(huì)鎖定當(dāng)前各依賴庫(kù)的版本,之后即使多次執(zhí)行pod install也不會(huì)更改版本,只有執(zhí)行pod update才會(huì)改變Podfile.lock在多人協(xié)作的時(shí)候,這樣可以防止第三方庫(kù)升級(jí)時(shí)候造成大家各自的第三方庫(kù)版本不一致。所以在提交版本的時(shí)候不能把它落下,也不要添加到.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$
注意: 在使用的時(shí)候你可能會(huì)碰到在代碼里導(dǎo)入(#import)頭文件沒(méi)有提示,雖然自己手寫出來(lái)也能使用,但總覺(jué)得不方便。在stackoverflow上找到了解決辦法:把pods目錄添加到用戶頭文件檢索的路徑即可。具體實(shí)現(xiàn)方法如下:
選擇target ——- BuildingSettings ——– User Header Search Paths,雙擊空白區(qū)域點(diǎn)擊“+”號(hào),輸入“$(PODS_ROOT)”,選擇recursive(會(huì)在相應(yīng)的目錄遞歸搜索文件)。
這樣設(shè)置完成后,再導(dǎo)入第三方庫(kù)就會(huì)有提示了。
五、使用PB編譯器編譯.proto文件
為了驗(yàn)證ProtocolBuffer環(huán)境已經(jīng)搭建好了,我們就做個(gè)測(cè)試。在桌面建一個(gè)prototest文件夾,直接拷貝電腦里一個(gè)已有的User.proto文件做測(cè)試
然后通過(guò)以下命令來(lái)生成model的源代碼文件:
protoc --plugin=/usr/local/bin/protoc-gen-objc User.proto --objc_out="./"
在當(dāng)前目錄下便可以看到User.pb.h和User.pb.m這兩個(gè)文件了(需要注意的是生成的代碼是支持ARC的!!)。將生成的 .h 和 .m 文件添加到工程中,編譯。
這里會(huì)提示找不到GeneratedMessageProtocol。你只需要將其注釋掉就行了。