🍎

ココナラiOSアプリ開発でのProtocol Buffer利用について

2023/01/10に公開

こんにちは!株式会社ココナラのプロダクト開発部でiOSアプリ開発を担当している あっきー と申します。Xcodeのバージョンが2の頃からiOSアプリ開発をやっています。最近では一回り以上も歳が下のメンバーが増えてきて、いつ老害と言われてしまうかと戦々恐々の毎日を過ごしています。

本記事では、ココナラiOSアプリ開発でのProtocol Buffer利用を改善した話をします。

はじめに

ココナラiOSアプリでは、API通信の高速化や型安全なデータ利用のために、Protocol Bufferを利用したgRPC(google, Remote Procedure Call) 通信を取り入れています。Protocol Bufferは2008年から使われている技術で、Google社が提供するデータのシリアライズ形式のことです。詳細については割愛させていただきます。

リポジトリ構成など

protoファイルはiOSリポジトリのサブモジュールとして管理されていて、各案件ごとにブランチを切り替えて運用しています。
submodule

また、protoファイルからswiftファイルを生成する際に使うコンパイラはgRPC-Swiftを使っていて、こちらはPodfileに書いているので他のライブラリ群と同じく、pod installでインストールされます。

pod 'gRPC-Swift'
pod 'gRPC-Swift-Plugins'

イケてなかった操作手順

以前までは、protoから生成されたpb.swift、grpc.swiftファイルを手動でXcode管理に追加していましたが、手動での操作だと追加漏れがあったり、APIに変更が入るたびにXcodeへのファイル追加/削除をする必要があるので、アプリ開発作業を効率良く進めるにはイケてない操作手順となっていました。

自動でのXcode管理への追加/削除

そこで、自動でXcode管理へのファイル追加/削除を行うためにxcodeprojを導入しました。xcodeprojはRubyで作られたGemで、Xcode上でのスキーム、ターゲットの作成や、ビルド設定などを弄ることができるパッケージです。protoc実行後に、protoから生成されたswiftファイルをXcode管理に追加したり、差分を見て不要になったファイルをXcode管理から削除しています。

require 'xcodeproj'

# プロジェクト参照取得
project = Xcodeproj::Project.open(ENV['SRCROOT'] + "/Coconala.xcodeproj")

# 生成swiftファイルを追加するXcode上のグループを取得
group = project["path"]["to"]["generated"]

# protoc実行前の生成swiftファイルリストを取得
old_file_list = group.files.map{ |item| item.path }

# protoc実行
`
find $SRCROOT/path/to/proto/ -name "*.proto" | \
xargs protoc --proto_path=$SRCROOT/path/to/proto \
  --swift_out=$SRCROOT/path/to/generated \
  --grpc-swift_out=$SRCROOT/path/to/generated
`

# 生成swiftファイルリストを取得
new_files = `ls -1 $SRCROOT/path/to/generated/`.split("\n")

# 追加リスト
add_files = new_files - old_file_list

# 削除リスト
remove_files = old_file_list - new_files

# 追加リストからファイル参照を生成、ターゲットに追加
refs = add_files.map{ |item| group.new_file(ENV['SRCROOT'] + "/path/to/generated/" + item) }
target_name = "CoconalaAPI"
add_to_target = project.targets.select{ |item| item.name == target_name }.first
add_to_target.add_file_references(refs)

# 削除リストのファイル参照をプロジェクトから削除
group.files.select{ |item| remove_files.include?(item.path) }.map{ |item| item.remove_from_project }

# ファイル数に変更があればプロジェクトを保存
if add_files.count + remove_files.count > 0
    project.save
end

上記のスクリプトを、ビルド実行時のpre-actionで呼んでいます。これは仕込んでから気づいたのですが、ここに仕込むことでクリーン実行時にもスクリプトが実行されるらしく、ほとんどの場合、ビルドを実行する前にはprotoからのswiftファイル生成とXcodeへの追加/削除が完了しています。
pre-action

ハマったポイント

仕込んでいるときにハマったポイントは、project.saveでのプロジェクト保存は、ビルドをキャンセルしてしまうところです。ビルド中にプロジェクトファイルが弄られるので停止するようです。なので、project.saveはファイル数に変更があったときだけにしています。

まとめ

本記事では、ココナラiOSアプリ開発でのProtocol Buffer利用を改善した話をしました。Protocol Bufferは高速化以外にもモデルクラスの共通化ができたりと、多くのアプリ開発においてメリットは多いので、これからも便利に使っていければと思います。本記事が同じようにiOSアプリ開発環境の改善を進める方のお役に立てれば嬉しいです!

さいごに

実際にこの仕組みをご覧になりたい方は、ぜひ以下フォームよりお気軽にご連絡ください!
ココナラに少しでも興味が湧いたという方も大歓迎です。
入力時間は1、2分です。
https://open.talentio.com/r/1/c/coconala/pages/70417

ココナラのエンジニアについてもっと知りたい!という方はこちらをご確認ください。

https://coconala.co.jp/recruit/engineer

Discussion