「だいじょぶだぁ」と言うとSAP CP Workflow Serviceで購買依頼登録が承認されるiOSアプリを実装する(2/2)

こんにちは、Mona Lisacoです。

[前回の記事](https://qiita.com/monamona/items/e5862409b6b7fb0902bf)では、SAP Cloud Platform Workflow Serviceを用いてだっふんだWorkflow定義を作成しました。

今回は、**どうしても「だいじょぶだぁ」と言って購買依頼を承認したい！！！！！**
という店長の熱い思いを叶えるべく、Apple社のSpeech Frameworkを活用したiOS AppとSAP CP Workflowの連携に取り組んでいきます。


# アーキテクチャと構築手順

アーキテクチャのイメージを再掲します。
![アーキテクチャ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320955/17e89375-ce3d-8cdb-f685-3745809ca39b.png)

今回の記事では、
- Workflow API for NeoをiOSアプリから叩く方法
をご紹介していきます。

そもそもiOSアプリのSpeech Frameworkを用いた音声認識ってどうやるのか、については[Mona Lisacoの過去記事](https://qiita.com/monamona/items/c55435580eaad482c7f7)をご参照ください。

# 前提条件と制限(再掲)

## 前提条件

- フロントエンド実行環境: iPhone8 iOS 12.3.1
- フロントエンド開発環境: macOS Mojave 10.14.4 / Xcode 10.2.1 / Swift 5.0.1
- クラウド開発実行環境: SAP Cloud Platform（NEO） ※ SAP CPユーザを作成すれば無料のトライアル環境でWorkflow Serviceを使用できる。
   - SAP CP ConnectivityでWorkflow RuntimeのDestinationが設定されていること（デフォルトで設定されているはず）。
   - SAP CP Connectivityでオンプレミス環境へのDestinationが設定されていること。（▲）
- バックエンド: SAP S/4HANA （オンプレミス） 
   - SAP CPとSAP HANA Cloud Connector(SCC)で連携されていること。（▲）
   - 購買依頼を登録できる適当なOData Serviceが有効化されていること（この記事ではカスタム実装したOData Serviceを使用する）。（▲）

※（▲）を付したものはOData Serviceを用いるための条件なので、WorkflowとiOS Appだけ試しに実装してみたい！という場合は不要です。

## 制限

- 今回の実装はトライアル環境（1ユーザ=1環境）で行うため、店長役の人とスタッフ役の人を技術的には別ユーザとして区別できない。


# Workflow API for NEOをiOSアプリから叩く方法

## Workflow API for NEOをテストする

Swiftのコーディングを始める前に、[SAP API Business Hub (Workflow API for NEO)](https://api.sap.com/api/SAP_CP_Workflow/resource)を用いてAPIをテストしておくのがおすすめです。

SAP CPユーザでログインし、Configure Environmentボタンを押して自分のSAP CP環境のbpmworkflowruntimeの宛先（SAP CP Connectivity参照）を設定すると、自分のSAP CP環境でのAPIのテストを行うことができます。

![b1.0API.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320955/e72b5217-6007-1904-a2b2-6f1db1869314.png)
<img width="929" alt="b2.0Environment.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320955/b69d48e5-947a-8361-3543-6af4f1ad0812.png">

それぞれのAPIに対して"Try out"ボタンを押下するとウェブサイトがテストモードに切り替わります。
ここで渡すべきパラメータやHTTPレスポンスなどを先に確認しておくことで実装イメージが固まり、迷いなくコーディングすることができます。
<img width="1223" alt="b3.0TryOut.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320955/1264e161-d123-74d2-8077-951c65793255.png">

（今回は下記でHTTPリクエストの書き方をご紹介するので、SAP API Business Hubの詳細な使用方法の説明は省きます。）

## だっふんだ！と言ってPOSTメソッド（Start a new instance）を使用しWorkflow Instanceを開始する

それでは実装を始めていきましょう。
まずは店舗スタッフが使用する想定の、「だっふんだ！」と言ったら「ドリフ大爆笑DVD」の購買依頼承認申請を出せるアプリです。

▼画面イメージ
![bapp1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320955/63f58582-7ad9-d237-9c97-c53701d1ae25.png)

「だっふんだ！」と音声認識ができた場合、POSTリクエストによってWorkflow定義のIDとWorkflow Context(後にService Taskで用いる伝票情報を格納)を渡し、新しいWorkflow Instanceを開始します。

APIの詳細仕様は[こちら](https://api.sap.com/api/SAP_CP_Workflow/resource)。
<img width="1182" alt="b4.api1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320955/b9496466-a316-ddf2-fafe-c1501e4ddfcc.png">

※今回の実装のソースコードサンプルは[こちら](https://qiita.com/monamona/items/0aeb231df1748b6300dd#%E3%81%A0%E3%81%A3%E3%81%B5%E3%82%93%E3%81%A0%E3%81%A8%E8%A8%80%E3%81%A3%E3%81%A6post%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89start-a-new-instance%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97workflow-instance%E3%82%92%E9%96%8B%E5%A7%8B%E3%81%99%E3%82%8B)。

## GETメソッド（Retrieve task by query parameters）を使用しWorkflow Instanceを取得する

次は店長が使用する想定の、「だいじょぶだぁ！」と言ったら「ドリフ大爆笑DVD」の購買依頼を承認できるアプリです。

▼画面イメージ
![bapp2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320955/ad9099a8-4417-74c0-a2b1-2a1c0c378151.png)

まず、画面表示時やテーブル更新時（下にスワイプしたとき）などにTask Instanceのデータを取得します。
URLにフィルタ用のパラメータを設定してGETリクエストを投げ、レスポンスでそれに合致するUser Task Instanceの情報を一括取得します。
今回のアプリでは取得した情報を配列に格納し、それを画面上のテーブルにリスト表示させています。
また、このとき取得したTask Instance IDをあとでだいじょぶだぁ承認するときに使います。

APIの詳細仕様は[こちら](https://api.sap.com/api/SAP_CP_Workflow/resource)。
<img width="1159" alt="b5.api2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320955/4c8b3166-db71-2e5e-c8ed-e3a6ff46d01c.png">

※今回の実装のソースコードサンプルは[こちら](https://qiita.com/monamona/items/0aeb231df1748b6300dd#get%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89retrieve-task-by-id%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97workflow-instance%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B)。

## だいじょぶだぁ！と言ってPATCHメソッド（Update task by ID）を使用しUser TaskのStatusをCOMPLETEDにする

それではいよいよだいじょぶだぁ！またはだめだこりゃ！と音声認識できたときに呼ぶメソッドを実装しましょう。

テーブルにリスト表示したTask Instanceがタップされたとき、そのInstanceにひもづくTask Instance IDを取得しておきます。
このIDを見ることで、どのTask Instanceに対して処理を行いたいのかを識別することができます。
だいじょぶだぁ！またはだめだこりゃ！と音声認識されたらPATCHリクエストに下記の情報を渡します。

- 状態を変更したいTask InstanceのID
- Task StatusをCOMPLETEDに変更
- 「だいじょぶだぁ！（承認）」なのか「だめだこりゃ！（否認）」なのか（Workflow Contextに渡す）

APIの詳細仕様は[こちら](https://api.sap.com/api/SAP_CP_Workflow/resource)。
<img width="1173" alt="b6.api3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320955/af98f39d-4c9d-65ee-1855-c9baa76c81b6.png">

※今回の実装のソースコードサンプルは[こちら](https://qiita.com/monamona/items/0aeb231df1748b6300dd#%E3%81%A0%E3%81%84%E3%81%98%E3%82%87%E3%81%B6%E3%81%A0%E3%81%81%E3%81%A8%E8%A8%80%E3%81%A3%E3%81%A6patch%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89update-task-by-id%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97user-task%E3%81%AEstatus%E3%82%92completed%E3%81%AB%E3%81%99%E3%82%8B)。

# iOSアプリとSAP CP Workflowが連携できているかどうかテストする

## だっふんだ！

だっふんだ！と言ったあとでSAP Fiori Launchpad "Monitor Workflow - Workflow Instance"を見てみると、ちゃんとタスクが1つ増えている！
だいじょぶだぁ承認アプリでテーブルを下に引っ張り更新すると、こちらでもタスクが1つ増えている！

## だいじょぶだぁ！

だいじょぶだぁ！と言ったあとで"Monitor Workflow - Workflow Instance"を見てみると、ステータスが「完了」になっている！
ログを見ると、Service Task「SAP S/4HANAで購買依頼を登録」も無事実行されている！

## だめだこりゃ！

だいじょぶだぁ！と言ったあとで"Monitor Workflow - Workflow Instance"を見てみると、ステータスが「完了」になっている！
ログを見ると、Service Task「SAP S/4HANAで購買依頼を登録」は実行されずにWorkflow Instanceは終了している！

## だいじょぶだぁ分岐条件について

Workflow定義の**Sequence Flow Properties(承認の場合)**"のプロパティに記載した分岐条件について前回の記事で紹介しました。

`${context.approved=="true"||usertasks.usertask1.last.decision=="approve"}`

**「Workflow Contextのapprovedの値が"true"」…(1)
または「usertask1の最後のDecisionが"approve"」…(2)
であれば購買依頼登録の方の分岐に進み、
どちらでもなければ何もしないで終了する方の分岐に進む。**

前回のテストでは(2)の方の条件を使用しましたが、今回のiOSアプリの実装で使ったのは(1)のほうです。
上記で紹介したソースコードでは、
- 「だいじょぶだぁ！」と言ったとき→APIに渡すworkflow Contextに含まれる"approved"の値が`true`となる
- 「だめだこりゃ！」と言ったとき→APIに渡すWorkflow Contextに含まれる"approved"の値が`false`となる
ように実装しており、これをフラグにして条件分岐させています。

# 終わりに

「だいじょぶだぁ」と言ってSAP CP Workflow Serviceで購買依頼登録が承認されるiOSアプリがついに完成しました！

しかも店舗スタッフが何度「だっふんだ！」を楽しんだとしても不要な分は店長が「だめだこりゃ！」と言って否認すればいいので、
スタッフも店長もともに素晴らしいドリフ的職業生活を好きなだけ営むことができます。商売人冥利に尽きるとユーザからも好評です。

こうしてとある雑貨店の麹町一丁目店の平和は再び守られたのでした。
お近くにご用の皆さまはぜひ足を運んでいただき、安心して「ドリフ大爆笑DVD」をお買い求めくださいませ。