iOSのワークアウトデータを見せびらかしたい [その2]

こんにちは。
SENSY株式会社のnkhrkです。

この記事は[SensyAdventCalender2017](https://qiita.com/advent-calendar/2017/sensy)の21日目の記事です。
なお、[13日目](https://qiita.com/nkhrk/items/e0f39b8c4794b71d858d)の記事の続きとなります。

# おさらい
前回は

- iOSプロジェクト作成
- ワークアウトデータを抽出
- 抽出したデータを加工

までを行いました。

今回は、抽出したデータを元に、いよいよワークアウトデータを見せびらかすことに挑戦しましょう。

# データを見せびらかす
Twitter, facebook, Instagramなど色々とSNSはありますが、
今回はエンジニア向けということで ***Slack*** へのPOSTを試してみます。

## Slack側の設定
まずはSlackの設定を行います。

### 前提
- 既にSlackチームが存在していること
- そのチームにAppを登録できる権限があること

### Slack Appを作成する
- https://api.slack.com/apps?new_app=1  にアクセスする
- Create a Slack App というウィンドウが開く
    - App Name
        - 作成するSlack Appの名前を入力
    - Development Slack Workspace
        - Appを登録する対象のSlackチームを選ぶ

<img width="350" alt="スクリーンショット 2017-12-21 13.32.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/167177/3fbd6a4f-99cb-d89d-ce2d-33184bfad1e5.png">

- "Create App"を押すと、自動的にSettingsの画面へ遷移する
    - "Incoming Webhook" -> Activate Incoming Webhooks -> ***"On"*** に変更
    - 下に "Webhook URLs for Your Workspace" が出て来るので、 "Add New Webhook to Workspace" を押す

<img width="350" alt="スクリーンショット 2017-12-21 13.41.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/167177/8fc84fff-c335-e5a3-2de8-1f8e5d303307.png">

---

<img width="350" alt="スクリーンショット 2017-12-21 13.41.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/167177/e3cc0a68-adee-5818-6949-3a4de13698eb.png">

- POST先のChannelを選ぶ
    - Authorizeを押す
        - 自動的に元の画面に戻り、 ***"Webhook URL"*** が追加されているため、控えておく

## SwiftからSlackへPOSTする
結局、Slack設定で取得した ***"Webhook URL"*** にPOSTするだけです。

- やってみる
今回はHTTPリクエストを簡単にするため、[Alamofire](https://github.com/Alamofire/Alamofire)というライブラリを使用します。
なお、インストール方法は割愛しますので、上記ページを参照してください。

- いよいよSlackへのPOSTですが、以下の仕様とします。
    - App起動時に一番直近のワークアウトデータの以下データをPOSTする。
        - 日時
        - 距離
        - かかった時間
        - 平均ペース
        - 消費カロリー

- POSTするfunctionを作成
以下のようにして、POSTする部分を作成します。

```ViewController.swift
// 追加
import Alamofire

~中略~

    // 追加
    // AlamofireでSlackへJSONをPOSTする
    func postToSlack(date: String, distance: String, time: String, pace: String, energy: String) {
        let parameters: Parameters = [
            "attachments": [
                [
                    "color": "#36a64f",
                    "text": "nkhrkさんはWorkoutを行いました。",
                    "fields": [
                        [
                            "title": "Date",
                            "value": date,
                            "short": true
                        ],
                        [
                            "title": "Distance",
                            "value": distance,
                            "short": true
                        ],
                        [
                            "title": "Time",
                            "value": time,
                            "short": true
                        ],
                        [
                            "title": "Pace",
                            "value": pace,
                            "short": true
                        ],
                        [
                            "title": "Energy Burn",
                            "value": energy,
                            "short": true
                        ]
                    ]
                ]
            ]
        ]
        let headers: HTTPHeaders = [
            "Content-Type": "application/json"
        ]

        Alamofire.request("[ここはSlackで取得したWebhook URL]",
                          method: .post,
                          parameters: parameters,
                          encoding: JSONEncoding.default,
                          headers: headers).responseString { response in print(response) }
    }
```

上記のfunctionが実装できたら、次は前回作成していた部分の `viewDidLoad` を少し修正します。

```ViewController.swift
    override func viewDidLoad() {
    // ~中略~
    DispatchQueue.main.async(execute: { () -> Void in
        for workout in self.workouts {
            // 以下のように変更する
            let km_double = workout.totalDistance!.doubleValue(for: HKUnit.meter()) / 1000
            let averagespeed = self.calcAverageSpeedForMeter(interval: workout.duration, distance: km_double)
            self.postToSlack(
                date: String(format: "%@ ~ %@", workout.startDate as CVarArg, workout.endDate as CVarArg),
                distance: String(format: "%@", workout.totalDistance ?? "no data"),
                time: String(format: "%@", self.stringFromTimeInterval(interval: workout.duration)),
                pace: String(format: "%@ / km", averagespeed),
                energy: String(format: "%@", workout.totalEnergyBurned ?? "no data")
            )
            break
            // ここまで
        }
    });
```

− 起動する
ここまでできたら起動してみましょう。

デバッグコンソールに `SUCCESS: ok` と表示され、Slackの指定したChannelへ通知されれば成功です。
<img width="350" alt="スクリーンショット 2017-12-21 15.24.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/167177/aebf333f-2e33-c8e7-a957-0b0d2964d263.png">

おつかれさまでした！

# 最後に
ここまでできれば、あとは煮るなり焼くなりして、いい感じにPOSTできるアプリが作れそうですね。
これまでのものをベースとして、もう少しいい感じに改良したものを時間のある時にGithubに置いておきますので、よろしければそちらもどうぞ！

では、みなさま良いランニングライフを！:runner::runner::runner: