JavaScriptからNative APIを”直接”さわるNativeScript for Capacitorとプラグインがβ版リリース!

2021/02/25に公開

This article as English is here:
https://nativescript.org/blog/nativescript-for-capacitor-explained/

Description

  • NativeScript for Capacitorを使えば、JavaScriptからデバイス Native APIに直接アクセスできる
  • 今まではSwiftやJavaで書く必要があったところが、JavaScriptだけで完結するようになった
  • @nativescript-community/capacitor-plugins を使えば、NativeScript for Capacitorのプラグインを利用できる
  • Web技術ができればストアアプリからアプリを配信できる時代はきてる

1. NativeScript for Capacitorとは

すごい世の中がやってきました。モダンなハイブリッド開発(Mobile Apps using WebView)のためのライブラリ「Capacitor」で、JavaScriptから、Native APIに ”直接” アクセスできるようになりました。

そう、NativeScript for Capacitorを使えば!

https://capacitor.nativescript.org/

何ができるようになったのか

NativeScript for Capacitor は、デバイスのNative APIに 対応した ほぼ同名のメソッドを用意しています。

例をあげましょう。iOSには、デバイスの輝度を設定するためには、デバイスオブジェクト UISCreen にあるメイン画面オブジェクト mainScreen() のオブジェクト brightness に値をいれる必要があります。

Swift Code:

plugin.swift
UIScreen.mainScreen().brightness = 1

NativeScript for Capacitorでは、これに対応する UIScreenmainScreenbrightness を用意してありますので、以下のようにJavaScriptで書くことができます。

NativeScript for Capacitor code:

plugin.js
UIScreen.mainScreen.brightness = 1

ほとんど同じでしょ?

また、AndroidのJava(SDK>24/canWrite)では、デバイスの輝度を設定するために、 Settings.System.putInt オブジェクトに以下のように設定する必要があります。

Java Code:

plugin.java
Settings.System.putInt(
  contentResolver, 
  Settings.System.SCREEN_BRIGHTNESS,
  100
);

NativeScript for Capacitorでは、 android.provider 以下に Settings オブジェクトを持っているので、以下のように書くことができます。

NativeScript for Capacitor code:

plugin.js
android.provider.Settings.System.putInt(
  context.getContentResolver(),
  android.provider.Settings.System.SCREEN_BRIGHTNESS,
  100
);

つまり、iOSとAndroidの両方で動くコードは以下のようになります。

NativeScript for Capacitor code:

plugin.js
if (!native.isIOS) {
  UIScreen.mainScreen.brightness = 1
} else {
  android.provider.Settings.System.putInt(
    context.getContentResolver(),
    android.provider.Settings.System.SCREEN_BRIGHTNESS,
    100
  );
}

NativeScript for Capacitorを使うことで、WebView上のJavaScriptから、デバイスのNative APIにアクセスできる時代になったのです。

今までできなかったの?

Capacitorにおいて、Native APIにアクセスする機構として「Capacitorプラグイン」があります(Cordovaプラグインも利用可能ですが構造は同じですので省略します)。これらは、デバイスのNative APIにアクセスするための処理をNativeで書きます。つまり、 Capacitorプラグインでは、SwiftとJavaを書く必要がありました。

そして、そのコードをJavaScriptからアクセスし、またイベントを受け取るためのインターフェイスがプラグイン機構でした。

Plugin.java (your work) - JavascriptInterface - JavaScript(your work)
Plugin.swift(your work) - WKUserScript - JavaScript(your work)

それに対して、NativeScript for Capcacitorは、それぞれのデバイスのNative APIのインターフェイスを用意しますので、JavaScriptのみで書くことができます。

NativeScript of iOS     - JavaScript(your work only!)
NativeScript of Android - JavaScript(your work only!)

これが一番大きな違いです。

脚注:
サードパーティライブラリを使う時はCapacitorプラグインをつくる必要があります。例えば、@capacitor-community/admobは、iOSでは Google-Mobile-Ads-SDK 、Javaでは com.google.android.gms:play-services-ads を利用しています。現在のところ、NativeScript for Capacitorでこのようなサードパーティライブラリを利用することはできません。

2. @nativescript-community/capacitor-pluginsでコードの再利用性を高める

NativeScript for Capacitorはパワフルですが、処理をプロジェクト内の専用ファイル src/nativescript/index.ts に書くというルールによって、再利用性・保守性に問題がありました。サンプルコードを手に入れることはできますが、それをコピペするとサンプルコードの更新に気づくことができません。また、プロジェクトを跨いだコードの共有もすることができません。

この問題を解決するために @nativescript-community/capacitor-plugins をつくりました。このプラグインは、NativeScript for Capacitorを導入しているプロジェクトを強力にサポートします。

はじめるのは簡単です。

% npm --save @nativescript-community/capacitor-plugins

でインストールし、 src/nativescript/index.ts を以下のように書き換えます。

  import '@nativescript/capacitor/bridge';
+ import * as Plugins from '@nativescript-community/capacitor-plugins';

+ native = Object.assign(native, Plugins);
...

同様に、 src/native-custom.d.ts を書き換えます。

+ import type { pluginsGlobal } from '@nativescript-community/capacitor-plugins/src/interfaces';

  declare module '@nativescript/capacitor' {
    export interface customNativeAPI extends nativeCustom {}
  }

  /**
   * Define your own custom strongly typed native helpers here.
   */
- export interface nativeCustom {
+ export interface nativeCustom extends pluginsGlobal {

これだけでこのプラグインに用意されているメソッドを利用することができます。詳細は

https://github.com/nativescript-community/capacitor-plugins#usage

をご覧ください。

Help contribution

プラグインによって再利用性を高める試みは実現しましたが、現在のメソッドは輝度を調整するもの1つだけです。本プラグインはNativeScriptチームの

https://capacitor.nativescript.org/swag-contest.html

と連携しておりますので、こちらで提案されているようなソリューション実現にぜひ力を貸してください。

結論

Capacitorを使えば、SwiftやJavaで書いたネイティブアプリと使い勝手に差異のないアプリを、Web技術でつくることができます。しかし今までどうしてもデバイスのNative APIに直接アクセスするためにはSwift/Javaを書く必要がありましたが、NativeScript for Capacitorの誕生により、この制約も大きく前進しました。
また、 @nativescript-community/capacitor-plugins によって、そのようなNative Scriptを利用するJavaScriptコードも再利用・配布が可能となっています。

Web技術をもっているあなたが、ストアアプリに取り組まない理由はもうありません!

Discussion