NativeSciriptでJavaの外部SDKをサクッと呼び出す

NativeScriptの良いところは、ネイティブAPIのアクセスが極めてナチュラルに出来るところです。

## 環境
NativeScript 3.1 + Angular 4

# どのくらい簡単にAndroidのAPIを呼び出せるのか

Androidのシステム情報を取得するandroid.os.Buildクラスを呼び出してみます。
参考) https://developer.android.com/reference/android/os/Build.html

```ts
declare let android:any;

// androidのデバイス名を取得
let deviceName = android.os.Build.MODEL;
```

はいこれだけです。何と、androidのクラス名をそのままTypeScriptで書いて、AndroidのAPI呼出が出来ちゃいます。 deviceName 変数には "SO-04H" みたいな機種名が入ります。直感的ですよね！

なお、`android` という名前空間はAndroid端末での実行時に解決されるもので、コンパイル時には解決できないため、普通に書くとTypeScriptでコンパイルエラーに...。そこで、`declare let android:any;` を書くことで android オブジェクトはany型なのでチェック不要ですよ！としてあげる必要があります。これはちょっとしたお作法です。

もしTypeScriptに名前空間を認識させるためには、TypeScriptのandroid,iosそれぞれの型定義をインストールしておく必要があります。入れておくと、IDE上で入力補完が聞いて開発効率が上がるので、オススメ。

↓以下の記事を参考にしてみてください

http://qiita.com/hosikiti/items/5c84e7ccfd33ecffc657

# Gradleで提供されるライブラリを利用する

AndroidのSDKはGradleで提供されることも多いようですね。こうしたSDKをNativeScriptから利用するにはどうしたらいいのか、見ていきましょう。試しに、ReproのAndroid SDKを利用してみます。

## build.gradleへの依存関係の記述

Reproの公式ドキュメント
http://docs.repro.io/ja/dev/sdk/getstarted/android.html#android-studio
を参考に入れていきましょう。
まず、「アプリケーションの app/build.gradle にRepro SDKへの依存を追記してください。」という説明をもとに、以下の設定を app.gradle に追記します。

```groovy:/app/App_Resources/Android/app.gradle
repositories {
     maven { url 'https://cdn.repro.io/android' }
}


dependencies {
     compile 'io.repro:repro-android-sdk:2.6.0'

     compile fileTree(dir: 'libs', include: ['*.jar'])
     testCompile 'junit:junit:4.12'
     compile 'com.android.support:appcompat-v7:23.0.1'
     compile 'com.android.support:design:23.0.1'
}
```

## SDKのメソッドを呼び出す

build.gradle へ依存関係を記述すると、もうSDKの準備は完了です。さっそくメソッドを呼んでみます。
以下の getDeviceID というメソッドを呼んでみましょう。

http://docs.repro.io/ja/dev/sdk/device-id.html#id

```ts:app.component.ts
import { Component } from "@angular/core";
declare let io: any;

@Component({
  selector: "gr-main",
  template: "<page-router-outlet></page-router-outlet>"
})
export class AppComponent {

  constructor(){
    console.log( "DeviceID => " + io.repro.android.Repro.getDeviceID() );
   }

}
```

ここでも、`declare let io: any;` という宣言で io 名前空間のコンパイルエラー回避をしているのがポイントです。

アプリをビルド＆起動すると、コンソールログに

```shell-session
DeviceID => xxx
```

と表示されるはずです。Repro SDKを呼び出すことが出来ました！

## 最後に

Cordova+Ionicのアプリを約3年間運用してきて、一番つらかったのは、ネイティブの機能を連携させるときです。外部の広告SDKを入れたいとき、ネイティブのUIコンポーネントを使うときなど、ネイティブの機能を使おうと思ったときに、必ず直面するのが「Cordovaでサポートされてるのか」問題でした。Cordovaではプラグインという機能でネイティブの機能を呼び出すことができるので、既に誰かが書いたプラグインがあればすぐに導入できるが、無ければ自作しなくてはならない、ということで導入の大きなハードルになっていたのです。しかも、プラットフォームそれぞれの言語でプラグインを書く必要があります。例えばiOSとAndroi両方をサポートしたアプリであれば、iOSではObjectiveC、AndroidではJavaのコードを別々に書くといったように。さらに、ネイティブコードをJSで呼び出せるようなJavaScriptのラッパークラスも必要です。大きなライブラリであれば、そのプラグイン実装に１週間以上かかったこともあります。

ところが、NativeScriptでは、JavaのAPIを直接TypeScriptで呼び出すことができます。これは大きな飛躍です。また、GradleといったAndroid標準のビルドシステムもサポートされているので、aarパッケージなどで提供されるライブラリであっても容易に導入することが出来ます。ObjectiveCやJavaに慣れていなくても呼び出せ、アプリの開発言語であるTypeScriptで書けるので、開発効率も非常に高いです。

なお、NativeScriptの開発者である「TJ VanToll」氏によれば、「Cordovaのプラグイン制作の難しさは、我々がNativeScriptを作り、APIへの直接アクセスを出来るようにした大きな要因の一つ」と語っていて、Cordovaをかなり意識して作られていることがわかります。

下記の記事が詳しいです。
http://developer.telerik.com/featured/write-nativescript-plugins-theyre-easier-cordova-plugins/