Objective-Cの最近のブログ記事

この記事は RubyMotion Advent Calendar 2012 の 16 日目の記事です。

いきなりRubyMotionで書き始めるのはなかなか辛いので、最初は語彙を増やすたObjective-CのサンプルプログラムをRubyMotionで実装するというのを結構やりました。

Objective-Cのコードをコピペして文法をRubyに書き換えていくのは慣れればそれほど難しくないのですが、最初は簡単なことで次々と引っかかって手が止まることが多かったので覚えている限りですがリストアップしていこうと思います。

形式プロトコルの指定は悩まないで省略してよし

モジュールのincludeとかそういうのかなー?といろいろやったりしましたが、RubyはObjective-Cよりもっと動的な言語なのでメソッドは実行時に存在すればOKという事(たぶん)で次のような形式プロトコルの採用の指定 は無視しても良さそうです。

また非形式プロトコルは既存クラスを開いてメソッドを追加する(オープンクラス)だけです。

オーバーライドして親の実装を呼ぶのはsuperだけでよい

パラメータが必要な場合でもsuperを呼ぶだけで、パラメータもそのまま親クラスのメソッドに渡されます。

型の宣言はすべてばっさり落とす

先ほどの例のメソッドパラメータのBOOLの宣言を無視したようにRubyは型の宣言は一切ないので落としてしまいます。

ターゲットにメッセージを送るの書き換え

Rubyの文法が拡張されていてパラメータ名の指定に対応されています。 (Ruby1.9の簡易Hash指定とどう区別してるのだろう...)

括弧は省略してもかまいません。

target.message3 arg1, with:arg2

クラスメソッドも同様ですので、よく見るオブジェクトの生成は

@propertyはインスタンス変数

@property指定はそのクラスのメンバーなのでRubyではインスタンス変数として扱うのが適切だと思います。

@synthesizeはattr_accessor

@synthesizeはsetter/getter生成の指定なのでRubyではattr_accessorにするのが適切だと思います。オプションによってはattr_reader/attr_writerで指定する方が適切かもしれません。

ちなみに、RubyMotionでattr_accessorを使用すると通常のrubyのアクセサ(property,property=)の他にsetPropertyというsetterも生成されます。

このsetProperty、property=と同じなのかと思いきや

cオブジェクト自身を返してます。メソッドチェーンできると言うことですね!

定数の最初の文字に気をつけよう

iOS SDKの定数は小文字から始まりますがRubyMotionではRubyの規約にあわせて大文字から始まるように変換されています。Objective-Cのソースコードをコピペして修正すると、定数の先頭を大文字にするのを忘れがちです。

エラーメッセージを見れば分かるのですが、慣れてくると見つけたらすぐに大文字にするのが習慣になります。

if文の条件に気をつけよう

Rubyの偽はnilとfalseですがObjective-CはCなので偽は0のみです。
#nilやNULLやNO(BOOL)も値としては0です。

なので、これをそのまま置き換えたらダメ。0以外が真と明示的に書かないといけない。

また、真偽値(BOOL)はObjective-CではYES(1)/NO(0)ですが、すべてtrue/falseに置き換える必要があります。

ファイルの依存関係

RubyMotionではappフォルダの中に入っているRubyソースコードをディレクトリが階層になっていてもすべてコンパイルしてくれますが、コンパイルの順番が単純な辞書順なためファイルを分けると未定義でコンパイルエラーになることがあります。

RubyMotionがリリースされたばかりでまだ情報がほとんどなかった頃は困って全部1ファイルにしたりしていましたが、依存関係をRakefileに書けば大丈夫なのでした。

ところが最近リリースされた1.28から自動で解決するようになったようです。
#が、まだうまく動かないことが多いらしいです(-ω-)

ブロック呼び出し方

Objective-Cにはクロージャを実現するブロック構文があって、アニメーションのコールバックなどでよく使います。lambdaを使います。

#この例は公式ガイドそのものですが...

lambdaじゃなくてprocでも動きますが、procはパラメータ数に無頓着だったりreturnで外側のメソッドを抜けてしまったりObjective-Cのブロックとは違う動きをするのでlambdaの方が安心です。

ポインタ

