OmniAICreator/Qiita-1.07M huggingface dataset:
Androidでパスコードロックを実現する

こんにちは[@u_nation](https://twitter.com/u_nation) です。

Androidアプリを作っていてパスコードロックが欲しいと思うことは良くあると思います。

私は2.3.3をサポートしていた時代はBaseActivityでライフサイクルを監視して無理くりアプリのバックグラウンドを検知してゴニョゴニョしていました。。
もちろん、精度も悪く、ただの画面遷移なのにパスコードロック画面が出たりとかなり消耗しました。。
巷のアプリでも、ロック画面が出たり出なかったりするアプリをチラホラ見かけます。

***ところが[@heki1224](https://twitter.com/heki1224)様のこちらの[スライド](http://www.slideshare.net/heki1224/android-45736528)を見つけて、全て解決しました！誠にありがとうございます(>_<)***

めちゃくちゃシンプルにアプリ全体のフォアグラウンド、バックグラウンドを検知できます。

```java
public class MyApplication extends Application implements Application.ActivityLifecycleCallbacks {
    private HashSet<Integer> activityStack = new HashSet<>();

    @Override
    public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(this);
    }

    @Override
    public void onTerminate() {
        unregisterActivityLifecycleCallbacks(this);
        super.onTerminate();
    }

    @Override
    public void onActivityStarted(Activity activity) {
        boolean isForeground = activityStack.size() == 0;
        activityStack.add(activity.hashCode());
        if (isForeground) activity.startActivity(/*Activity for entering passcode*/);
    }

    @Override
    public void onActivityStopped(Activity activity) {
        activityStack.remove(activity.hashCode());
        boolean isBackground = activityStack.size() == 0;
    }
    ~~~~
}
```

これを応用して、パスコードロックを実現した**[サンプル](https://github.com/u-nation/PassCodeLockSample)**を作りました。
ユーザーがパスコードロックを設定したら、バックグラウンドに入ったあとロック画面を表示し、解除されたら元の画面に戻るといういわゆる**LINE**のパスコードロックの完成度を目指しました。一年くらい放置したのを軽くリファクタリングしたため、バグってたらすみません。。

以上です。

## 追記
たまたま同僚の[@magie_pooh](https://twitter.com/magie_pooh)氏の[記事](https://qiita.com/magie-pooh/items/3aa733ba7f7670c234be)を見つけてさらにシンプルに画面回転を考慮した実装ができました。

簡単に説明すると`ComponentCallbacks2#onTrimMemory`をApplicationクラスで実装するとバックキーやホームボタン、マルチタスクボタンが押されてアプリがフォアグラウンドじゃなくなった事を検知できます。

```java
  @Override public void onTrimMemory(int level) {
    super.onTrimMemory(level);
    if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
      // do something
    }
  }
```

**[サンプル](https://github.com/u-nation/PassCodeLockSample)**の方も軽く更新したので、良ければぜひ(>_<)
CodeIgniter 3とtwigを連携させ継承して使う

ぐぐっても情報が少なかったので書いておきます。

#CodeIgniterにtwigテンプレートエンジン連携
##環境
・Composer
・PHP7.0.2
・CodeIgniter3.0.6
・twig1.24.0

##連携手順
applicationディレクトリ内にcomposer.jsonをまずは作成します。

```
vi cd application/composer.json
```

内容は

```json:composer.json
{
    "require": {
        "twig/twig" : "1.*"
    }
}
```

そしたら、Twigのインストールで

```
cd application
composer install
```

これでapplication/vendorディレクトリが作成されその中にautoload.phpとtwig本体が入るかと思います。

![WS000005.JPG](https://qiita-image-store.s3.amazonaws.com/0/110510/af22e001-eed9-7810-6ac2-b99e5394b611.jpeg)


vendor/autoload.phpを読み込ませるためにapplication/config/を変更します。

```
vi application/config/config.php
```

でコメントアウトされてない方の

```
変更前
$config['composer_autoload'] = FALSE;

変更後
$config['composer_autoload'] = TRUE;
```
に変更します。これでtwigが連携されました。

[CodeIgniter 3でTwigテンプレートエンジンを使用する](http://symfoware.blog68.fc2.com/blog-entry-1711.html)
こちらの記事のようにこのままcontrollerに毎回twigの宣言を書いても使えるのですが、毎回書くのも面倒ですよね？そこで本体CI_Controllerのコンストラクタにして毎回読み込まれるようにします。

##CI_Controllerの継承先MY_Controller作成

CI_Controllerを弄るのはあまり良くないので継承先で記述を追加していきます。
CI_Controllerを継承する時はMY_Controllerという名前にしないと使用できないようです。

まずはapplication/coreにMY_Controller.phpを作成します。

```
vi application/core/MY_Controller.php
```
内容を

```php:MY_Controller.php
<?php
class MY_Controller extends CI_Controller {
	protected $twig;

    public function __construct()
    {
    	parent::__construct();
        //テンプレートを配置しているフォルダを指定
        //今回はapplication/views
        $loader = new Twig_Loader_Filesystem('application/views');
        //オプションを指定して、twigインスタンス生成
        $this->twig = new Twig_Environment($loader, array('cache' => APPPATH.'/cache/twig', 'debug' => true));
    }
}
```

##コントローラ作成
先ほどの継承先を使います。
コントローラを作ってみましょう。

コントローラ作成します。

```
vi application/controllers/Sample.php
```

内容を

```php:Sample.php
<?php
class Sample extends MY_Controller {
	public function index() {
        //テンプレート読み込み先指定
        $template = $this->twig->loadTemplate('Sample.html');       

        $view_data = array('test_value' => '日本語でこんにちは');
        $this->output->set_output($template->render($view_data));
	}
}
```

テンプレート先も作成します。

```
vi application/controllers/Sample.html
```

内容は

```html:Sample.html
<p>{{ test_value }}</p>
```

これでいい感じにtwigを使えるようになりました。
開発現場で流すBGMの選曲基準やミックス

この記事は [作業用BGM(個人or社内) Advent Calendar 2015](http://qiita.com/advent-calendar/2015/bgm) の一部ではありません。
（投稿しようと思っていたら数ヶ月経っていました。。）

## 社内BGMについて
### BGMの選曲

職場では音楽当番なるものがあり、持ち回りで月一くらいで当番が回ってきます。
当番の日は、一日中自分の好きな音楽を流すことができます。
その際、自分が気をつけていることを書きます。

- **キャッチーな懐メロはほどほどにする**
懐メロを流すと、（曲を知っている同僚とは）盛り上がってスムーズなコミュニケーションの一助になりますが、流し続けると意外と作業の邪魔になりやすいです。
青春時代に苦い/甘い感情のある曲なら尚更です。
また、[Get Wild の流し過ぎ](http://togetter.com/li/951745)にも注意しましょう。  

- **攻撃的な曲/暗め要素の強い曲は流さない**
嫌なことがあっても、攻撃的な曲/暗め要素の強い曲はできるだけ流さないようにしています。
攻撃的な曲はだんだん疲れてきますし、暗すぎる曲は職場全体が沈んだ空気になります。

- **FMラジオに逃げない**
自分以外が担当の場合、FMラジオ（大体同じ局）が流れることも多いです。
流すネタが思いつかない時に、自分もFMラジオを流すのはアレなので、適当に [Soma FM](http://somafm.com/) などを流します。
（オススメは[Groove Salad](http://somafm.com/groovesalad/)）

### BGMのミックス

せっかくBGMを流すことができるので、できればDJぽく振る舞ってみたいですよね。
というわけで、単純に選曲するだけでなく、ノンストップミックスを作ってみましょう。

自分は、[Pacemaker](https://itunes.apple.com/us/app/pacemaker/id593873080?mt=8) というアプリ（iOS専用）を使ってミックスを作っています。 
曲を選曲していくだけで、曲と曲のミックスはアプリが勝手にやってくれるので、簡単にミックスが作れます。
Pacemaker については、[こちらのブログ](http://stopneko.blogspot.jp/2015/04/pacemaker-iphone.html)が参考になります。

## 開発に集中したいとき
フロー状態に入りたいときは、ノイズキャンセリングイヤホンを着けて外界の音をシャットアウトします。
イヤホンからはBGM代わりに [MUJI to Relax](https://www.muji.com/jp/beadssofa/) を流します。森林の音が好み。

## 番外編

Lisperだらけの職場なのであれば、問答無用でこれを流し続けましょう。
https://www.youtube.com/watch?v=4qsxTV3sg-g
参照：[竹内関数で音楽生成](http://d.hatena.ne.jp/aike/20111112)
browserSyncを使ってwordpress開発環境にlivereloadを導入する


Wordpressの開発環境だと、MAMP等を使ってphpの動くサーバー上で開発する必要があるため、
node製のbrowserSync.serverを使うことができない。

従って、livereloadを導入するにはphpファイルの中にreload用のjsスクリプトを埋め込んでおく必要がある。


以下はlocalhost環境のときだけbrowserSyncのスクリプトを埋め込むスニペット。

```index.php
<?php
if ( strpos( $_SERVER["HTTP_HOST"], 'localhost' ) !== false ) : ?>
    <script>
        document.write("<script async src='http://HOST:35729/browser-sync/browser-sync-client.2.11.2.js'><\/script>".replace("HOST", location.hostname));
    </script>
<?php
    endif;
?>
```

あとは通常のフロントエンド開発時と同様に、watchでファイル変更を検知したタイミングでbrowserSync.reloadを実行するようなタスクを記述すればok
さくらのレンタルサーバーライトにメールフォームを設置する

# 標準でPOSTMAILが提供されている

コントロールパネルで操作をすればメールフォームを簡単にインストールできます。
しかし、せっかくなのでRubyで作ることにしました。

# フォームを作る

まず、HTMLでフォームを作ります。

```html:mailform.html
<html>
<head>
  <title>お問い合わせ</title>
</head>
<body>

<form method="post" action="mailform.cgi">

  <div>お名前</div>
  <div><input type="text" name="name" /></div>

  <div>メールアドレス</div>
  <div><input type="text" name="from" /></div>

  <div>件名</div>
  <div><input type="text" name="subject" /></div>

  <div>内容</div>
  <div><textarea name="body"></textarea></div>

  <div><input type="submit" name="submit" value="送信" /></div>

</form>
</body>
</html>
```

# フォームの内容を受け取り、メールを送信するCGIを作る

フォーム送信されたフォームの内容を受け取り、メール送信するCGIを作ります。

```ruby:mailform.cgi
#!/usr/local/bin/ruby

require "cgi"
require 'net/smtp'
require "nkf"

cgi = CGI.new

if ENV['HTTP_REFERER'] == "[メールフォームのURL]" then
  
  mFrom = cgi["from"].gsub(/(\r\n|\r|\n)/, '')
  mSubject = cgi["subject"].gsub(/(\r\n|\r|\n)/, '')
  mName = cgi["name"]
  mBody = cgi["body"]

  subject = "[問合せ] " + mSubject
  subject = NKF.nkf("-JM", NKF.nkf("-jW", subject))
  
  body = <<EOF
[#{mName}]
#{mBody}

#{ENV['HTTP_REFERER']}
EOF
  
  body = <<EOF
From: #{mFrom}
To: [送り先のメールアドレス]
Subject: #{subject}
Date: #{Time::now.strftime("%a, %d %b %Y %X %z")}
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-2022-JP
Content-Transfer-Encoding: 7bit

#{NKF.nkf("-Wjm0", body)}
EOF

  Net::SMTP.start('[メールサーバーのアドレス]', 25) {|smtp|
    smtp.send_mail(
      body,
      mFrom,
      '[送り先のメールアドレス]'
    )
  }

end

print <<EOF
Location: [送信後に戻るURL]

EOF
```

追記
メールヘッダーインジェクション対策として、fromとsubjectの文字列から改行文字を削除するコードを追加しました。
また、メールフォームのURLをチェックするコードを追加し、本文にも送信元URLを表示するよう変更しました。

追記(2020/09/07)
文字化けするのを修正しました。

# アップロードする

上記のファイルをアップロードする。
アップロード後、mailform.cgiのパーミッションを「755」に設定する。

# テストする

メールフォームに必要事項を入力して送信してみる。
うまくメールを送信できれば完成。

...できなかったら、コントロールパネルにあるアクセスログの設定から、エラーログを表示させ、エラー内容を確認して対応する。
【メモ】【OSX】peco/fzf でブランチ切替

```git-branch
git branch -a \
  | perl -ne'm|[^/\* ]+$|;next if$_{$&};$_{$&}=1;next if m,^\*|remotes/.+/HEAD,;$s="\e[0m<S>";s|.*/([^/]+)/|\e[31m$1$s|; s|^ +([^/]+)$|\e[34mlocal$s$1|;print' \
  | column -ts'<S>' \
  | fzf --ansi \
  | xargs git checkout
```
FuelPHP Request_Curlでファイルアップロードをする

## はじめに
FuelPHP標準のRequest_Curlでファイルアップロードをする機会があったのでそのサンプルになります。他でやればいいのですが、標準使いたかったので調べました。
Curlの場合＠を使用すればファイルアップロードになるはずなのですができなかったので微妙にはまりました。

環境
FuelPHP 1.7
PHP 5.6.18

## 概要
1. ソース作成
2. 実行


## 詳細
----

#### 1. ソース作成
ソースを作成します。

```php
namespace Fuel\Tasks;

class UploadTest {

	public function run() {
		$params = array(
			'post_param1'	=> 'データ１'
		,	'fileupload'	=> \CURLFile(dirname(__FILE__)."/upload.csv");
		);
		$postparam 	= array(
			'form-data'		=> $params
		);

		$curl		= \Request::forge($url, 'curl');
		$curl->set_method('post');
		$curl->set_params($postparam);
		$curl->set_option(CURLOPT_RETURNTRANSFER,true); 
		$curl->set_option(CURLOPT_BINARYTRANSFER,true);
		$curl->set_header('Content-Type','multipart/form-data');
		$execResult	= $curl->execute();
		$response	= $execResult->response();
		$result 	= $response->body;
		print_r($result);
	}
}
```

#### 2. ソース作成
実行します。

```shell-session
$oil refine UploadTest
```

## あとがき
set_optionでCURLOPT_RETURNTRANSFERはソースを見るとCURLOPT_つけている感じなので文字列で指定する場合はRETURNTRANSFERでも良いかもしれません。

```php:curl.php
：
	public function set_options(array $options)
	{
		foreach ($options as $key => $val)
		{
			if (is_string($key) && ! is_numeric($key))
			{
				$key = constant('CURLOPT_' . strtoupper($key));
			}

			$this->options[$key] = $val;
		}

		return $this;
	}
```

## その他
参考
[PHPでcURLのクソ仕様 "@" を回避する](http://qiita.com/mpyw/items/c2d2f9cf67072e926721)
CircleCI上のWebアプリをローカルブラウザで表示する方法


CircleCI上でWebアプリのテストを実行している時に、どうしてもローカルのブラウザで操作したい場合があると思います。そんなときには以下の設定でブラウザ操作が可能になります。

# 設定
CircleCIのプロジェクトを`Debug via SSH`でビルドしたときのSSHコマンドに、オプションを追加するだけで簡単に実現出来ます。

```bash:例
# -Lオプションを追加する
ssh -p mmm ubuntu@nn.nn.nn.nn -L 3000:localhost:8080
```

上の例だと、CircleCI上の`8080`ポートアプリを、`localhost:3000`経由でブラウザアクセス出来ます。

# 参考
https://circleci.com/docs/browser-debugging/
OnsenUIで画面遷移時にカクつくのを減らしたい

# 記事の対象者
- OnsenUIを使っている人
- 画面遷移時に$httpとかでロードさせている人

# 問題
nav.pushPage()で画面遷移させるとアニメーションが発生するが、次の画面でHTTP読み込み処理とかが入っていると画面がカクつく。Android端末では顕著だ。

# 解決策
アニメーション終了後に読み込み処理を実行する。

# 方法
遷移後の画面のJS内のons.readyにpostpushイベントを拾う処理を追加する。

```js
// ページ読み込み時
ons.ready(function() {
    $timeout(function() {
        // アニメーションが終わってから
        nav.once('postpush', function() {
            // 読み込む
            loadSomething();
        });
    });
});
```

当たり前すぎて他に書くことがない。困った。

# 結論
postpushイベント重要。
$http自体は非同期で動くので、本来は必要ないかもしれない。

使用したのはOnsenUI 2 Beta.8だが、iPhoneで動かすと特に工夫しなくてもサクサク動く。
流石にここら辺はWebViewの性能だったり、OnsenUI 2自体のチューニングの問題だったりするのだろう。
SwiftでGaugeKitに触ってみた

Swiftでやろうかd3.js等でやろうかなど、選択肢がいろいろありそうですが、お試しで、ということで下記を試してみました。

* https://github.com/skywinder/GaugeKit

### CocoaPodsでインストール

READMEを見ながら、ライブラリを追加します

が、ここでエラーが発生しました。
暫定的な対応を入れました。以下に記載しています。

* https://github.com/skywinder/GaugeKit/issues/33

### UIViewの配置

`UIView`をMain.storyboardで配置します。

その後、下記の図にあるように、Custome Classを設定します。

![スクリーンショット 2016-04-06 10.30.31.png](https://qiita-image-store.s3.amazonaws.com/0/49547/5f3a9207-4628-ca00-40aa-243783a59ffe.png)

### IBOutletで、UIViewに紐づけを実施

UIViewにマウスオーバして`control`ボタンを押しながら、ViewControllerにコネクトします。

```swift
    @IBOutlet weak var gauge_in: Gauge!
    @IBOutlet weak var gauge_mid: Gauge!
    @IBOutlet weak var gauge_out: Gauge!
```

### IBOutlet変数にひもづくIBActionを実装

UISliderをMain.storyboardに配置して、マウスオーバして`control`ボタンを押しながら、ViewControllerにコネクトします。

```swift    
    @IBAction func changeRate(sender: UISlider) {
        gauge_in.rate = CGFloat(sender.value * 4)
        gauge_mid.rate = CGFloat(sender.value * 8)
        gauge_out.rate = CGFloat(sender.value * 12)
    }
```

### 実行してみる

![スクリーンショット 2016-04-06 10.47.11.png](https://qiita-image-store.s3.amazonaws.com/0/49547/3102b289-ae3d-e2d9-1e50-9aaf73553452.png)　　　　![スクリーンショット 2016-04-06 10.47.22.png](https://qiita-image-store.s3.amazonaws.com/0/49547/2c9dcb43-acbf-4fb0-4929-17e53fdc75c3.png)

いい感じですね。

---

ライブラリの実装方法についてもキャッチアップして自分でもこういうUIを作ってみたいですね＾＾

本日は以上となります。
OnsenUI 2 Beta.8からons-splitterの仕様が変更されたらしい

# 記事の対象者
- OnsenUI 2 Beta.8以降を使っている人
- ons-splitterとons-splitter-sideでスライドメニューを組んでいる人

# 問題
Beta.8にしたらons-splitterのサンプルが一部動かない。

具体的には、画面スワイプでメニューを表示させるのは可能だが、ツールバー上のメニューボタンを押して表示させる事ができない。

というかそもそもsplitter.toggleLeft()なんてメソッドが存在しない。

# 解決策
ons-splitter-sideにvarを仕込んでtoggle()を呼ぶ。

# 方法
基本はこれ。
公式のドキュメントには書かれていないが、ons-splitter-sideには「var」属性が付与できる。

```html
<ons-splitter>
    <ons-splitter-side var="side" page="menu.html" side="left" collapse="portrait" swipeable swipe-target-width="50px" width="200px"></ons-splitter-side>
    <ons-splitter-content page="page.html"></ons-splitter-content>
</ons-splitter>
```

そして、toggle()を呼ぶ。こちらは以前からドキュメントに書かれてある。

```html
<ons-toolbar>
    <div class="left">
        <ons-toolbar-button ng-click="side.toggle()">
            <ons-icon icon="ion-navicon" style="font-size: 32px; width: 1em;"></ons-icon>
        </ons-toolbar-button>
    </div>
    <div class="center">タイトル</div>
</ons-toolbar>
```

# 結論
Beta.8以降でスプリッタを操作する場合はons-splitter-sideにvarを設定して動かす。

OnsenUI 2は現在ベータ版なので、公式のドキュメントを鵜呑みにせずソースコード(onsenui.js)を確認しながら実装しよう。
画像を横幅ぴったりで上揃えに配置する方法

UIImageViewを使ってこの配置をググっても全然出てこなかったので紹介します。

## 設定した画像の縦横比に自然にフィットするUIImageViewを実装する

まず、UIImageViewを継承して簡単に拡張したStretchImageViewを作ります。StretchImageViewはAutoLayoutで特に指定がない場合に、自然に見える縦横比・高さに勝手になってくれるImageViewです。

```swift
class StretchImageView: UIImageView {
    override func sizeThatFits(size: CGSize) -> CGSize {
        guard let image = self.image else {
            return super.sizeThatFits(size)
        }

        let newHeight = size.width * (image.size.height / image.size.width)
        return CGSizeMake(size.width, newHeight)
    }

    override func intrinsicContentSize() -> CGSize {
        return sizeThatFits(bounds.size)
    }
}
```

このように、`sizeThatFits`と`intrinsicContentSize`の出力に設定された画像のアスペクト比を反映してあげるだけで実現できます。

## 上部のみの表示

あとは、用意したStretchImageViewの上部のみが表示されるように配置します。表示したい領域にUIViewを配置し、その中にStretchImageViewを配置します。
配置したStretchImageViewには以下のようなconstraintを貼ります。

- superview.top = view.top
- superview.left = view.left
- superview.right = view.right
- superview.bottom <= view.bottom

Bottomは明確には指定していないけれども、StretchImageViewが勝手に高さを決めてくれます。

## 様子

ImageViewのClassとして`StretchImageView`を設定しましょう。
![スクリーンショット 2016-04-06 10.16.35.png](https://qiita-image-store.s3.amazonaws.com/0/12413/fdd78736-90a6-7edb-bbf3-2c0c0bfcd2a7.png "スクリーンショット 2016-04-06 10.16.35.png")

Constraintはこんな感じ
![スクリーンショット 2016-04-06 10.15.24.png](https://qiita-image-store.s3.amazonaws.com/0/12413/1fc6151f-38ef-b219-17da-d028faeba2fc.png "スクリーンショット 2016-04-06 10.15.24.png")

実行の様子
![スクリーンショット 2016-04-06 10.14.15.png](https://qiita-image-store.s3.amazonaws.com/0/12413/a6c96316-a23e-315a-cd8a-f871d9bc54ba.png "スクリーンショット 2016-04-06 10.14.15.png")
git grepでディレクトリを限定して検索

該当するファイルが多すぎて見づらくなるのを回避しましょう。

## 特定のディレクトリ内だけで検索する

```git grep -l '検索語句' -- "PATH/"```

とするだけで範囲を絞りこむことができます。

![](https://qiita-image-store.s3.amazonaws.com/0/8405/1d6d3e33-1f35-5672-20f5-0284b2e5a0af.png)

上記は「code」という文字列をassetsというディレクトリ内だけで検索しています。

これでちょっとはラクになるかな？
１週間に１冊の技術本を読む

###前提など
新しい部署に異動した時、新入社員が技術本を読もうとした時

###結論に至る過程
会社の先輩と「技術向上するには」という会話をしたとき、
何かしらのOutputすること。
という結論になった。

情報（技術・知識）を
Input（講習を受ける・本を読むなど）しても、
Output（実際に経験してみる・内容を議論する・本を書く）がないと身に付かないということ。
本を読んで、英会話はできないと思うし、
本を読んで、泳げるようにはならないと思う。

###本を読んでQiitaに投稿しよう
なんでもいいから１週間に１冊読んで、
感想、要約、やりたくなったことを投稿してみようということをしてみる。

###Qiitaに初めて投稿する勇気とフォロー
私も初めての投稿です。
初めて掲示板に書き込みしたときのことを思い出します。
思い出して欲しいです。激しく緊張してます。
まわりからフォローがあると安心します。
内容はともかく、「お、そういえば投稿してたね。」って。
それだけで、新人も部署異動した人もモチベーションが上がります。
次の投稿の意欲が出てきます。
DBaaS環境でバックアップ＆リストア（Compose.io＠BluemixのPostgreSQL編）

先日データロードをしたので↓、今度はそのデータをバックアップ＆リストア。
http://qiita.com/azzeten/items/126c4730b6f8d15ae039

## バックアップは自動で取得する仕組みが組み込まれています。
Composeでは、以下のポリシーのもとに自動でフルバックアップが取られています。
・日次（7世代分保持）、週次（４世代）、月次（3世代）
・手動バックアップOK、1週間に10個までキープ。
バックアップを取ることに対して、追加料金は取られないっぽいです。そもそもfree trialですが。AWSのRDS？とかを見ると、バックアップ領域に対しても課金されるとのことだったので一応書いときます。

## リストアは数クリックで可能です。
・リストアしたいバックアップを選んで、何回かクリックするとできました。
・PITR（ポイント・イン・タイム・リカバリ）は無いようにみえます。

## イメージ図的にはこんなかんじです。
リストアするときは、既存の環境に上書き・・・ではなくて、新しく環境がプロビジョニングされて、そこにリストアされます。
障害のときもそうですが、たとえば**「1ヶ月前のテストデータでもう一回テストまわしたい、けどデータが当時から変わってる・・」なんてときも、このcomposeのリストアであれば、新規で環境構築されるので、そこを新しいテスト環境として使うみたいなことができる**ってことですかね。
![backup_about.png](https://qiita-image-store.s3.amazonaws.com/0/119378/738a9640-2354-7151-668b-831dd48e1a31.png)

## やってみた
・左のほうの「Backup」をクリックすると、どの時点のバックアップが取られているかリストされるので、どの時点のものをリストアしたいのか選んで、クリック。
・新しい環境の名前と、どの環境（AWSかSoftLayer）のデータセンターが良いかを選択して「Create Deployment」をクリック
![restore.png](https://qiita-image-store.s3.amazonaws.com/0/119378/9ad84d32-f5f7-ef83-24cd-449c35972782.png)

##1.4GBのデータは、何秒でバックアップ＆リストア？
・手動バックアップをやってみたところ、バックアップは1分31秒
・リストアをやってみたところ、5分30秒で完了　　　　　　　　　　　　でした。

##まとめ：普通に使えそうですね
ですね。
jekyllで構築したサイト、本番へアップしたらcssが適用されない場合に試しておきたいbaseurlの便利な変更の仕方。

jekyllでサイトを構築し、buildで生成された_site以下のファイルを本番環境にアップしたらCSSなどが適用されなかった…。というアナタ。

_config.ymlにて、baseurlを指定しているが、

* 本番環境では"http://yourdomain.com"
* 開発環境では"/"

と異っていて、いちいち_config.ymlを書き換えないといけないのは面倒ですよね。

## jekyll serve --baseurl ""
_config.ymlには
```baseurl  http://yourdomain.com```
と書いておき、ローカルでの起動時にはoptionをつけると便利です。

## jekyll build --config FILE1[,FILE2,...]
build時は上記のようなoptionは使えないので、_config.ymlを本番環境用、開発環境用とふたつ用意しておき、build時に上書きする。

開発環境用の設定ファイル_config-dev.yamlを作成し、本番環境と異る箇所のみ記載しておきましょう。

![](https://qiita-image-store.s3.amazonaws.com/0/8405/000f48f3-4811-8b15-d656-a60f9cc6df7f.png)
左が本番、右が開発環境

あとは```jekyll build --config _config.yml, _config-dev.yml]```と実行すれば該当箇所のみ_config-dev.ymlの内容が適用されます。
CocoaPodsの.podspecファイルでOther Swift Flagsを指定する方法


## 動作を確認した環境

|環境	|情報			|
|-------|---------------|
|CocoaPods	|0.39.0			|
|Date	|2016/4/6		|

## 使い方

例えば、Debugビルドの時だけ『-D DEBUG』を指定する場合はこんな感じ。.podspecファイルの適当なところに書きます。

```
	s.pod_target_xcconfig = {
		'OTHER_SWIFT_FLAGS[config=Debug]' => '-D DEBUG'
	}
```

そもそも、Xcodeが標準で『-D DEBUG』ぐらい設定してくれても良いと思うんですけどね・・・
Linux screenコマンド使い方

かなり基本的な操作について
screenを使ったことがない人は、たぶん\<ctrl> + \<a>という操作に慣れないと思う。慣れればなんてことはないだろうけど。

3つの目的別に説明。
（１）スクリーンでセッションを保存
（２）スクリーンで画面分割
（３）スクリーンでマウスを使わずにコピー＆ペースト（画面のスクロール）



# （１）スクリーンでセッションを保存
作業している状態を保存する。マシンの電源が切れない限り保持される。
たとえば、普通にログインしてジョブを流していると、いつの間にかsshの接続等が切れてjobが止まってしまうときがある。screenで生成したセッション内で計算を投入し、セッションからデタッチ（一時的に離れる）しておくことで、途中で計算プログラムが止まることがなくなる。

## 新しいセッションを作る

```bash
screen
```

## セッションを一時的に離れる（デタッチ）

```bash
<ctrl> + <a> 

d
```

一旦、コントロールとaを同時に押してから、dを入力する。

## screenの状態を確認する (セッションの一覧表示)

`screen -ls`

## アタッチする

`screen -r`

複数のセッションがある場合は、 `screen -ls` で調べたIDを指定してセッションに戻る。

### セッションに名前を付ける

`screen -S hogehoge`

として新規スクリーンを作ると、`screen -r hogehoge`でアタッチできる。

**小技**
以下のように，IDの先頭が重複しないように名前を付けておくと，先頭の（数）文字を指定するだけでアタッチできるので，管理しやすい。

```
[hnishi@centos ~]$ screen -ls
There are screens on:
        2947.a_bsc      (Detached)
        17657.b_test1   (Detached)
        17897.c_test2   (Detached)
3 Sockets in /var/run/uscreens/S-k007200.

[hnishi@centos ~]$ screen -r b
```

### 既にアタッチされているスクリーンに強制的に入る

`screen -rx ID`

# （２）スクリーンで画面分割
どんなターミナルでもscreenが入っていれば画面分割して作業できる。

## 水平方向に画面を分割

```bash
<ctrl> + <a> 

S
```
コントロールキー+aを同時に押した後で、大文字のSを入力する。

## 分割された画面の移動

```bash
<ctrl> + <a> 

<tab>
```

## 新しいウィンドウを作る

分割された画面にできた、何もないディスプレイに移動して以下を実行する。

```bash
<ctrl> + <a> 

c
```


## 垂直方向に画面を分割

```bash
<ctrl> + <a> 

|
```

## 分割したスクリーンを消して、元に戻す

```bash
<ctrl> + <a> 

X
```


# （３）スクリーンでマウスを使わずにコピー＆ペースト
コマンドライン操作に慣れてくると、マウスを使うことが億劫になってくる。
スクリーンを使えば、キーボードだけでターミナル上の文字列をコピペできる。

## コピーモードに入る（画面のスクロール）

```bash
<ctrl> + <a> 

[
```

コピーモードに入ると、カーソルが矢印キーで自由に動かせるようになる。
PageUpとPageDownキーも画面を大きく動くときに利用できる。

コピーしたい始点でSpaceキーを押して、終点でもう一度SpaceキーもしくはEnterで、バッファーに一時保存できる。

なお、コピーモードではスクロールが自由。通常のスクリーンのセッションではマウスのホイールキーを使って端末の出力をさかのぼって見ることができないが、コピーモードを使って画面をスクロールするという使い方もできる。

## ペースト

```bash
<ctrl> + <a> 

]
```

スクリーンを起動していれば、どんな状態のときもコピーモードに移行とペーストが利用できる。


# 参考
ほかにもいろいろなscreenコマンドがある。
http://aperiodic.net/screen/quick_reference
RStudio で Fink 版の R を使う方法

~~OSX 11.10 までは Fink で RStudio (rstudio-desktop と rstudio-server) を提供していましたが、ビルドの設定が複雑なために提供を中止しています。~~

RStudio は、Fink でもインストール可能です (2016/6/15 修正)。

```
$ fink list rstudio
Information about 9845 packages read in 4 seconds.
     cran-rstudioapi  0.5-1        Safely access the RStudio API
     cran-rstudioapi  0.5-1        Safely access the RStudio API
 i   cran-rstudioapi  0.5-1        Safely access the RStudio API
 i   rstudio-desktop  0.99.902-1   IDE for R
     rstudio-server   0.99.902-1   IDE for R
```

RStudio 本家からダウンロードした RStudio は、Fink でインストールした R を認識しません。

原因は、ソース中にハードコードで 

- /usr/bin/R
- /usr/local/bin/R
- /opt/local/bin/R

あるいは、

`*pHomePath = FilePath("/Library/Frameworks/R.framework/Resources");`

といった指定があるためです。

ハードコードなので、Preferences などで変更することはできません。

Fink でインストールした R を認識させるために、シンボリックリンクを張りましょう。

ターミナルを開き、

`$ sudo ln -s /sw/bin/R-3.5 /usr/local/bin/`

`$ sudo ln -s /sw/Library/Frameworks/R.framework /Library/Frameworks/`

と入力するだけです。

Fink 版の R は、パッケージも fink からインストールすることを推奨します。Fink の R パッケージは、必要なライブラリにリンクしているかを確認しています。実際、 rgdal などは RStudio からはビルドに失敗します。

ターミナルで

`$ fink list cran`

として、Fink で何がインストールできるか確認してみてください。

なお、install.packages でインストールしたい場合は、Fink で r-base35-dev をインストールする必要があります。

また、RStudio で

`Sys.setenv(PATH="/sw/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin")`

とすると、rgdal はインストールできます。ただし、毎回入力する必要があります。

もし、毎回入力することが面倒だと感じるのであれば、ターミナルから、

```
sudo mv /Applications/RStudio.app/Contents/MacOS/RStudio /Applications/RStudio.app/Contents/MacOS/RStudio.exe
sudo echo '#!/bin/sh' >/Applications/RStudio.app/Contents/MacOS/RStudio
sudo echo "export PATH=/sw/bin:$PATH" >>/Applications/RStudio.app/Contents/MacOS/RStudio
sudo echo ". /sw/bin/init.sh && /Applications/RStudio.app/Contents/MacOS/RStudio.exe" >>/Applications/RStudio.app/Contents/MacOS/RStudio
sudo chmod +x /Applications/RStudio.app/Contents/MacOS/RStudio
```

と入力します。これで、毎回 Fink の環境を読み込んで R を起動するようになります。

Fink でインストールした R パッケージは、/sw/lib/R/3.5 に保存され、RStudio でインストールしたパッケージは ~/Library/R/3.5 に保存されるので、消されることはありません。
LinuxでVPN Serverに接続する方法

VPNサーバーに接続するには、通常はクライアントアプリが必要になります。

ただ、ネットワーク接続に関しては、`networkmanager`が有名で、まとめて設定できるようにしておくと便利です。

networkmanagerには、いくつかVPN接続のためのプラグインがありますので、今回は、それを使ってみます。

なお、VPN Serverは公開されている[VPN Gate](http://www.vpngate.net/ja/)を使います。

```bash:
$ sudo pacman -S networkmanager networkmanager-openvpn network-manager-applet
$ sudo systemctl start NetworkManager
$ nm-applet
```

メニューにアイコンが表示されますので、そこから`VPN接続 > VPNを設定 > 追加 > 保存したVPN接続をインポート`します。

OpenVPNの設定ファイルをダウンロードして、そこからCA鍵を抜き出し、`crt`ファイル(CA証明書)を作成します

```bash:
$ cd ~/Downloads
$ cat foo.ovpn | grep '</ca>' -B22 | sed -e 1d -e '$d' > foo.crt
```

タイプはパスワードを選択し、パスワードやユーザーは`vpn`を入力します。CA証明書は先ほど作成したものを選択。

通常はこの手順で接続できますが、接続できない場合は、他のサーバーを試してみてください。上手く接続できないサーバーはいくつかあります。

`L2TP/IPsec`は簡単に接続できるものの、速度が遅いです。

また、`networkmanager`の設定では、インターフェイス(設定)からVPNの自動接続が可能です。
プロダクトマネージャー（PDM）とプロジェクトマネージャー（PM)はやっぱり分離するべき

# 追記（2019/5/13）
※この記事書いたの大分前なので・・・

## この数年で学んだ組織論やPM論を別のブログで書いているのでよかったらそっちも読んでみてほしいです

[OKRに関する『混ぜるな危険』（最近流行りのOKRについて書いた記事）](https://yuta-kobayashi.hatenablog.com/entry/okr-danger)
[テキトウ組織論（個人ブログ）](https://yuta-kobayashi.hatenablog.com/)
[楽しく雑談しながら仕事をしたいので「雑談は役に立つ」という屁理屈をこねてみた（会社のブログに書いた記事）](https://tech.speee.jp/entry/20181218)

# 主張
## プロダクトマネージャー（PDM）とプロジェクトマネージャー（PM)は兼務するべきではなく、分離するべき

PDMはプロダクトの成功に必要不可欠ですが
同じく実はPMも必要不可欠なのではないかと考えています。
PDMを任されたら､まずは__背中を預けられるPMをチーム内に見出すこと__から始めるのが良いと思うのですが、いかがでしょうか。

以下、そう考える論拠と、私の身の回りで起きていた事例を挙げてみます。

# 論拠
1. PDMとPMは__本質が異なり、求められる資質も異なる__
2. 特に事業の初期段階は、PDMは「価値ある、使い勝手の良い、実現可能な製品を見出すこと」に__集中すべき__
3. しかし、特に日本のIT企業では、__PDMとPMが兼務されるケース__が多く見え、失敗が多く見られる

# 論拠の検証
## PDMとPMは本質が異なり、求められる資質も異なる
> Inspired：
> プロダクトマネジメントの役割が､価値のある､使いやすい、実現可能な製品を見つけ出すことにあるのに対して、プロジェクトマネジメントの役割は、製品を市場に送り出すことに尽きるからだ。

Inspiredでもこう語られている通り、二つの役割は__本質的に異なる役割__です。
本質的に異なる二つの役割を同一人物が担おうとするのは、やはり難しいことだと言えると考えています。

> Inspired：
> PDMに求められる資質＝製品に対する熱意　/　顧客との共感力　/　知性　/　仕事に対する倫理観　/　誠実さ　/　自信　/　姿勢
> PMに求められる資質＝緊迫感　/　立案者たること　/　明晰な思考力　/　データ指向　/　決断力　/　判断力　/　姿勢

また、こちらもInspiredで語られている通り、PDMとPMに求められる資質も異なります。
特徴はやはりPDMはその責任の向き先がプロダクトに直結しているので、__プロダクトに向き合う__のですが
PMはそのプロダクトを市場に送り出す手段としてチームの力を活用するので、__チームやメンバーに向き合う__というところだと考えています。

## ※事例
私がかつて在籍したソーシャルゲームの開発現場では、プロデューサー:PDM ディレクター:PM という分担でした。プロデューサーはとにかくユーザーが求めている面白さ、ゲームのグロースに繋がる施策を制約を気にせずに発案します。当然、技術制約、コスト制約などにより全てを実現できるわけではないのですが、そこはディレクターが要件や条件を整理してチームと共に作り上げていきます。チームには、ユーザーの反応をモチベーションにする人、数値グロースをモチベーションにする人、チーム内での自己の貢献をモチベーションにする人など多様なメンバーが存在するので、様々なコミュニケーションでチームを盛り上げつつパフォーマンスを上げるのがディレクターの１つの役割になっていました。

## 特に事業の初期段階は、PDMは「価値ある、使い勝手の良い、実現可能な製品を見出すこと」に集中すべき
事業の初期段階では、__現実問題としてそこまでのコストをかけられない__、という理由でPDMとPMが兼務されるパターンをよく見ます。
しかし、事業の成功確率を上げるためにも特に初期段階こそ、__PDMとPMは分けるべき__だと考えています。
何故なら事業の初期段階というのは正に「価値ある、使い勝手の良い、実現可能な製品を見出すこと」に集中すべき時期であるからです。
そして特に__ソフトウェア・プロダクトの初期開発というのは、プロジェクトマネジメントの難易度も高い__ので、やはり選任のPMが必要だと考えています。

## ※事例
PM的な役割を、エンジニアリーダーが務めるという話もよく聞きます。プロデューサー、エンジニア、デザイナーという最小メンバーで始まったプロジェクトで、エンジニアがPM的な役割を果たし、プロデューサーがPDMタスクに集中できたことで事業がスピーディーにグロースした、という事例も目にしました。事業が拡大してエンジニアチームが増えても、エンジニアリーダーがPM的に立ち回ることでチームは安定し、プロデューサーがPDMタスクに集中することでプロダクトの進むべき方向が明確になっていました。

## しかし、特に日本のIT企業では、PDMとPMが兼務されるケースが多く見え、失敗が多く見られる
すでにそうではない企業もあるとは思いますが､私の周りではかなり多いケースです。
こういったパターンでは､__そもそもPDMとかPMという役割では呼ばれていなく__て
大体「プロデューサー」とか「ディレクター」とかいう名前で呼ばれていて
__実体としてはPDMとPMを兼務している__という例をよく見ます。

## ※事例
新規事業の立ち上げで、PDMとPMをプロデューサーが兼務していた現場がありました。新規事業の開発段階はKPIなどの数値もなく、チームのモチベートの難易度が高く、プロジェクトの方針に疑念を抱えてしまうというような状況に陥りがちです。そうなると進捗管理、詳細要件定義、リスク管理などのPM的タスクが膨れ上がり、結果プロデューサーがPDM的タスクに向き合うことが出来なくなります。やはりそのプロジェクトでもそういった状況が発生していて、プロデューサーはかなり大変そうでした。

いかがでしょうか。やはり

- PDMとPMの兼務にはリスクがある
- 専任のPMは、特にプロダクト開発の事業グロースに効果を発揮する

と言えると考えています。
技術英語 > At the speeds we're talking about, that alloy could depolarize…

@ Star Trek Voyager > THRESHOLD

ワープ10達成を試みる中、船が破壊されてしまうという問題についての議論の中でキムが

> At the speeds we're talking about, that alloy could depolarize…

http://eow.alc.co.jp/search?q=alloy
http://eow.alc.co.jp/search?q=depolarize

船の合金の分極が解消される（偏光解消する）ことにより船体が破壊されるという設定。

Voyagerでよく出てくる containment field とも関係あるのだろうか。

http://eow.alc.co.jp/search?q=containment

物質をある空間内に閉じ込めておく containment field が depolarization によって機能を失い、船体が破壊される、ということロジックなのかもしれない。
Atom Flight Manual（Atom Editorのチュートリアル）をざっと訳してみるテストw

# Atom フライトマニュアル

## [訳注] この文章について

本文章はAtom Flight Manual ( http://flight-manual.atom.io/ ) の日本語抄訳です。
配布条件はCC SA BY で、Atom Flight Manualに準じます。
全てを翻訳するつもりはなくて、最初から、できるところまでを対象にしたいと思っています。
Atom Flight Manual自体はAsciiDocという形式で管理されており、これらの成果物はGitHubで公開されてはいますが日本の皆さんの便宜を図るためその土台である日本語文章翻訳に集中し、まずはMarkDownでフライトマニュアルを提供したいと思います。

この翻訳はきむりん(@kimrin)が暫定的にゲリラ的に訳した文章で、
将来より良い形でAtom Flight Manualに取り込まれることを望んでいます。

かなり意訳が入っていますが、どうぞよろしくお願い致します。

## Chapter1: 始めよう

### なぜAtomなのか

この世にはたくさんのテキストエディターがあるのに、なぜあなたは
`Atom`エディターの使い方を勉強したり使ったりするのに時間を費やさねばならないのでしょう。

`Sublime`や`TextMate`のようなエディターは使い易い使用感を提供しているものの限定された拡張性しかありません。反対にそれと逆の方向で言うと、`Emacs`と`Vim`はものすごい柔軟性を提供しますが、それらのエディターはとてもとっつき易いとは言えず、特殊用途のスクリプト言語でしかカスタマイズできません。

私たちはもっとうまくできる、と考えています。私たちのゴールは妥協を許さないハックしやすさと使いやすさの両立です： 小学生がコーディングについて学ぶ一番最初の日においても（小学生達に）歓迎されるエディタであると同時に、経験溢れるハッカーが開発を行うに際して彼らがぎこちなさを感じないようなツールとしてのエディターを目指します。

`Atom`を使って`Atom`をビルドしていく中で、何が起こったかといえば徐々にエディターが成熟していくに従って、それなしでは生活できない（訳注：`Atom`なしでは開発が成り立たない）という経験です。表面上は`Atom`はあなたが欲しいと期待するモダンなデスクトップのテキストエディターです。しかしボンネットを開けると、ハックを熱望しているシステムがそこにはあります。

### Atomの核

（訳注：Atomエディターの核心部分をAtom（原子）の原子核と引っ掛けている）

web技術はその失敗に触れずに語ることはできないですが、20年に渡る改善においてweb技術は凄まじく柔軟でパワフルなプラットフォームに変容しました。なので私たちが拡張したいと欲するようなテキストエディタを書き始めた時、web技術を採用することは自明な選択でした。
しかしまず最初に不自由な技術的束縛から解放してあげる必要がありました。

### ネイティブweb

Webブラウザはwebページを閲覧することにおいてはグレートですが、コードを書くということはそれ専用のツールを必要とする特殊なアクティビティです。さらに重要なことは、ブラウザはセキュリティ的理由によりローカルの資源に対して極めて制限されたアクセスしかできず、それは私たちにとってテキストエディターがファイルをローカルに保存したりローカルマシン上のサブプロセスを実行できないということを意味します。

この理由のために、私たちは`Atom`を伝統的なWebアプリケーションとして作ることをしませんでした。その代わり、`Atom`はwebブラウザというよりはテキストエディターのためにデザインされた`Chromium`亜種として特化することにしました。全ての`Atom`のウィンドウは原則としてローカルにレンダリングされたwebページなのです。

典型的な`Node.js`アプリケーションのために用意された全てのAPIsは、それぞれのウィンドウのJavaScriptコンテキスト上で走るコードにも解放されているのです。このハイブリッドな構成は独特のクライアントサイド開発環境を提供します。

すなわち全てがローカルにあるので、アセットパイプラインやスクリプトの結合、非同期モジュール定義(AMD)を気にする必要がありません。
もしあなたが何かコードをロードしたいと思った時には、ファイルの先頭で`require`すればいいだけです。`Node`のモジュールシステムはシステム（Atomエディタ)を特定の仕事に特化した小さなたくさんのパッケージに分割することができます。

### JavaScriptとC++の出会い

ネイティブコードとのインタラクションも非常にシンプルです。例えば私たちは「鬼車」正規表現エンジンのラッパーを私たちの`TextMate`文法のサポートのために書きました。ブラウザにおいては、`NaCl`か`Esprima`技術を必要とするかもしれません。`Node`のインテグレーションはそれを簡単にします。

`Node APIs`に加え、私たちはネイティブダイアログ、アプリケーションやメニューアイテムの追加、ウィンドウの大きさ制御などなどの`APIs`も解放しました。

### Webテック：美味しいところ

Atomエディタのためにコードを書くことについてのもう一つの素晴らしい点は`Chromium`の最新バージョンでの動作を保証されるということです。それはブラウザコンパティビリティや`polyfill`などまつわる問題を回避できるということを意味します。私たちは`web`の輝かしい機能を今日明日にでも使うことができるのです。

例えば、ワークスペースとペーンのレイアウトは`flexbox`を使っています。それはスタンダートとして有名になり私たちが（`flexbox`を）使い始めてからたくさんの変更を乗り越えてきましたが、動きさえすればそれは関係ないのです。

業界全体が`web`テクノロジーを推進するにつれて、私たちは`Atom`を肥沃な大地に作り上げていることを確信するのです。ネイティブUIテクノロジーは流行り廃りもありますが、近年`web`はより優秀でどこにでも見られる標準になりつつあります。私たちはそのツールボックスを深く探求できることにワクワクします。

### オープンソースのテキストエディター

私たちは`Atom`を`GitHub`の最優先使命を完全に補足するものとして見ています。その使命というのは、共に働くことにより良いソフトウェアを築きあげる、というものです。

`Atom`は長期の投資対象であると同時に、`GitHub`はその開発のサポートを専門のチームを充てて続けていくでしょう。しかし私たちは同時に私たちの力だけで`Atom`を作り上げられないことも知っています。`Emacs`と`Vim`が過去30年間で証明しているように、もしテキストエディタのまわりに健全で長続きするコミュニティを形成したいのならば、それはオープンソースプロジェクトであるべきです。

`Atom`エディターの全てがフリーでオープンソースであり、https://github.com/atom に公開されています。
AWS KMSで暗号化した認証情報をAWS Lambda実行時に復号化する(Node.jsでのkms.decrypt使用例)

はじめに
---

Node.jsでAWS Lambdaファンクションを作成した時、AWS Key Management Service(KMS)で暗号化した文字列をkms.decryptにより復号化する例です。

概要
---

AWS Lambdaファンクション作成時、サーバ接続用パスワード、Slackをはじめとする外部サービス連携用のトークン文字列といった認証情報やクレデンシャルをプログラム内に書いておきたい事があるかと思います。

時には、Lambdaファンクションに、パスワードやトークン文字列を平文のまま書くのではなく、パスワードやトークン文字列を暗号化して書いておきたい事があるかもしれません。

このページでは、AWS KMSにより暗号化したトークン文字列をLambdaファンクション(Node.js)に記述する事で、Lambdaファンクション実行時に暗号化したトークン文字列を復号化する例について記載します。

参考サイト
---

KMSによるパスワードやトークン文字列の暗号化手順はクラスメソッド様の記事を参考にさせて頂きました。
http://dev.classmethod.jp/cloud/decrypt-sensitive-data-with-kms-on-lambda-invocation/
KMSで認証情報を暗号化しLambda実行時に復号化する

LambdaファンクションでKMSにより暗号化した文字列を復号化するサンプルコード
---

Lambdaファンクション作成にあたり、まずはaws kms encryptコマンドで「example_password」というトークン文字列を暗号化するとします。

後述のLambdaファンクションサンプルコード中の「kmsEncyptedToken」には、aws kms encryptコマンドにより「example_password」を暗号化した文字列(CiC** ～ **I=)をセットします。

Lambdaファンクションは
　ランタイムは「Node.js」
　Handlerは「index.handler」
　Roleは「lambda_basic_execution」
　Advanced settingsは「No VPC」
を選択して作成します。

Lambda(node.js)でKMSにより暗号化した文字列を復号化するサンプルコードは以下になります。

```js:index.handler
var AWS = require('aws-sdk');

exports.handler = function(event, context){
    var token;
    var kmsEncyptedToken = "CiC**********************************************************************************************I=";
    
    var encryptedBuf = new Buffer(kmsEncyptedToken, 'base64');
    var cipherText = {CiphertextBlob: encryptedBuf};

    var kms = new AWS.KMS({ region: 'ap-northeast-1' });
    kms.decrypt(cipherText, function (err, data) {
        if (err) {
            console.log("token string decrypt error: " + err);
            context.fail(err);
        } else {
            token = data.Plaintext.toString('ascii');
            console.log('token string = ' + token);
        }
    });
};
```

Lambdaファンクションを実行し、「Log output」に「example_password」と文字列が表示されていれば、KMSで暗号化したトークン文字列の復号化は正常です。

```
START RequestId: 28f3900b-fb59-11e5-8a6a-3f80f8c61572 Version: $LATEST
2016-04-05T18:06:47.427Z	28f3900b-fb59-11e5-8a6a-3f80f8c61572	token string = example_password
END RequestId: 28f3900b-fb59-11e5-8a6a-3f80f8c61572
REPORT RequestId: 28f3900b-fb59-11e5-8a6a-3f80f8c61572	Duration: 853.67 ms	Billed Duration: 900 ms 	Memory Size: 128 MB	Max Memory Used: 19 MB	
```
[slack] hubot に gyazo の image を表示させる

# hubot をイジイジしてみよう

`hubot` は言わずと知れた、github 社謹製の bot ツールです。
貴方の slack ライフをより楽しくしてくれるストレスフルに・・・そんな tips を紹介していきます。

# 前提

- slack を使っている
- `hubot` が動いている（heroku可）

# やりたいこと

`gyazo` という便利なツールを使った事があると思います。
画面キャプチャをURL化して皆で共有できるアレです。
こちらの gyazo ですが、slack 上で使っていると最初は快く画像をTLに展開してくれるのですが、途中から「上限に達した」とのご案内と共にTLには表示されずURLをクリックする必要があります。

それは非常にストレス・・・！であれば、 hubot に画像を引っ張ってきてもらいましょう。

# やること

非常に簡単です。
以下のコードを `example.coffee` にでも貼り付けてください。

```coffeescript
robot.hear /(https:\/\/gyazo\.com\/\S+)/i, (msg) ->                                                                                                                                                                                
  url = msg.match[1] + ".png"                                                                                                                                                                                                      
  robot.emit 'slack.attachment',                                                                                                                                                                                                   
    channel: msg.envelope.message.room                                                                                                                                                                                             
    content:                                                                                                                                                                                                                       
      author_name: "Gyazo"                                                                                                                                                                                                         
      image_url: url 
```

`gyazo` の URL を監視して、見つかった場合は slack API の `attachment` 機能を使って画像URLを表示します。
コピペしたら、commit して bot をデプロイしましょう。

正常に動く場合は、こんな感じ↓に画像URLを展開してくれます。
<img width="488" alt="スクリーンショット 2016-04-06 1.52.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/8963/ba1f02f0-97eb-b51a-1822-00adb2466c6d.png">

`attachment` は地味に便利なので使いこなせると slack ライフに潤いがもたらされます。
以上。
git lfs pull を毎回しなきゃいけなくなった時にやったこと

# はじめに

Github で Git LFS が使えるようになったので、iOS で使ってる SDK を、LFS で管理してたら、
`git reset` した後とかに、 `git lfs pull` しないと build が失敗が失敗する問題が発生。

更に、`git lfs pull` すると必ず index に入っちゃうので、セットで `git reset` までしなきゃいけない状態で、
かなりめんどくさくて調べて解決した時のメモ。

ちなみに、ローカルのリポジトリを削除して、再度 clone だと解決できなかった。

# 解決方法
`git lfs install` を実行して、`git reset` する

```
$ git lfs install
Updated pre-push hook.
Git LFS initialized.
$ git reset
$ git lfs pull
Git LFS: (0 of 7 files) 0 B / 124.40 MB
Git LFS: (0 of 7 files) 0 B / 124.40 MB
$ git status
On branch develop
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
```

ただ、git-lfs のバージョンが古いと、`unknown command` になるので、バージョンアップが必要

### brew でのアップデート
```shell-session
$ git lfs install
Error: unknown command "install" for "git-lfs"
Run 'git-lfs --help' for usage.
$ git lfs version
git-lfs/1.0.2 (GitHub; darwin amd64; go 1.5.1)
$ brew update git-lfs
Error: This command updates brew itself, and does not take formula names.
Use 'brew upgrade <formula>'.
$ brew upgrade git-lfs
==> Upgrading 1 outdated package, with result:
git-lfs 1.1.2
==> Upgrading git-lfs
==> Downloading https://homebrew.bintray.com/bottles/git-lfs-1.1.2.yosemite.bottle.tar.gz
######################################################################## 100.0%
==> Pouring git-lfs-1.1.2.yosemite.bottle.tar.gz
🍺  /usr/local/Cellar/git-lfs/1.1.2: 5 files, 11.6M
$ git lfs version
git-lfs/1.1.2 (GitHub; darwin amd64; go 1.6)
```


参考URL： [stackoverflow](http://stackoverflow.com/questions/34685689/git-lfs-large-file-storage-says-lfs-managed-files-are-modified-after-a-git-lfs)
TypeScriptで型の異なるメソッドをオーバーライドする

# これはなに

 * TypeScriptでは親クラスのメソッドを継承する際、オーバーライド（同名メソッドの上書き）ができる
 * ただし、引数や返り値の型の異なる場合はオーバーライドできない
 * オーバーロード宣言と組み合わせる事で実現できる

# 前提：引数や返り値の型の異なるメソッドはオーバーライドできない

TypeScriptは（、元のES2015の仕様に合わせ）特に何の宣言も不要でメソッドのオーバーライドができる。ただしJSと異なるのは引数や返り値の型のチェックが入るため、一致しないとオーバーライドできない[^1][^2]。

```ts:引数の型が異なるのでオーバーライドできない
class Base{
	method(arg:string){}
}

//error! Type of property 'method' are incompatible.
class ChildA extends Base{
	method(arg:number){}
}
```

# 対処法：オーバーロード宣言と組み合わせる

TypeScriptには同名メソッド・関数で引数・返り値の型や数などが異なる時用に、[オーバーロード](http://www.typescriptlang.org/docs/handbook/functions.html#overloads)がある。

これをつかい、子クラス側で①継承元と同じ型のメソッドと②新しいメソッドをオーバーロードで宣言すればエラーにならず、継承できる。

```ts

class Base{
	method(arg:string){}
}

//ok
class ChildB extends Base{
	method(arg:number):void;	//②
	method(arg:string):void;	//①
	method(arg:any){
		if(typeof arg === "string"){
			super.method(arg);
		}else if(typeof arg === "number"){
			//...
		}
	}
}

```

## 親クラスと同じ型を拒否

親クラスと同じ型の引数だった場合を拒否するには、TSの型システムではできない。やるなら、以下のようにランタイムにチェックする。

```ts
class ChildB extends Base{
	method(arg:number):void;
	method(arg:string):void;
	method(arg:any){
		if(typeof arg === "string"){
			throw TypeError(`Invalid type of argument. typeof arg: ${typeof arg}`);
		}else if(typeof arg === "number"){
			//...
		}
	}
}

```

# 参考：型定義

既存ライブラリ用に型定義ファイルを書くなら以下のようになる。

```ts:*.d.ts
declare class Base{
	method(arg:string):void;
}

//ok
declare class ChildB extends Base{
	method(arg:string):void;
	method(arg:number):void;
}
```


[^1]: [C++](http://qiita.com/holly_nano/items/59fd93fe3887c1a6f752)/[Java](http://qiita.com/shyamahira/items/512ef48ee3af0ae4ecb5)/C#も同様。

[^2]: なお、基底クラスのメソッドを`private`で宣言していてもダメ。
新しいLinuxサーバにログイン時確認すること

サーバを管理するような作業をしていると、日々いろいろなサーバにリモートログインします。最近、一緒に作業する人から「ログイン後入力するコマンドで、その人が育ってきた環境がわかります」と言っていました。その人が言うには、「私(kaikusakari)は管理がずさんなたくさんのサーバ群を、管理している環境で育っている」とのことです笑。その判断基準はよく分からないですが、複数人で作業している時、ログイン後の動きは人によって異なっていて面白いと思っています。

あまり参考にならないかも知れないですが、自身がいつもやることを確認も含めてまとめておきます。

#ログイン後確認すること
（環境：CentOS7）

**ユーザの確認**
ログインしたユーザが意図したものであるか確認する
ついでに利用シェルも確認します

```sh
[Bellatrix@idp ~]$ id
uid=1005(Bellatrix) gid=1005(Bellatrix) groups=1005(Bellatrix)

[Bellatrix@idp ~]$ cat /etc/passwd
Bellatrix:x:1005:1005::/home/Bellatrix:/bin/bash
```

**ホスト名の確認**
プロンプト([Bellatrix@idp ~])は編集可能であるため、コマンドで確認する
centos7での管理ファイル→/etc/hostname

```sh
[Bellatrix@idp ~]$ hostname
hostname
```

**同時接続ユーザ、LAの確認**
シャットダウンなど同時接続ユーザに影響が出る場合は
同時接続しているユーザがいないか確認する

```sh
[Bellatrix@idp ~]$ w
 00:56:59 up 53 days, 21:34,  1 user,  load average: 0.00, 0.01, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
con      pts/0    10.10.10.10      00:45    3.00s  0.05s  0.00s sshd: con
```

**ここまでする？IPの確認**
作業マシンをIPで管理している場合など

```sh
[Bellatrix@idp ~]$ ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
 省略
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 9c:a3:ba:30:cd:14 brd ff:ff:ff:ff:ff:ff
    inet 100.100.100.100/24 brd 153.120.171.255 scope global eth0
       valid_lft forever preferred_lft forever
```

**初めて触る機器なら良くやる文字コード確認**
ターミナルの文字コード設定とセットでやります

```sh
[Bellatrix@idp ~]$ echo $LANG
en_US.UTF-8
```

**ごく稀に変なオプションが付いてたりするエイリアスの確認**
rmに-fが付いていた環境がありました、それ以後-iを必ず付けるようになりました。

```sh
[Bellatrix@idp ~]$ alias
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
```

**wコマンドでLAが大きな数値になってる場合など**
機器の情報をもう少し確認する

```sh
[Bellatrix@idp ~]$ top
→プロセス状況を確認する

[Bellatrix@idp ~]$ df -h
→ディスク容量を確認する

[Bellatrix@idp ~]$ ss -natus
→機器のネットワーク統計情報を確認する
```

以上です。
AzureVMに特定IPアドレスでアクセス制御をかける手順書


Azure上のVirtualMachineに対して、特定のIPアドレスのみからアクセスできるように制御をかける必要があったのでメモ。

### エンドポイントの作成
***
[ポータル]→[VirtualMachine]→[対象のVMを選択]し、[リソースグループ]をクリック。
![SnapCrab_NoName_2016-4-5_17-13-26_No-00.png](https://vxc.qiita.com/files/1b9fb091-fbd2-e4a9-6cfc-56aede556723.png)


リソース一覧の中から、盾アイコン（ネットワークセキュリティグループ）を選択。
![SnapCrab_NoName_2016-4-5_17-14-11_No-00.png](https://vxc.qiita.com/files/aa5debfe-d4cd-e22b-7636-781a73e458de.png)

[受信セキュリティ規則]を選択。
![SnapCrab_NoName_2016-4-5_17-14-35_No-00.png](https://vxc.qiita.com/files/e3817a5c-b158-155e-3d93-35f3807fce03.png)

[追加]アイコンをクリックし、CIDRブロックを選択してアクセス許可するIPアドレスを入力。
宛先ポートも設定し、OKボタンクリック。
![SnapCrab_NoName_2016-4-5_17-15-4_No-00.png](https://vxc.qiita.com/files/0f1b7232-edb8-e4bf-a6e0-8280c62c76ed.png)

これでポータル画面での作業は終了。非常に簡単。


### VirtualMachineのファイアーウォール設定
***
VMにログインし、Windows の [スタート] をクリック。
[コントロール パネル] から[システムとセキュリティ]、[Windows ファイアウォール]、[詳細設定] の順にクリック。


[受信の規則]、[新しい規則] の順にクリックし、[規則の種類] で、[ポート] を選択して [次へ] をクリックします。
![SnapCrab_NoName_2016-4-5_17-24-40_No-00.png](https://vxc.qiita.com/files/4d40318c-d9dc-59f2-c5e0-0e7ae26d323f.png)

[プロトコルとポート] 画面で、[TCP] を選択し、[特定のローカル ポート] を選択してエンドポイントで設定した宛先ポートを入力し、[次へ] をクリックします。
![SnapCrab_mrso-srv01 - vxc-hhfactoryjapanwestcloudappazurecom - リモート デスクトップ接続_2016-4-5_17-24-58_No-00.png](https://vxc.qiita.com/files/c0f25cca-d0d5-6e4d-c113-cbebebd8aa2b.png)


[操作] 画面で、[接続を許可する] を選択し、[次へ] をクリックします。
![SnapCrab_mrso-srv01 - vxc-hhfactoryjapanwestcloudappazurecom - リモート デスクトップ接続_2016-4-5_17-25-29_No-00.png](https://vxc.qiita.com/files/3dc87516-bb95-9b69-4cba-4b5c6da9f7d6.png)


[プロファイル] 画面で、[ドメイン]、[プライベート]、および [パブリック] の各チェック ボックスがオンになっていることを確認し、[次へ] をクリックします。
![SnapCrab_mrso-srv01 - vxc-hhfactoryjapanwestcloudappazurecom - リモート デスクトップ接続_2016-4-5_17-25-37_No-00.png](https://vxc.qiita.com/files/964a466c-497c-e525-3781-b30ee0f4d9bf.png)


[名前] 画面で、適当な名前を入力し、[完了] をクリックします。
![SnapCrab_mrso-srv01 - vxc-hhfactoryjapanwestcloudappazurecom - リモート デスクトップ接続_2016-4-5_17-25-43_No-00.png](https://vxc.qiita.com/files/51ea6415-5266-1bde-3d9f-f0c860b6ae71.png)


これで指定したIPアドレスによるアクセス制御ができました。
入力後に半角数字、ハイフンをチェックする

電話番号に利用可能な文字列の入力のみサポートする入力欄を作りたくてサンプルを作ったのでメモ書き。

```js:main.js
$( function() {
  $('#tel').on("keyup blur", function(){
    if( $(this).val().length > 0 ) {
        if(!$(this).val().match(/^[0-9\-]+$/)){
            alert("入力内容に半角数字、ハイフン以外が含まれています");
            return false;
        }
    } 
  })
} );
```

```html
<html>
<head>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.19/jquery-ui.min.js"></script>
  <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.19/themes/redmond/jquery-ui.css">
  <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.19/i18n/jquery-ui-i18n.min.js"></script>
  <script src="script/main.js"></script>
  <style>
<!--
.ui-autocomplete {
    max-height: 100px;
    overflow-y: auto;
    overflow-x: hidden;
    padding-right: 20px;
}
#jquery-ui-autocomplete label {
    float: left;
    margin-right: 0.5em;
    color: black;
    font-size: 15px;
}
-->
</style>
</head>
<body>
  <div>
    <label> 電話番号:</label>
    <input type="text" id="tel" />
  </div>
</body>
</html>
メモ：シフト演算子でも整数拡張は起こる

Arduinoのサンプルスケッチを見ていたときに、自分自身の「思い込み」にはまったので、メモ。

```
#include <stdio.h>
int main(void)
{
    char a = 1;
    printf("sizeof(a) = %d\n", sizeof(a));
    printf("sizeof(a << 4) = %d\n", sizeof(a << 4));
    return 0;
}
```

を実行すると、

```
% ./a.out
sizeof(a) = 1
sizeof(a << 4) = 4
```
となる。

うっかり、char型に収まる範囲でのビットシフトでは型が変化しないと思い込んでしまったが、整数拡張は起こる。

参考: https://www.jpcert.or.jp/sc-rules/c-int02-c.html

> 整数拡張は通常の算術型変換の一部として、引数式や、単項 +、-、~演算子, シフト演算子のオペランドに対して適用される。
【Swift】for文を逆順で回したいあなたに

## はじめに
独学でプログラミング学び始めて約1年、業務でプログラムを書き始めて2ヶ月、Swift始めて１ヶ月のSwifterです。
タイトルの通りですが、for文を逆から回したい時がたまーにあると思います。でも高速列挙では逆から回せないし、

```swift
for(var i = 10; i > 0; i--)
```
この書き方だと「将来廃止予定ですよ」なんて警告が出て嫌だし・・・という迷えるあなたに贈るメモです

## 対象となる人
・プログラミング/Swift初心者
・for文を警告なく逆から回したい

## 環境
xcode 7.2.1
Swift 2.1.1

## やること
・for文を逆から回す

## for文色々
逆から回す前にfor文の基本をおさらいします。

### 基本形
```swift
var array = ["りんご", "ごりら", "らっぱ", "ぱせり", "りーる"]
for var i = 0; i < 10; i++ {
    print(array[i])
}
```
これは将来廃止の可能性があるようなので、通常、高速列挙型を使います

### 高速列挙１
```swift
var array = ["りんご", "ごりら", "らっぱ", "ぱせり", "りーる"]
for i in 0..<array.count {
    print(array[i])
}
```
基本形と同じ意味ですが、for文の中身が短くなりました。

### 高速列挙２
```swift
var array = ["りんご", "ごりら", "らっぱ", "ぱせり", "りーる"]
for name in array {
   print(name)
}
```
こんな書き方もできますね。出力内容は全て同じです。

また、単純に逆順に出力するなら、上であげたように

```swift
for(var i = 10; i > 0; i--)
```

この書き方でもできますが、廃止の可能性を考えると修正しておく方が無難。

## for文を逆順で回したいのはどんな時か
さて、ここで本題。じゃあ一体どんな時に配列を逆から回したいでしょうか。
僕がぶちあたったのはこれです。
**・for文の途中で配列の要素を削除したい時**

例えば、先ほどのfor文で"ごりら"を削除してみます。

```swift
var array = ["りんご", "ごりら", "らっぱ", "ぱせり", "りーる"]
for index in 0..<array.count {
    if array[index] == "ごりら" {
        array.removeAtIndex(index)
    }
    print(array)
}
```
この文を実行すると「fatal error: Array index out of range」というエラーが。
removeAtIndexで要素を削除すると要素数が変化してしまい、存在しないindexまでアクセスしてしまうためですね。
これをどうすればよいか。逆から回せばよいのです。

### for文を逆から回す
逆順で回すときは、

```swift
for index in (0...10).reverse() {
    print(index)
}
```
こんな感じで書けます。このfor文の出力結果は「10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0」です。

```swift
for index in (0..<10).reverse() {
    print(index)
}
```
こうすると「9, 8, 7, 6, 5, 4, 3, 2, 1, 0」となります。

ようやく本題。これらを応用すると、、、

```swift
for index in (0..<array.count).reverse() {
     if array[index] == "ごりら" {
        array.removeAtIndex(index)
     }
}
print(array)
```
この出力結果は「"りんご", "らっぱ", "ぱせり", "りーる"」となり、ごりらが削除できました。
お疲れ様でした。

### 補足
長々と書いておいてアレですが、配列の操作(今回の場合は削除)は、調べるとどうもfilterという関数を使えばクソ簡単に書けるようです。

```swift
var array = ["りんご", "ごりら", "らっぱ", "ぱせり", "りーる"]
array = array.filter($0 != "ごりら")
print(array)

出力結果：["りんご", "らっぱ", "ぱせり", "りーる"]
```

複数削除したい場合はこんな感じ？

```swift
var array = ["りんご", "ごりら", "らっぱ", "ぱせり", "りーる"]
let removeName  = ["ごりら", "りーる"]
for name in removeName {
    array = array.filter($0 != name)
}
print(array)

出力結果：["りんご", "らっぱ", "ぱせり"]
```
削除というよりは条件に合わないものを再代入している形ですね。
調べればもっと短くなりそうです。
いやはや奥が深い。(この時間はなんだったんだ・・・)

お疲れ様でした。
いつも忘れるTableView下部の余分なSeparator消し

#はじめに
TableView下部の余分なSeparatorの消し方についてです。（Objective-C）
TableViewを使うとき、いつも忘れてしまって参考書やらネットやらを見直すので書き残します。

今回は、余分なSeparator消しということに絞っているため
TableViewの実装に関して詳しくは触れませんのでご了承下さい。

#とりあえずTableViewを作成してみる
Storyboard利用して作成しました。
##Storyboard
<img width="1273" alt="スクリーンショット 2016-03-30 0.40.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/103695/62aeda91-a738-984c-35ee-6b0b8fb8c9c4.png">
Storyboard上では、いつも通り。
TableViewを用意して、更にTableViewCellを乗せて
TableViewCellのReuse Identifierを設定（今回は「Cell」と設定）しただけ。

##Source code
```lang:ViewController.m
#import "ViewController.h"

@interface ViewController () <UITableViewDataSource, UITableViewDelegate>
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (nonatomic) NSArray *data;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationItem.title = @"たいとるううう";
    
    //Cellに表示する文字列
    _data = @[@"hoge", @"poco", @"piyo"];
    
    //Delegate
    _tableView.delegate = self;
    _tableView.dataSource = self;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return _data.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
    }
    
    cell.textLabel.text = _data[indexPath.row];
    return cell;
}

#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // 選択状態の解除
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
}

@end
```

##実行結果
![Screen Shot 2016-03-30 at 0.57.27.png](https://qiita-image-store.s3.amazonaws.com/0/103695/6c8bb80d-ca72-731d-90bd-6b5c9233c47e.png)
Cellは3つだけなのに余分なSeparatorがいっぱい、、
***

#解決策
**たった1行追加するだけで解決できちゃうんです!!**
- (void)viewDidLoad内に次の1行を追加します。
`_tableView.tableFooterView = [UIView new];`

たったこれだけで、解決しちゃうんです！
先ほどのSource codeのviewDidLoadに追加してみると、
##Source code
```lang:ViewController.m
- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationItem.title = @"たいとるううう";
    
    //Cellに表示する文字列
    _data = @[@"hoge", @"poco", @"piyo"];
    
    //Delegate
    _tableView.delegate = self;
    _tableView.dataSource = self;
    
    //下部の余分なセパレータを表示しないために、TableViewのFooterViewを生成
    _tableView.tableFooterView = [UIView new];
}
```
##実行結果
![Screen Shot 2016-04-06 at 0.10.39.png](https://qiita-image-store.s3.amazonaws.com/0/103695/2542d598-1a0d-349d-a846-150a45105987.png)
余分なSeparatorを消すことができました。
***

#最後に
今回は、Objective-CでTableView下部の余分なSeparatorの消し方について書いてみました。
tableFooterViewを生成する方法以外にも、もっと良い方法をご存知という方はご教授願います。