Help us understand the problem. What is going on with this article?

Scala/JavaでiOSアプリを作るtipsその2

More than 5 years have passed since last update.

概要

これまでxcodeとの連携を手作業で行っていたのですが、これを自動化しました。
プロジェクトのテンプレートはこちらです。
https://github.com/chototsu/mikumikustudio-gdx

今回追加したのはxcodebuildというタスクです。
このタスクを実行すると、xcode_iosというディレクトリにあるxcodeプロジェクトをコンパイルし、自動的にUniversal Static Libraryを作成します。また、xibファイルを解析し、そのJavaバインディングコードをios/generatedディレクトリに自動生成します。

ライブラリ生成

今回作成したのはこのようなプロジェクトです。
スクリーンショット 2014-02-23 21.32.19.png

このプロジェクトの「lib」というターゲットがライブラリ用のターゲットです。ライブラリに含めたいクラスはこのターゲットに入れるようにして下さい。
尚、UIViewControllerのクラスはこのターゲットに含めないで下さい。UIViewControllerのクラスはRoboVM側で生成しますので、こちらに同名のクラスがあると名前が衝突してしまいます。

画面生成

画面はUIViewControllerのサブクラスとして作ります。
スクリーンショット 2014-02-23 21.37.35.png
この時、「With XIB for user interface」をチェックするようにして下さい。
繰り返しますが、ここで作ったクラスはlibターゲットに含めないで下さい。名前が重なって実行時にエラーが発生します。

クラスを作ったら普通に画面を作成し、OutletやActionを作成します。
スクリーンショット 2014-02-23 21.39.19.png

作成出来たらsbtからxcodebuildを実行します。

$ sbt
> ios/xcodebuild

するとxibが自動的にnibにコンパイルされ、このようなクラスが生成されます。

package view;
import org.robovm.cocoatouch.uikit.*;
import org.robovm.objc.Selector;
import org.robovm.objc.annotation.BindSelector;
import org.robovm.objc.annotation.CustomClass;
import org.robovm.objc.annotation.TypeEncoding;
import org.robovm.rt.bro.annotation.Callback;
@CustomClass("TestAppViewController")
public abstract class TestAppViewController extends UIViewController {
    public TestAppViewController() {
        super("TestAppViewController", null);
    }   protected UILabel label1;
    @SuppressWarnings("unused")
    @Callback
    @BindSelector("setLabel1:")
    @TypeEncoding("v@:@")
    private static void setLabel1(TestAppViewController self, Selector selector, UILabel label1) {
        self.label1=label1;
    }
    @SuppressWarnings("unused")
    @Callback
    @BindSelector("getLabel1")
    @TypeEncoding("v@:@")
    private static UILabel getLabel1(TestAppViewController self, Selector selector) {
        return self.label1;
    }
    @SuppressWarnings("unused")
    @Callback
    @BindSelector("buttonAction:")
    @TypeEncoding("v@:@")
    private static void buttonAction(TestAppViewController self, Selector selector, UIButton sender) {
        self.buttonAction(sender);
    }
    abstract protected void buttonAction(UIButton sender);
    @SuppressWarnings("unused")
    @Callback
    @BindSelector("button2Action:")
    @TypeEncoding("v@:@")
    private static void button2Action(TestAppViewController self, Selector selector, UIButton sender) {
        self.button2Action(sender);
    }
    abstract protected void button2Action(UIButton sender);
}

このクラスはabstractクラスですのでそのままでは使えません。
使うためにはこのクラスを継承したクラスを作成します。
これはScalaの例です。

class TestAppViewControllerImpl extends TestAppViewController {
  protected override def buttonAction(sender: UIButton): Unit = {
    label1.setText("Hello!!")
  }

  protected override def button2Action(sender: UIButton): Unit = {
    label1.setText("World!!")
  }
}

この画面を表示するためにはdidFinishLaunchingでaddSubviewしてやります。

  override def didFinishLaunching(application: UIApplication, launchOptions: NSDictionary[_ <: NSObject, _ <: NSObject]): Boolean = {
    super.didFinishLaunching(application, launchOptions)
    testAppViewController = new TestAppViewControllerImpl
    app.getUIViewController.getView.addSubview(testAppViewController.getView)
    true
  }

実行すると、作成した画面がOpenGLの画面の上に表示される事が確認出来ます。
作成したボタンを押すとlabelの内容が変化する事が分かります。
qiita.png

制限

現在はすべてのUIButtonのTouch Up Insideアクションにしか対応していません。
その他のアクションはサブクラス側に手作業で追加して下さい。

TODO

*Objective Cのバインディグを自動生成したい(これはかなり大変そう・・・)。
*xibの全action, outletに対応する。
*maven centralリポジトリに作ったバインディグを登録する。

終わりに

開発環境が整ってきて、だいぶ作業が捗るようになりました。
Javaのエコシステムを利用してiOSの開発が出来てしまうのは凄い事だと思います。
ちなみに私が公開したアプリ Tiny AR liteは
https://itunes.apple.com/jp/app/tiny-ar-lite/id806062401?mt=8
RoboVMの作者のNiklas Therning氏に世界初のScalaで書かれたiOSアプリとの公式認定を受けております(笑)
当初安定性の心配をしていたのですがユーザー様からの評価では概ね安定しているようで、ほっとしています。
RoboVMは十分安定していると言えるでしょう。

chototsu
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした