40歳からのキャリアチェンジ

20代はエンジニア・PM、30代はWeb系エンジニア向けのキャリアアドバイザー。40代の今はフリーランスで開発含めて色々やってます。技術ネタとしてはRuby/RailsとJavaScript関連あたり

RubyMotionいじって気づいたTi.UI.ImageViewが意外と賢い件

先日、Qiitaのハッカソン疑似体験したということを書きましたが Titanium Mobile で作ってるものを、RubyMotionで実装しなおすことで、勉強になるんじゃないかと思って、色々いじっている中で、Titanium Mobile が、意外と(といっては失礼かな?)しっかりと作りこまれている事に気づいたのでそれについて紹介しようと思います

※一応断っておくと、Titanium Mobile 、RubyMotion のどっちが優れているというのを書きたいわけではないです。また自分はObjectiveCでiPhoneアプリ書いたことはないため、これまでまともにiOS SDKAPI リファレンス見たことがないです

画像の表示

Titanium MobileのAPI だと、Ti.UI.createImageView を通じて画像表示をするかと思います。

var remote_image = 'http://www.....';
iconImage = Ti.UI.createImageView({
  width: 40,
  height: 40,
  top: 5,
  left: 5,
  image: remote_image
  });
  iconImage1 = Ti.UI.createImageView({
  width: 40,
  height: 40,
  top: 5,
  left: 50,
  image: 'icon.png'
  });

image プロパティにその画像のパスを指定すれば、そのパスがリモートのものでも、ローカルのものでも特に深く考えずに表示できるかと思います。

この前提で、RubyMotion で画像表示の機能を実装しようと思ってRubyMotion で画像を View の上に表示するを参考にして

image_path = @feed[indexPath.row]["user"]["profile_image_url"]
image = UIImage.imageNamed(image_path)
@image_view = UIImageView.alloc.initWithImage(image)
@image_view.frame = CGRectMake(0, 0, 36, 36)
view.addSubview(@image_view)

という感じのコード書いたら、コンパイルできませんでした。最初何が原因だったのかさっぱりわからずに、色々ググッている中でTable View のセルにインターネットから読み込んだ画像を表示するというページをたまたま見つけ、そこに

前回の最後に使った imageWithContentsOfFile: では、ローカルのファイルパスしか指定できません。そこで、画像データを NSData 形式で取得して、imageWithData: で UIImage を生成することになります。

という一文がありました。 ここで、初めて

「あー、リモートの画像を表示する場合と、ローカルの画像を表示する場合とで処理方法がそもそも違うんだ。。」

ということに気づきました。

冷静に考えるとローカルから読み込む場合には、指定したパスに該当の画像があるかどうかを気をつければいいのに対して、リモートから画像取得する場合に、それに加えて、ネットワークの接続状況、遅延などが考えられるから、それらを考慮しないといけないから処理方法が異なるのは当たり前ですよね・・

ネットワークの接続状況、遅延とかを考えず、ひとまずリモート画像を表示するのをRubyMotionで書く場合にはこんな感じですね

image_path = @feed[indexPath.row]["user"]["profile_image_url"]
image_src = NSData.dataWithContentsOfURL(NSURL.URLWithString(image_path))
image = UIImage.imageWithData(image_src)
image_view = UIImageView.alloc.initWithImage(image)
image_view.frame = CGRectMake(5, 5, 30, 30)
  • リモートの画像が格納されているURLを、変数image_path に格納。
  • 変数image_path はこのままだとString型なので、NSURLのURLWithStringを使って、URL型(っていうのかな?)に変換した上で、NSDataのdataWithContentsOfURLを利用して画像取得。
  • 取得した画像をUIImage.imageWithDataに渡す

こんな面倒なことを、Titanium Mobile がイイ感じに処理してくれていたんですね。今まで気づかずにいて、Titaniumごめんなさいww

最近RubyMotionとTitaniumと両方とも面白くなってきた

RubyMotionのもくもく会が開催され運営お手伝いしつつ、作業していたのですが、参加している人達同士の質問や雑談などから、RubyMotionでの開発で知っておくと便利なこと(BubbleWrapとかteacup等。)が知れてかなり面白くなって来ました。

5月にRubyMotionいじってみた感想を書いた時に

Titanium Mobileの内部構造をもう少し理解したいという漠然とした考えを持っていました。

ということを書いてました。RubyMotionでサンプルアプリ書いてる作業を通じて

「Titanium Mobileでのあの作業は実際にはこうなってるのか」

というのが漠然とですが、頭の中でイメージできるようになりました。(るびまのRubyMotion紹介記事で取り上げられていたDashというドキュメントブラウザーというか本来はスニペット管理アプリのおかげで、iOS SDKAPI リファレンスを引くのがそんなに苦でなくなったのも大きいかもしれませんね。)

RubyMotionを通じて、間接的にですがTitanium Mobileの内部構造の理解も以前よりは理解進んできたし、両方とも面白くなってきたので、しばらく両方共いじっていこうかなと思ってます。

おまけ:RubyMotionでつくりかけのQiitaのアプリ

Titanium Mobileで作ってるやつと比べて実装しきれてない部分多いですがGistに貼ってみました。