描画系のAPIを使う場合にCのポインタをライブラリに渡さなければいけないシチュエーションが多々あります。

RubyMotionのPointerを使えばC言語のポインタ操作ができますが、Objective-Cから移植していると、表記方法を混乱しがちなので落ち着いて対応していきましょう。

こういうのでもGLubyte(OpenGLESの型)をXcodeで調べればサイズはunsigned charと分かるので、

とかけます。アクセス方法は配列と同じですが相手はCの配列=メモリエリアなので何を格納するのがプログラムの意図として正しいのかよく考えて移植しましょう。

写経に使えるサンプルコードの紹介

元になるコードはGithubなどでObjective-CやiOSで検索してもたくさん出てくるでしょうが、まずは小さなプログラムから始めたいところです。

私が参考にしたサンプルコードを紹介します。

iOS Developer Library Sample Code

Appleのサンプルコード集です。

cocoa controls for iOS

iOS用のUIパターン実装例が大量にあります。移植したものが動くとかなり嬉しいです。

iOS 6 新機能のサンプルコード/ライブラリのまとめ22個 - Over&Out その後

iOS 6の新機能を紹介したブログエントリーですが、新機能をRubyMotionで実装してみる実験に良さそうです。

まとめ

Objective-Cで実装できていることは、なんでもできる...と言い切れるかはまだ分かりませんが、私がいろいろやってみたサンプルコードではひとつ(OpenELGSを使っているもの)を除いてすべて動きました。

もっといろいろ突っかかった事があった気がするのですが、思い出せたのはこのくらいでした。簡単なことでも気づいたことをブログに書くなどして残しておいた方がいいですね。

この記事は RubyMotion Advent Calendar 2012の13日目の記事です。

BubbleWrapRubyMotion Tutorialでお馴染みのClay Allsoppさんによって書かれたRubyMotion本がリリースされました。

章立て

  • Foreword
  • Ruby on iOS
  • Creating a New App
  • Filling the Screen with Views
  • Organizing Apps with Controllers
  • Representing Data with Models
  • Showing Data with Table Views
  • Testing Your Apps
  • Example: Writing an API-Driven App
  • Uploading to the App Store

序文とRubyMotionの概要

序文はRubyMotionの開発者Laurent Sansonettiさんによって書かれています。

続いてRubyMotionの成り立ちや、この本についての説明など概要部分が「Ruby on iOS」の章となっています。

3章の「Creating a New App」からは実践的になります。

ここは公式のスタートアップガイド(日本語)を詳しくしたような内容です。

RubyMotionを初めてさわる方でも迷うことなくビルドしてシミュレータが動作するところまで行けそうです。Rakefileの内容にも少し触れられていて公式のガイドより理解を深めながら実験できる作りになっています。

ViewとController

4章の「Filling the Screen with Views」はWindowとViewの階層構造やハンドリング方法の基本です。 最初は戸惑う、Viewをアニメーションさせる方法についてもわかりやすく解説されています。

5章の「Organizing Apps with Controllers」はiOS SDKプログラミングのキモであるUIViewControllerについての解説です。

rootViewControllerとして単純なUIViewControllerインスタンスを使う方法から始まって、UINavigationControllerを使ってのスタック型の画面遷移、UITabBarControllerの使い方、モーダルビューの使い方が説明されています。

このViewとControllerの解説パートはiOSの知識があるならば飛ばしても大丈夫かもしれません。

データの扱い方

6章の「Representing Data with Models」ではRubyMotionでMVCプログラムを書くための基本が説明されています。 モデルクラスを自分で定義してUIViewとUIViewControllerをどう連携させるか、データの初期化をどこでやるかなど初心者にとって迷うポイントだと思われるのでいいですね。

パラメトリックなモデルの初期化など簡単な動的モデルの構築についても書かれていて、Rubyもこれからという人にとって良いサンプルです。(ほんの触りだけではありますが)

データの保存はNSUserDefaultsを使ってでした。CoreDataを使ってRubyっぽくやる方法のアイディアがあったら良かったな〜。そこはiOSプログラミングやサードパーティライブラリのスコープで専門的すぎるのかしら。

7章の「Showing Data with Table Views」ではUITableViewにデータを表示する方法の解説です。

