シチズンデベロッパーによるOutSystemsモバイルアプリケーション作成過程のイメージ

[開発速度を上げ、反感を買う　ローコード開発の光と影](http://techtarget.itmedia.co.jp/tt/news/1901/10/news05.html)に以下のような記述がありました。
>米アイオワ州ジョンストンを拠点とする農業科学企業DuPont Pioneerでは、同社の社内モバイルアプリの約90％をシチズンデベロッパーが開発している。

ここでいうシチズンデベロッパーとは、
>技術者だけでなく、IT部門以外に所属する開発経験がほとんどないような人々

ということなので、IT部門以外でIT技術者でない人、また開発経験がほとんど無い人々なのでIT部門でも自分で開発しない人は含まれるのではないでしょうか。

この開発をOutSystemsでやっているということなので、実際に開発経験がほとんど無い人がOutSystemsでモバイルアプリケーション開発をすると、どんな感じになるのか考えてみました。

以下、全くOutSystemsを知らない人がわかることを目的として書いていきます。わからないことがあったら、是非コメント等で教えてください。

# 前提条件
環境は以下の通り。
Service Studio：11.0.204.114(Beta)
Platform(Personal Environment)：11.0.118.0

また、OutSystemsの環境のセットアップ、必要な部品のインストール、モバイルアプリケーションビルドのための設定は専門家によって行われているとします。

開発する人の想定スキルは、Officeやブラウザは問題なく使える、本を見ながらコピー・アンド・ペーストでいいから数行程度のVBAくらい書ける、程度。

# 作成するアプリケーション
上の記事の最後あたりに、ネットワークが通じない場所で検査するために、オフラインでフォームに情報を入力する例が出てきます。これに合わせて、以下の条件で作っていきます。

- 利用者は、作成者が所属する部門のごく限られた人数
- 検査対象の名前(Text型、Name)、検査日(Date型、SurveyDate)、検査完了(Boolean型、IsSurveyFinished)、検査結果(Integer型、SurveyResult)を入力するフォーム1画面を持つ
- 作りを簡単にするため、入力したデータを確認する画面はなし
- フォームにはオフラインで入力する。入力結果はモバイル端末内のLocalDBに持つ

こんな画面ができます。
![qiita2_17.PNG](https://qiita-image-store.s3.amazonaws.com/0/332987/96846efb-1e98-b67b-2930-651f91207270.png)

入力すると端末内のデータベースに蓄積されます。

# アプリケーションとモジュールを作成
モバイルアプリケーションはモジュールという単位として作成します。
このモジュールはアプリケーションに格納します。

よってまずはアプリケーションを作成します。
Service StudioでNew Application、Mobile Appと選択して、NEXTボタンをクリック。
![qiita2_1PNG.PNG](https://qiita-image-store.s3.amazonaws.com/0/332987/178409db-7a78-9457-5956-2293289bd57e.png)

次の画面でどのテンプレートで作るか選択肢がでてきます。ここではスマートフォンで動作することを考えて、Phoneを選択して、NEXTボタンをクリック。

名前を入力してCREATE APPボタンをクリック(説明は入力した方がいいですね。色合いやアイコンはごく少人数で使うことを想定してそのままにします)。
![qiita2_2.PNG](https://qiita-image-store.s3.amazonaws.com/0/332987/356b4bd1-cbff-ece3-fa74-f8be8340caee.png)

モジュール名はアプリケーション名のままにして、Module TypeはMobileであることを確認してから、CREATE MODULEボタンをクリック。
![qiita2_3.PNG](https://qiita-image-store.s3.amazonaws.com/0/332987/ee8536b9-3086-404f-eb87-aabcfe40080a.png)


# Entityを用意
OutSystemsではDBのテーブルに相当する要素をEntityと呼びます。

今回は、ごく限られた人数が身内だけで利用することを想定しているので、モバイルのモジュール中にEntityを定義していきます。

まずはサーバ側Entity、後でWebアプリケーションで閲覧するのに使うEntityを定義します。
Dataタブを開き、Entities>Databaseを右クリックしてAdd Entity。
![qiita2_4.PNG](https://qiita-image-store.s3.amazonaws.com/0/332987/80cca977-81a1-2595-5502-b5889b8afde9.png)

作成されたEntityの名前を「Survey」に変更し、Surveyを右クリックしてAdd Entity Attributeで属性を追加していきます。「作成するアプリケーション」に書いた4つと、検査担当者(Text型、SurveyUserName)を追加しました。
![qiita2_5.PNG](https://qiita-image-store.s3.amazonaws.com/0/332987/8e4d3baf-cd22-00b2-0de1-54e7c9ff2101.png)

後で別のモジュール(閲覧用Webアプリケーション)から参照するため、PublicプロパティをYesにしておきます。

LocalDBにも同じEntityを定義します。

今回は、すでにサーバ側にEntityがあるので、ここからコピーして作成です。
Dataタブを開き、Entities>Local Storageを右クリック。Add Entity from Databaseを選択。
![qiita2_6.PNG](https://qiita-image-store.s3.amazonaws.com/0/332987/27e27e91-2284-5476-5d6e-bdd8f8dd1a37.png)

EntityはSurveyを選択し、Attributeはサーバ同期時に追加する予定のSurveyUserName以外を選択してADDボタンをクリック。。
不要なデータはデータ容量、同期時の通信容量を食うので必要最小限をLocalDB荷物ことが推奨されています。
![qiita2_7.PNG](https://qiita-image-store.s3.amazonaws.com/0/332987/79efe003-293c-f314-0ac1-649767aa3409.png)

LocalDBに作成されたEntity(Localのプレフィックスがつきます)。
![qiita2_8.PNG](https://qiita-image-store.s3.amazonaws.com/0/332987/365ed3d6-d4ba-1dc4-a767-c81e69210a20.png)

このEntityは実行時にユーザの端末内のsqlite DBにテーブルとして保持されます。

# スクリーン作成
OutSystemsには、Screen Templateと言う仕組みがあります。

画面作成時に、画面のテンプレートとして利用できるもので、これをベースに画面を作成すると、サンプルデータを使って組み上がった状態になります。

利用できるScreen Templateがある場合は、サンプルデータを実際に使用するデータに紐付け直して微調整することですぐに完成度の高い画面が作れます。

どんな感じのテンプレートがあるかはここで確認できます。
https://www.outsystems.com/outsystems-ui/screens/mobile

また、つい最近このScreen Templateを自作する機能がリリースされたので、企業の要件に合わせたテンプレートを事前に作成しておくことで、Low-Codeの生産性を享受できる範囲が拡大できるかもしれません。

とは言え、今回は単純な入力フォームを作るので、あえてScreen Templateを使いません。

InterfaceタブのUI Flows>MainFlowを右クリックして、Add Screenを選択し、テンプレートはEmptyとしてCREATE SCREENボタンをクリック。

![qiita2_9.PNG](https://qiita-image-store.s3.amazonaws.com/0/332987/c4974d2e-74d4-3d52-637c-0a2d474ac9a8.png)

# ドラッグ＆ドロップで入力フォームを作成
フォームを作成したいので、できあがった画面にForm Widgetをドラッグ＆ドロップします(下の画像の左の赤枠内のウィジェット)。

そして画面上にドロップしたForm ウィジェットの上に、作成しておいたLocalDB>LocalSurvey(Dataタブ)をドラッグ＆ドロップ(右の赤枠の位置でドロップしてください)。

![qiita2_10.PNG](https://qiita-image-store.s3.amazonaws.com/0/332987/187274a2-6f05-712a-8c47-3b68ea3f2003.png)

この時点で、

- パラメータとして、LocalSurveyのId(レコードを特定する値)を受取る(入力変数：LocalSurveyId)
- パラメータでLocalDBを検索する(Entity：GetLocalSurveyById)
- 検索した1レコードを表示する
- パラメータが渡されなかった場合は、値は空で表示する

という画面ができています。

入力したデータをローカルのデータに格納する処理を書きましょう。
Saveボタンをクリックしたら入力内容を変数に格納してLocalSurveyに1データ追加(既存データの場合は更新。今回のUIでは想定しませんが)する処理を書きます。

できあがったフォームのSaveボタンを選択してください(画像左の赤枠)。
すると画面右下にSaveボタンの設定が表示されるので、その中のOn Click(ボタンクリックしたときの動作を紐付ける設定です)の右側にある下向き三角形(▼)をクリック。
その中で、(New Client Action)を選択します。これで保存処理の枠ができます。
![qiita2_11.PNG](https://qiita-image-store.s3.amazonaws.com/0/332987/84277e0c-0aac-e0c9-6451-f1ff0f94aeb0.png)

Client Actionというのは、端末内で動作するひとかたまりの処理を定義するものです。
実行時にJavaScriptに変換されて動作します。

入力内容を更新し、次の登録のために、画面を再び空にする処理です。
![qiita2_12.PNG](https://qiita-image-store.s3.amazonaws.com/0/332987/ff9da39b-5d75-75ea-e0c9-8b13df1b380c.png)

画面内のアイコンは対応するものを、画面左側からドラッグ＆ドロップしてください。
上から順に説明します。

1. Form1.Valid?：この部分は作成時に自動的に配置されるので作成不要です。入力内容が正しいかを判定(型があっているか、必須入力を満たしているかなど)
2. CreateOrUpdateLocalSurvey：LocalSurvey Entityに1レコード登録。ただし、パラメータで受け取ったIdがある場合、対応するレコードに対する更新となります
3. LocalSurveyId：パラメータ(LocalSurveyId)をNullIdentifier()に設定
4. Refresh……：Entityを再取得する。3でNullIdentifierを設定するため、空のレコードが返ってきます

これだけでもう入力フォームができあがりです。

Chromeが入っていれば、動作確認が可能です。
1-Click Publish(画面上部の緑のアイコン)をクリックしてサーバに変更を反映し、アイコンが青に変わったらもう1回クリックするとPC上のブラウザでプレビューできます。

![qiita2_13.PNG](https://qiita-image-store.s3.amazonaws.com/0/332987/1fec3deb-b80c-798f-8f9e-a25957a7fa9f.png)

入力したデータを確認するUIを作っていませんが、ブラウザプレビュー中には、Chromeの機能で確認できます。
F12キーを押してデベロッパー　ツールを起動し、Applicationタブ＞Storage>Web SQLの下にEntityを見るためのUIがあります。

![qiita2_18.PNG](https://qiita-image-store.s3.amazonaws.com/0/332987/b1916405-e447-91db-8e78-45a658e15d0d.png)

# UI Patternからウィジェットを追加
作成したフォームの内、検査結果はInteger型(整数)であるにもかかわらず、直接入力のテキストボックスになっています。

これをもう少し項目が整数であることがわかりやすい部品に置き換えてみます。

UI部品を探すときは、まずはService Studio左側に表示されるウィジェットを見ますが、その次はUIフレームワークです。

OutSystems 11ではOutSystems UIです。
https://www.outsystems.com/outsystems-ui/patterns/mobile

ページを見渡して、要件を満たすUIを探してみます。
RangeSliderと言う部品がありました。数値をスライダーを使って入力できます。
https://www.outsystems.com/outsystems-ui/patterns/mobile/RangeSlider

まずは、参照を確認しましょう。
Service Studio上でCtrl+QでManage Dependenciesダイアログを開き、OutSystemsUIMobileのInteraction>RangeSliderのチェックを確認します。
もしチェックがなかったらチェックしてOKボタンをクリック。
![qiita2_14.PNG](https://qiita-image-store.s3.amazonaws.com/0/332987/34214678-da72-c3a3-1f43-7da170cf12b3.png)

整数型のSurveyResult変数を紐付けてあったInputを削除し、代わりにRangeSliderをドラッグ＆ドロップして配置します。
RangeSliderはInterfaceタブのUI Flows>OutSystemsUIMobile>Interactionsにあります。

UIフレームワークの使い方は上記ページのHow to Useにあります。

> Bind your variable to the InitialValue input and use the OnChange event to add your logic to handle value changes.

残念ながら英語です。

- 変数をInitialValueプロパティに紐付ける
- OnChangeイベントハンドラを作成して、紐付けた値を変化させる

ですね。
OnChangeイベントハンドラはドロップしたウィジェットのEvents>Handlerプロパティの(New Client Action)で作ります。
こんな感じになります。
![qiita2_15.PNG](https://qiita-image-store.s3.amazonaws.com/0/332987/a998c1af-b1de-9c38-67b6-d514da7aab7f.png)

- スライダーは0-10の範囲で変化する。
- 紐付ける変数は元々あったInputの時と同じくEntityの整数型の属性。
- OnChangeのハンドラは以下の通り(入力変数Value:Changeイベント発生時のスライダー上のつまみの位置の値、をフォームの変数に設定している)

![qiita2_16.PNG](https://qiita-image-store.s3.amazonaws.com/0/332987/9bfc27b6-84ee-d7aa-57a6-c2b9875e16d4.png)

この段階で実行イメージ
![qiita2_17.PNG](https://qiita-image-store.s3.amazonaws.com/0/332987/96846efb-1e98-b67b-2930-651f91207270.png)

# 所感
あまりにも長くなりすぎたので、証跡の画像を端末のカメラで撮影する部分と、入力結果をOutSystemsサーバに吸い上げ、Web画面で一覧する部分は後日別の記事に譲ることにしました。

長い手順に見えるかもしれませんが、手順書用意するか、一度慣れてしまえば簡単に何度でもできるようになるのではないでしょうか。

ただ、残念ながら、UIフレームワークの説明が薄すぎ、英語のみはきついですね。
OutSystemsの専門家チームがいたら、そのチームがウィジェットの使い方を調べてマニュアル化したらいいかもしれませんね。

もし使い方がわからないウィジェットがOutSystems UIのパターンにあったらコメントで質問ください。
70ほどもあるので即答はできないと思いますが、なるべく調べて回答してみます。