こんにちは最近一日に一回は波紋のビートを刻んでる村田です。
はじめに
スマートフォンアプリの開発では回線状況や端末のスペックなど様々な状況下で動作するため、少しでも高速化できる余地があるのであればなんとか頑張りたいところですよね。 今日はサーバサイドとiOSアプリの間のデータのやり取りを高速化する方法をご紹介したいと思います。 サーバサイドはRuby on Railsを前提にすすめさせて頂きます。
こんな感じでできないか?
弊社ではアプリとサーバサイドのデータのやり取りをjsonで行なっていました。 レスポンスを受け取ってからパースする部分を高速化するには? と考えたときパーサ自体を高速なものに置き換えてみたりしましたが、それよりもplistバイナリで直接やり取りすればパースをする処理が省けるので高速化できないかという仮説に達しました。 このようなイメージですね。
実際どうなのよ?
いきなり結論から行きますが、高速化できました。 以下具体的な実装の一部を紹介していきます。
実装(サーバ側)
Rubyでplistのデータを扱うときにはCFPropertyListというgemを使うのが簡単でいいと思います。 Ruby on Railsで使う場合Gemfileに
code gem 'CFPropertyList' /code と追記してbundle installすれば大丈夫です。 実際にサンプルのコードを書いてみました。 code require 'cfpropertylist' class SampleController < ApplicationController def index #こんな感じのレスポンスをサーバサイドから返す
response_data = {:info => {:total => 100, :count => 10}, :results => [{:name => "murata", :age => 27}, {:name => "6rats", :age => 28}, ... #省略
{:name => "ozaki", :age => 15} ] }
if params[:format].to_s == "plist" #plistでレスポンスを返却
plist = CFPropertyList::List.new
plist.value = CFPropertyList.guess(response_data, :convert_unknown_to_string => true)
render :text => plist.to_str(CFPropertyList::List::FORMAT_BINARY)
else
#デフォルトではjsonで返却
render :json => response_data.to_json(:root => 'response', :skip_instruct => true, :dasherize => false, :skip_types => true)
end
end
end
/code
formatというパラメータにplistが指定されたときにはplistのバイナリをテキストで返すようにしてみました。 最後のテキストにする時にCFPropertyList::List::FORMAT_BINARYを指定するなど少しだけハマりかけたところも有りましたが、これで大丈夫そうです。 サーバサイドではここまで準備できれば完了です。
実装(iOS側)
次にサーバサイドからデータを受け取ったiOSアプリ側の実装になります。
code self.parsedResponse = [NSPropertyListSerialization propertyListFromData:self.responseData mutabilityOption:NSPropertyListImmutable format:nil errorDescription:&aError]; /code
self.responseDataにAPIサーバからのレスポンスが入ってself.parsedResponseが実際に扱えるデータになります。 iOS側はこの部分がJSONをパースしてという処理でした。
どれくらい速くなった?
1. APIからのレスポンスのデータ量の比較
ファッションアイテムの一覧を取得するAPIのデータ量の比較 plistバイナリのものは大体16KB jsonのものは大体約30KB 通信する際の容量の点でも結構削減できました
2.iOS内での処理速度の比較
同じくファッションアイテムの一覧を取得するAPIにリクエストした時を想定して計測してみます。 今回はAPIからのレスポンスを実機で100回パース処理を行なってみました。 計測結果 大体10倍くらいは速くなっていますね。
最後に
いろいろ思考錯誤を重ねましたが、少なくともこの方法は高速化に貢献できたと思います。 サーバサイドからのデータ量が少し大きくなってしまった場合に、より効果を発揮しています。 エンジニアチームではまだまだやりたいこととできていないことがたくさんあります。 技術的なチャレンジを一緒に楽しめるエンジニアを大募集しています。