JINS MEME x socket.ioで離席時に自動でスクリーンロックをかけるやつを作ってみた

# What's JINS MEME
一言でいうと、外ではなく内を見ることのできるメガネです。詳細については以前まとめたものがありますので、そちらをご参考ください。
http://qiita.com/mito_log/items/020a87996ed2b9d793e6

# Motivation
私は特定のオフィスをもっていないので、作業をするのはほぼカフェとかコワーキングスペースなどのpublicなスペースです。そこでトイレに行きたいなどの離席時に、画面を自動でロックしてくれたら1秒くらい時短できるなぁ(洒落てるなぁ)と思って今回のサンプルを作り始めました。今回もRxSwiftです。

# What I created (gif movie)
![autoLockScreen.gif](https://dl.dropboxusercontent.com/u/91774212/autoLockScreen.gif)

# What will be covered
今回は2部構成の2部目の記事、という体裁にしています。各部の内容は以下：

 - [ローカルに立ち上げたsocket.ioサーバを介してデータをリアルタイムにmac PCに出力する](http://qiita.com/mito_log/items/8108c38a6c8cb4475e7b)
 - mac側では受け取ったデータを使って、PCを離れると自動的に画面ロックがかかる (← 本記事)

# github
https://github.com/mitolog/JINSMEMESampler
今回のサンプル部分は[こちら](https://github.com/mitolog/JINSMEMESampler/tree/master/JINSMEMESampler/AutoLockScreen(socketio))

# How it works
![jinsmeme_autoscreenlck.png](https://qiita-image-store.s3.amazonaws.com/0/46489/36d80a9e-e5ea-03bc-0583-250468e38d0a.png)

仕組みとしては、

1. iOSアプリでJINS MEME SDKを経由して取得したデータをsocket.ioクライアントを用いてnode serverに送信します
2. node serverではiosアプリからのデータをそのままmac側に受け流します(broadcast)
3. macアプリでは、node serverから届いたJINS MEMEデータから`isWalking`パラメータを抜き出し、x歩カウントされたら、スクリーンロック

という感じです。

# Recap

# How to Lock Screen via mac app
"アプリからどうやって画面ロックを実行するか"を調べてみると、[stackoverflowで色々とやり方が紹介](stackoverflow.com/questions/1976520/lock-screen-by-api-in-mac-os-x)されていました。その中でも一番簡単そうな**NSTaskを使って、terminal(シェル)のコマンドを実行する**手法を今回は採用しました。

コードとしては本当に単純で、

```swift:ViewController.swift
let task = NSTask()
task.launchPath = NSBundle.mainBundle().pathForResource("CGSession", ofType: nil)!
task.arguments = ["-suspend"]
task.launch()
```

これだけです。ポイントとしては、CGSessionのシンボリックリンクを作ってそれをNSBundleに入れてあげていることです。直接リンク先をlaunchPathに指定するとアクセス出来ないよとエラーになってしまうので、今回このような泥臭いやり方になりました。

```bash
$ cd path/to/project/directory
$ ln -s /System/Library/CoreServices/Menu\ Extras/User.menu/Contents/Resources/CGSession
```

## Some todos...
今回はあくまでサンプルということで、とりあえず動くところまでやりましたが、もし万が一アプリとして提供する場合にはまだクリアすべき課題がいくつかあります。

### 1. socket.ioサーバをローカルPCでデーモン化する?クラウドに置く？
これクリアしないと、毎回`node app`なんて打たなければいけません。そんなの面倒すぎます。

### 2. 離席時間が長いとsocket.io切れない？大丈夫？
各種仕様を把握していないので、確認しないと変な挙動がでそうです。ロック中にsocketはtimeoutしないかとか、iOS/macアプリがバックグラウンドにいくとどうなるとか。もろもろ。

### 3. 離席/着席の判定をちゃんとする
現状は、あくまでサンプルということで、離席から戻った判定をせず、macアプリ上のconnect/disconnectボタンを押すことで'着席した'ということにして、歩数カウントのリセットし、再度離席モニタリングを開始をしています。これだとただ無駄な作業が増えるだけなので、着席チェックを自然に行うには〜をもう少し詰めないといけません。

### 4. 右上のメニューバーに追加しておけると便利かも？
nice to haveな単なる願望です。[stackoverflow](http://stackoverflow.com/questions/3409985/how-to-create-a-menubar-application-for-mac)とか[こういうとこ](https://nsrover.wordpress.com/2014/10/10/creating-a-os-x-menubar-only-app/)見つつやってみたい。

ということで、要改善点は多いですが、JINS MEMEのある生活を少しイメージできたのではないでしょうか。

# JINS MEME is very robust
私は[fitbit(腕時計型万歩計)](https://www.fitbit.com)も使っているのですが、あれだと着けている部分が汗ばんできて、カフェとか目的地につくと100%と行っていいほど外しています。一方でメガネは常に身に着けているもの(ないと困る)なので、歩数だったり、姿勢だったり、眠気や瞬きなどを、ユーザが意識すること無く常にセンシングすることができます。

今回は`席を離れる`というアクションだけで画面を自然にロックすることができましたが、他にも[`姿勢が悪くなる`というアクションでLED照明の色を変化](http://yuichi-dev.blogspot.jp/2015/12/Attitude-monitoring-jins-meme.html)させたり、[`上を向く`というアクションだけでスクリーンを暗く](http://kyoro353.hatenablog.com/entry/2015/12/15/061208)したり、そういう自然なインタフェースを実現して、より生活に溶け込んで且つ生活の質を向上させるアプリケーションを実現できるんじゃないかなーと思っています。

ただ、1点、20年来のメガネユーザー(コンタクトは3日で紛失したくらい相性が悪い)として言いたいこととしては(JINS MEME ESの場合)、柄の部分が真っ直ぐなせいで耳にfit感がなくて、下をむくとかちょっと激し目な動きをすると、落ちそうになっちゃいます。そこをどう回避したらいいかを教えてほしいです(笑)。

# References
[【OSX】【swift】コマンドの実行](http://qiita.com/kitanoow/items/8b551a2d121ff95ef553)

[socket.ioの公式クライアントについて](http://socket.io/blog/socket-io-on-ios/)