iOSとAndroidで同じようにアプリ開発するための技術比較

最近iOSアプリとAndroidアプリの両方を開発するようになったのですが、納期が短くエンジニアも少ないのでできる限り開発手法や設計などを同じような形にして開発コストを下げたいと思っています。同じような悩みを持っている人は結構いるんじゃないでしょうか。
ここではiOSとAndroidの両アプリで同じように使えるライブラリなどを紹介していきます。主に自分が使ったことのあるものや聞いたことのあるものを選定しています。実際に自分で使ってみたことのないものもあるので間違っていたらごめんなさい。

個々のライブラリは簡単な紹介のみとなっていますので詳細な使用方法はリンク先等を参照してください。

#言語
| iOS | Android |
|:-----------|------------:|
| [Swift](http://www.apple.com/jp/swift/)|[Kotlin](https://kotlinlang.org/)|
iOSと言えばObjective-c、Androidと言えばJavaだった時代は今は昔。今時のiOS開発といえばSwiftですね。AndroidにもSwiftと類似の文法で開発できるKotlinという言語があります。KotlinはIntelliJ IDEAなどで有名なJetBrains社が開発している100%JAVA互換の言語です。2015/10/31現在で1.0.0-betaなのでまだまだ大規模プロジェクトなどで導入するのは不安かもしれませんが、新規プロジェクトを始めるのなら開発言語としての採用を検討してもいいんじゃないでしょうか。

文法がどれくらい似ているかという一例として変数・定数定義の仕方を紹介します。

```swift:Swift
    var hoge = 100 //変数
    let hoge2 = 100 //定数
```

```Kotlin:Kotlin
    var hoge = 100 //変数
    val hoge2 = 100 //定数
```

#DB
[Realm](https://realm.io/jp/)
両OSで使えるDBといえばRealmでしょう。近年急速に普及が進んでいると感じています。iOS版、Android版それぞれに日本人の方が開発に参加されていらっしゃるので、比較的日本語のサポードが厚いのが心強いですね。
以前はiOSであればCoreData、AndroidであればSQLiteやActiveAndroidだったでしょうか。

#リアクティブ
| iOS | Android |
|:-----------|------------:|
| [ReactKit](https://github.com/ReactKit/ReactKit),[RxSwift](https://github.com/ReactiveX/RxSwift),[SwiftBond](https://github.com/SwiftBond/Bond),[ReactiveCocoa](https://github.com/ReactiveCocoa/ReactiveCocoa)|[RxJava](https://github.com/ReactiveX/RxJava),[RxAndroid](https://github.com/ReactiveX/RxAndroid)|
最近流行りのリアクティブプログラミングですが、できるだけ近しい技術を選択するならRx系でしょうか。

#引っ張って更新
|iOS|Android|
|:-----------|------------:|
|[UIRefreshControl](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIRefreshControl_class/)|[SwipeRefreshLayout](https://developer.android.com/reference/android/support/v4/widget/SwipeRefreshLayout.html)|
すっかりおなじみとなった引っ張って更新するUIですが、今では両OSで標準のコンポーネントとして提供されています。UIRefreshControlはiOS6から、SwipeRefreshLayoutはAndroid Support Library,revision 19.1.0からそれぞれ追加されました。

#スワイプでタブ切り替え
|iOS|Android|
|:-----------|------------:|
|[PagingMenuController](https://github.com/kitasuke/PagingMenuController)|[ViewPager](http://developer.android.com/reference/android/support/v4/view/ViewPager.html),[TabLayout](https://developer.android.com/intl/ja/reference/android/support/design/widget/TabLayout.html)|
グノシーなどのニュース系アプリでよく使われる、上タブをスワイプで切り替えてコンテンツを表示するUIのことです。どちらかといえばAndroidアプリでよく使われるUIです。Androidでは以前からViewPagerとHorizontalScrollViewなど組みわせて実装されていましたが、今後はAndroid Support Library,revision 22.2.0で追加になったTabLayoutとViewPagerを組み合わせて実装する方法が主流になるのではないでしょうか。
iOSは基本的にタブは下に配置するためか、上タブをスワイプで切り替えるための一般的に手法が確立していないのではないかと思います。あえてライブラリをあげるならばPagingMenuControllerではないかと思いますが、他のライブラリもあります。こちらの[サイト](http://animane.hatenablog.com/entry/2015/09/27/133859)が詳しいです。

#画像をダウンロードして表示
|iOS|Android|
|:-----------|------------:|
|[SDWebImage](https://github.com/rs/SDWebImage)|[Picasso](http://square.github.io/picasso/)|
サーバ上にある画像をダウンロードしてきて任意のImageView上で表示したくなるケースが多々ありますよね。そんな時に使える便利なライブラリが両OSにあります。共にDisckCacheとMemoryCacheを使うことで無駄な通信を省くことができます。

それぞれ以下のように使います。

```swift:Swift
imageView.sd_setImageWithURL(url);
```

```java:Java
Picasso.with(context).load(url).into(imageView)
```

#JSON
|iOS|Android|
|:-----------|------------:|
|[NSJSONSerialization](https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSJSONSerialization_Class/)<br>[SwiftyJSON](https://github.com/SwiftyJSON/SwiftyJSON)|[JSONObject](http://developer.android.com/reference/org/json/JSONObject.html)<br>[gson](https://github.com/google/gson)

iOSはNSJSONSerializatin、AndroidはJSONObjectがそれぞれJSONをシリアライズ・デシリアライズする標準の方法です。標準の方法だけですと面倒な場合も多く、SwiftでJSONを扱いやすくしたSwiftyJSONや、JavaオブジェクトとJSONオブジェクトの変換をシンプルに行えるgsonなどがよく使われています。

#イベント通知
|iOS|Android|
|:-----------|------------:|
|[NSNotification](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSNotification_Class/)|[otto](https://github.com/square/otto)<br>[EventBus](https://github.com/greenrobot/EventBus)

オブジェクトの状態の変化やDBの更新結果などのイベントを、オブジェクトに通知したくなる時があると思います。特定のオブジェクトに通知したい場合、iOSであればdelgateを、Androidであればcallback用のlistenerを登録して対応することになるかと思います。
複数のオブジェクトに対してイベントを通知する場合、iOSであればNSNotificationという仕組みが標準であり、簡単に独自イベントの定義やイベントの監視ができます。Androidの場合、NSNotification相当のことを実現したければBroadcastReceiverを使うという手もありますが、Intent-filterを登録したりなどちょっと面倒なので、ottoやEventBusなどのライブラリを使うことをおすすめします。個人的にはottoしか使ったことがありませんが、NSNotificationに近い感じで使えて便利です。
例えば、「didFinish」という独自イベントの監視と発行は以下のようになります。

```swift:Swift
//didFinishイベントの監視開始(ViewController内など)
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("hoge"), name: "didFinish", object: nil)

func hoge() {
  //イベント受信後に実行したい処理
}

//didFinishイベントの発行(モデルクラス内など)
NSNotificationCenter.defaultCenter().postNotificationName("didFinish", object: nil)
```

```java:Java
// Ottoでは常に同じBusオブジェクトを使う必要があるのでSingletonにする
public class OttoHolder {
    public static final Bus sBus = new Bus();
}

//独自イベントクラスの定義
public class DidFinishEvent {}

//DidFnishイベントの監視開始(Activity内など)
OttoHolder.bus.register(this);

@Subscribe
public void subscribe(DidFinishEvent envent) {
//イベント受信後に実行したい処理
}

//didFnishイベントの発行(モデルクラス内など)
OttoHolder.sBus.post(new DidFinishEvent());
```

#UITest

[Calabash](http://calaba.sh/)
CalabashはBDDツールとして有名なCucumberを使ったUIテストフレームワークです。Cucumberは自然言語に近い形でテストケースを書くことができるRuby製のテストフレームワークです。RubyとCucumberの文法がわかればテストを記述することができます。個人的にはiOSでしか利用したことがありませんが、両OSで同じようなUIを実装しているのであれば、1つのテストケースを両OSで実行することができるのではないでしょうか。
#配布
配布ツールといえばTestFightが有名でしたが、Androidアプリの配布ができなくなったので、両OSで使えるという観点では候補からは外れてしまいます。

[Fabric](https://get.fabric.io/)
FabricはTwitter社が提供するモバイル向けの開発ツールでクラッシュレポートの収集、アナリティクス、アプリの配布などが行えます。完全無料というのが強みでしょう。

[DeployGate](https://deploygate.com/)
DeployGateはmixi社の新規事業として立ち上がったサービスで、今は独立してデプロイゲート社が提供しています。
日本初のサービスなので英語が苦手でも使えるというのが強みでしょう。
個人開発であれば無料のプランでも十分かもしれませんが、会社で開発するとなると有料プランが必須になります。

[Hockey App](http://hockeyapp.net/features/)
以前iOSアプリの配布で使っていましたが特に不満なく使えていました。一概には言えませんが、料金はDeployGateより安いように思えます。