RubyMotion でスタティックライブラリを作成し、 Xcode プロジェクトで利用する

## RubyMotion プロジェクトを作成する
まずは、RubyMotion のプロジェクトを作成してみます。

```
% motion create TestStatic
    Create TestStatic
    Create TestStatic/.gitignore
    Create TestStatic/app/app_delegate.rb
    Create TestStatic/Rakefile
    Create TestStatic/resources/Default-568h@2x.png
    Create TestStatic/spec/main_spec.rb
```

アプリケーションが起動する際にインスタンス化され呼び出されるクラスとして、`AppDelegate` があります。Xcode でプロジェクトを作成する際にも同盟のクラスが自動的に作成されます。シンボルが衝突したりすると面倒なので、クラス名を `AppDelegate` から `StaticAppDelegate` などに変更しておきます (`AppDelegate` そのものを削除しても良いのですが、RubyMotion で動作確認できなくなってしまうので、このようにしてます)。

```ruby:app/app_delegate.rb
class StaticAppDelegate
  def application(application, didFinishLaunchingWithOptions:launchOptions)
    true
  end
end
```

`Rakefile` を修正し `app.delegate_class` を設定して delegate クラスを変更したことを設定しておきます。

```ruby:Rakefile
Motion::Project::App.setup do |app|
  # Use `rake config' to see complete project settings.
  app.name = 'TestStatic'
  app.delegate_class = 'StaticAppDelegate'
end
```

## コーディング
ライブラリ化するコードを記述していきます。ここでは、文字列から UIColor オブジェクトを作成するものを書きました。

```ruby:app/app_delegate.rb
class NSString
  def to_color
    # string like a "#0c92f2"
    raise "Unknown color scheme" if (self[0] != '#') || (self.length != 7)
    color = self[1..-1]
    r = color[0..1]
    g = color[2..3]
    b = color[4..5]
    UIColor.colorWithRed((r.hex/255.0), green:(g.hex/255.0), blue:(b.hex/255.0), alpha:1)
  end
end

class StaticAppDelegate
  def application(application, didFinishLaunchingWithOptions:launchOptions)
    NSLog("%@", "#0c92f2".to_color)
    true
  end
end
```

## ライブラリを作成する
`rake static` コマンドを実行してスタティックライブラリを作成します。

```
% rake static
     Build ./build/iPhoneSimulator-6.1-Development
    Create ./build/iPhoneSimulator-6.1-Development/TestStatic.a
     Build ./build/iPhoneOS-6.1-Development
   Compile ./app/app_delegate.rb
    Create ./build/iPhoneOS-6.1-Development/TestStatic.a
    Create ./build/TestStatic-universal.a
```

できあがったライブラリは `build` ディレクトリの中に `XXXXX-universal.a` という名前で格納されます。


## Xcode プロジェクトからライブラリを利用する
先ほど作成した  `XXXXX-universal.a` に加えて、`libstdc++.dylib` と `libicucore.dylib` というライブラリをプロジェクトに追加します。

![130605-0001.png](https://qiita-image-store.s3.amazonaws.com/0/2075/ade5ed9a-3f43-5f46-e459-bff1fc64a028.png "130605-0001.png")

あと、RubyMotion で用意したメソッドを呼び出そうとすると、「メソッドの宣言がされていない！」と ARC がオンになっていると怒られてしまうので、とりあえず ARC はオフにしています。(Ruby で用意したメソッドにそったヘッダファイルを作成すれば良いのですが・・・、面倒だったので省いています)

次に `main.m` をに以下のようにコードを追加します。`RubyMotionInit()` を呼び出すと、RubyMotion で用意したコードの初期処理が行われ、クラスなどが構築され Objective-C から利用できるようになります。

```objc:main.m
      // RubyMotion のライブラリを初期処理
      void RubyMotionInit(int argc, char **argv);
      RubyMotionInit(argc, argv);

      return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
```

あとは Objective-C から利用します。

```objc
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSLog(@"%@", [@"#0c92f2" to_color]);
    return YES;
}
```

実行すると、以下のようにアウトプットコンソールに表示され、RubyMotion で作ったスタティックライブラリが動作していることが確認できます。

![130605-0002.png](https://qiita-image-store.s3.amazonaws.com/0/2075/032a7994-e99b-a25b-ebba-c6c0cacf8258.png "130605-0002.png")