この章もiOSのUITableViewの知識があるならば飛ばしても大丈夫かもしれません。

テスト

8章の「Testing Your Apps」ではRubyMotionもくもく会でも毎回話題になる、みんなどういうのがベストプラクティスなのか分からなくて困っているテストについて。

しかし結論から言うと内容としては公式ドキュメントのWriting Tests for RubyMotion Apps(日本語)の方がずっと詳しい(爆)

この章の内容は、TDDでspecを書くための最初のとっかかりとして使い、UIのテストについては必要なオブジェクトをテスト時にどう引っ張ってくるかを理解するために4章の内容をじっくりやって、公式のドキュメントを参照しながら、必要なテストの語彙を自分で増やしていくのが良さそうです。

最近RailsプロジェクトでやっとTDD厨になったので、RubyMotionを使ったアプリを作るときはTDDで開発して、またの機会にそれを報告できたらいいなと思います。

実践的な開発例

9章の「Example: Writing an API-Driven App」ではこれまでの内容をもとにAPIをたたいて(Mashup!)表示をする簡単なアプリを作成する例となっています。

App Storeへの申請

10章の「Uploading to the App Store」はApp Storeへ申請するためのプロジェクトの設定方法と作業内容についての解説となっています。

iOSアプリの設定はハマりどころ満載で最初は本当に大変なので、本書の最も使える内容なのではないかと思われます。

まとめ

RubyMotionをこれからはじめる人にはとても良い内容になっていると思います。

今まではネットにある優れたチュートリアルをやるのが最初のステップとなっていましたが、さすがに書籍としてまとまっているだけあって、本書を写経して実際に動かしながら確認すればひと通りのことはできるようになるでしょう。

駆け足で紹介してきましたが、私もまだRubyMotionでアプリを作り上げたことがないレベルなので、時間を作ってひと通りやってみようと思っています。

この記事は RubyMotion Advent Calendar 2012の二日目の記事です。

第2回RubyMotionもくもく会でYahoo! iOSマップSDKのサンプルをRubyMotionに翻訳していて
http://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/iphonesdk/tutorial2.html

YMKCoordinateRegionMakeのところで

Undefined symbols for architecture i386:
  "___concrete__YMKCoordinateRegionMake", referenced from:
      _MREP_F77F7B4AA08045E9933EBA24E7FDF1CA in app_delegate.rb.o
  "___concrete__YMKCoordinateSpanMake", referenced from:
      _MREP_F77F7B4AA08045E9933EBA24E7FDF1CA in app_delegate.rb.o
ld: symbol(s) not found for architecture i386

こんなエラーで落ちます。何を言ってるのか分からなかったのですがWatsonさんのおかげでサードパーティーのライブラリのマクロは自動で定義されないので存在しないことが分かりました。

大文字で始まっているのですぐ気づいても良さそうなものですが、このときは全然気づかなかった(汗)

本題はそこではなくて、frameworkのヘッダファイルからYMKCoordinateRegionMakeを探して同じ事をするメソッドを定義する際にC構造体の扱いがすぐに分からなかったこと。

該当ヘッダファイルの内容はこうでした。

マクロじゃなくてstatic inlineな関数でしたが同じ事なのでしょう。

このYMKCoordinateSpan構造体のオート変数としてspanを定義するところです。

構造体変数はframework内で使われているので勝手に他のもの代替するわけにはいきません。YMKCoordinateSpan構造体としてのアクセス領域が必要です。

これはPointerを使えば回避できます。
http://www.rubymotion.com/developer-center/guides/runtime/#_pointers

元のプログラムはオート変数を生成して値を設定しそのまま返して、値をコピーして利用している。同じ事をするためにYMKCoordinateSpan型のポインタを作ったら#valueで値を取得して使用します。([0]で値にアクセスしてもいいですが)

これでバッチリ動作するようになりました。

余談ですが、再定義しても上記のようにメソッド名をYMK...からymk...と小文字に変えないと動きませんでした。static inlineの方の定義が使えないのに名前としては参照できるからという事でしょうか...(・ω・)

このアーカイブについて

このページには、過去に書かれたブログ記事のうちObjective-Cカテゴリに属しているものが含まれています。

前のカテゴリはNetworkです。

次のカテゴリはopencvです。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。