OmniAICreator/Qiita-1.07M huggingface dataset:
指定した子のViewクラスを取得する処理を作成してみた

タグを使用せずに
特定の子のViewを取得する処理を作成してみた

```UIView+getSubView.swift
extension UIView {
    func getSubView(checkClass : AnyClass) -> AnyObject? {    
        //子のViewを取得
        for subView in self.subviews {
            //その子のViewが引数のクラスだったらそのオブジェクトを返す
            if type(of: subView) == checkClass {
                return subView
            } else {
                //違ったら下のViewを再起的にチェックし、見つかったらそのViewを返す
                if let view = subView.getSubView(checkClass : checkClass ) {
                    return view
                }
            }
        }  
        return nil
    }
}
```

使用する時は
`self.view.getSubView(checkClass : UIView.self)`
とするだけ
AWS認定　ソリューション　アーキテクト　アソシエイト　受験メモ

#経緯
1月に55％で不合格。リトライ中。

#作戦
1.公式のガイドに沿って公式ドキュメントを見直す。
2.デプロイ/実装の得点が低かったので重点的に実機操作。


#ASA受験に向けてメモ
##AWS 認定ソリューションアーキテクト – アソシエイト
https://aws.amazon.com/jp/certification/certified-solutions-architect-associate/

##サービス別資料
https://aws.amazon.com/jp/aws-jp-introduction/

##よくある質問
EC2
https://aws.amazon.com/jp/ec2/faqs/
PHP 日付ライブラリ Carbonの日本語化＆言語ファイル差し替え

#概要
日付計算が簡単にできるライブラリの[Carbon](http://carbon.nesbot.com/)。現在日時と比較して「○分前」みたいなことも標準メソッドが用意されており、超簡単。
とはいえ、デフォルトの言語は英語なので、日本語化するための備忘録です。

#環境
PHP 7.1.3
Carbon 1.22.1

#やること
1. 普通に使う（○分前表示）
2. 日本語化
3. 言語ファイルを差し替える（これがメイン）

以下、サンプル

##普通に使う

```php
echo Carbon::now()->subMinutes(12)->diffForHumans();
#12 minutes ago
echo Carbon::now()->subHours(2)->diffForHumans();
#2 hours ago
echo Carbon::now()->addMinutes(12)->diffForHumans();
#12 minutes from now
echo Carbon::now()->addHours(2)->diffForHumans();
#2 hours from now

```

##日本語化
一行追加するだけ。でもスペースが気にくわない。

```php
# この一行を追加するだけ。
Carbon::setLocale('ja');

echo Carbon::now()->subMinutes(12)->diffForHumans();
#12 分 前
echo Carbon::now()->subHours(2)->diffForHumans();
#2 時間 前
echo Carbon::now()->addMinutes(12)->diffForHumans();
#今から 12 分
echo Carbon::now()->addHours(2)->diffForHumans();
#今から 2 時間
```

##言語ファイルを差し替える
情報が見つからず、ソースを見て試行錯誤したorz
もっと良い方法があったら指摘ください。

```php
// 言語リソース差し替え ここから（LaravelならAppServiceProviderとかで行う）
$translator = new \Symfony\Component\Translation\Translator('ja');
$translator->addLoader('array', new \Symfony\Component\Translation\Loader\ArrayLoader());
// 専用の言語ファイルを用意することを推奨（Laravelなら下のようにやる）
// $date_resource = require resource_path(sprintf('lang/%s/date.php', config('app.locale')));
$date_resource = [
    'year'      => ':count年',
    'month'     => ':countヶ月',
    'week'      => ':count週間',
    'day'       => ':count日',
    'hour'      => ':count時間',
    'minute'    => ':count分',
    'second'    => ':count秒',
    'ago'       => ':time前',
    'from_now'  => '今から:time',
    'after'     => ':time後',
    'before'    => ':time前'
];
$translator->addResource('array', $date_resource, 'ja');
Carbon::setTranslator($translator);
// 言語リソース差し替え ここまで

echo Carbon::now()->subMinutes(12)->diffForHumans();
#12分前
echo Carbon::now()->subHours(2)->diffForHumans();
#2時間前
echo Carbon::now()->addMinutes(12)->diffForHumans();
#今から12分
echo Carbon::now()->addHours(2)->diffForHumans();
#今から2時間
```

#補足
未来時間のdiffForHumans()で「今から２時間」って何だ？「２時間後」にした方が良いのか？と思いつつも使う予定はないのでそのままにした。

以上です。
【Android】Expected resource of type string [ResourceType] のエラーの対処法

Generate Signed Apkをしたときにエラーが出たので対処法のメモです。

## 結論

gradleに以下を追記

```
android {
  lintOptions {
    disable "ResourceType"
  }
}
```

## エラー内容

```
Error: Expected resource of type string [ResourceType]
```

## 参考

https://stackoverflow.com/questions/35009832/androidstudio-disable-expected-resource-of-type-string
[Angular] Angular CLIでプロキシを利用する

フロントエンドからバックエンドに対して、同一ホストだがポートが異なる構成で疎通したいケースがある。
たとえば

* フロントエンドが ```localhost:4200/```
* バックエンドが ```localhost:3000/```

といったケースである。
~~Angular では~~ 通常、こうしたケースだと CORS によるエラーが発生してしまうのだが、Angular では Angular CLI でプロキシ設定ファイルを用意することで対応できる。

## この記事を実施した環境

* Windows10 Home 64bit
* node v8.2.1
* npm v4.0.5
* angular/cli v1.2.6
* Angular v4.3.2

## プロキシ設定ファイルの用意(proxy.conf.json)

次の例だとフロントエンドの 「/app」にリクエストがきた場合、バックエンドの「localhost:3000」にフォワードされる設定となる。

```json:proxy.conf.json
{
  "/app": {
    "target": "http://localhost:3000",
    "pathRewrite": {"^/app": ""}
  }
}
```

## package.json の編集
プロキシ設定ファイルを用意したら、それを使用してアプリケーションを起動する設定を package.json に記載する。
具体的には、次の「start」の内容を package.json の「scripts」の要素に記載する。

```json:package.json
{
  "scripts": {
    "start": "ng serve --proxy-config proxy.conf.json"
  }
}
```

## プロキシ設定を反映させてアプリケーションを起動

前項までの設定を終えたら、次のコマンドを実行することでプロキシ設定を反映させた状態でアプリケーションが起動する。

```js
// プロキシ設定を反映させる場合
$ npm run start
```

## プロキシ設定を反映させたくない場合

プロキシ設定を反映させたくない場合、直接 ng serve でアプリケーションを起動させれば良い。

```js
// プロキシ設定を反映させたくない場合
$ ng serve
```

## 参考

* [Proxy To Backend](https://github.com/angular/angular-cli/blob/master/docs/documentation/stories/proxy.md)
* [webpack dev server#proxy](https://github.com/webpack/docs/wiki/webpack-dev-server#proxy)
WordPressで、○ページ目のリンクURLを取得する

自分で、ページネーションリンクを生成するときなどに利用。カテゴリーページやタグページなどで、適切なリンク先を取得できます。

```php
$url = get_pagenum_link(3); // /category/cat1/page/3 などを取得
```

- [get\_pagenum\_link\(\) \| Function \| WordPress Developer Resources](https://developer.wordpress.org/reference/functions/get_pagenum_link/)
chromeデベロッパーツールのCall Stackの表示が便利になった！

# はじめに
chromeはブラウザとしての機能だけでなく、デベロッパーツールにも積極的に機能追加をしています。
先日ver.60に更新され、今回もデベロッパーツールに新たな機能が追加されております。
その中で個人的に一番うれしかった機能をご紹介します。

#chrome ver.59までの場合

下図のソースはファンクション*CCC*→*BBB*→*AAA*の順に呼ぶだけのプログラムですが
*CCC*から*BBB*、*BBB*から*AAA*を呼ぶときには*setTimeout*を使用して、タイムアウト後に呼び出すようになっております。
アプリケーションを開発していく中ではレンダリングを優先させるためやタイミング調整のためこのように*setTimeout*を使用する場合があると思います。

ここで、ファンクション*AAA*をデバッグしたい場合、*AAA*内部でブレイクさせると下図の通りCall Stackは*setTimeout*の
タイムアウト後の処理から始まり、それ以前までたどることができません。
複雑な処理の場合は非常に不便でした。

2017/8/1 訂正
ver.59でもAsyncチェックボックスをonにする事でver.60と同様の事ができるとご指摘を頂きました。
ver.60からはAsyncチェックボックスがなくなり
標準機能になったようです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/171118/e25e595d-4912-1e23-55a2-6f8174a5e772.png)

# chrome ver.60の場合

ver 60からは*setTimeout*の呼出し元まで遡ってCall Stackに表示されるようになりました！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/171118/59a37dda-b36d-391f-cf4f-0a1f1f651a29.png)

# さいごに
chromeのデバッグについては以下の記事にも便利な技を掲載しております。

[chromeでのブレイクポイントのいろいろな設定方法](http://qiita.com/Shinji-Hashimoto/items/e6ab00be4f3dfbc20855)
[chromeでのデバッグ便利技](http://qiita.com/Shinji-Hashimoto/items/b63883168a2b825a0dff)
Ubuntu 16.04LTSでゲストセッションを無効にする

Ubuntu 16.04 のデスクトップ版ではデフォルトでゲストセッションが有効になっている。これを無効にする方法を日本語で書き留めました。LightDMというデフォルトのＸディスプレイマネージャーの設定を変更することで可能です。

```bash:terminal
sudo mkdir /etc/lightdm/lightdm.conf.d # lightdmの設定用のディレクトリを作成
# 50-no-guest.confというファイルに設定を書き込む
sudo sh -c 'printf "[SeatDefaults]\nallow-guest=false\n" > /etc/lightdm/lightdm.conf.d/50-no-guest.conf'
```

```bash:50-no-guest.conf
[SeatDefaults]
allow-guest=false
```

再起動するとゲストセッションの表示がなくなっています。

ゲストセッションを有効にし直す場合は、設定ファイルを消すだけ。

```bash:terminal
sudo rm /etc/lightdm/lightdm.conf.d/50-no-guest.conf
```



## 参考
http://ubuntuhandbook.org/index.php/2016/04/remove-guest-session-ubuntu-16-04/
Laravel5.4のインストールからデモ画面の表示まで

### Composerのインストール

```
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('SHA384', 'composer-setup.php') === '669656bab3166a7aff8a7506b8cb2d1c292f042046c5a994c43155c0be6190fa0355160742ab2e1c88d40d5be660b410') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
```
composerをグローバルで使えるようにする
`mv composer.phar /usr/local/bin/composer`

### Laravelのインストール
`composer global require "laravel/installer"`

laravelコマンドが使えるようにパスを追加
$PATHに ~/.composer/vendor/bin を追加する。

### プロジェクトの作成
プロジェクト名を指定してプロジェクト作成。
`laravel new project`

プロジェクトが完成したらディレクトリに移動
`cd project`

### パーミッション設定とか
storageとbootstrap/cacheを書き込みできるようにしておく。

```
sudo chmod -R o+w storage
sudo chmod -R o+w bootstrap/cache
```

### .envファイルの編集
適宜環境に合わせて編集する

```Bash:.env
APP_NAME=Laravel # プロジェクト名
...
DB_DATABASE=homestead # DB名
DB_USERNAME=homestead # DB ユーザー
DB_PASSWORD=secret # DB パスワード
```

### nginxのバーチャルホスト設定の変更
rootにlaravelのpublicディレクトリを指定する
* 前にテンパってここでハマりました。

### デモ画面がちゃんと表示されるか確認
![スクリーンショット 2017-07-31 21.44.33.png](https://qiita-image-store.s3.amazonaws.com/0/194671/1fb2e129-6b7e-2ab4-902b-fec6cc58f23a.png)
おしゃれなWebをつくるには。

おしゃれなWebデザインをつくるTipsを、備忘録としてまとめます。

#フォント

###Font family
日本語でも、google fontを使う。
https://developers.google.com/fonts/
https://fonts.google.com/

サンセリフ系

```css
"Josefin Sans",sans-serif;
'Roboto', sans-serif, 'Noto Sans Japanese', sans-serif, 'Quicksand', "游ゴシック体", "Yu Gothic", YuGothic, "ヒラギノ角ゴシック Pro", "Hiragino Kaku Gothic Pro", 'メイリオ' , Meiryo , Osaka, "ＭＳ Ｐゴシック", "MS PGothic", sans-serif;
Quicksand, 游ゴシック体, "Yu Gothic", YuGothic, "ヒラギノ角ゴシック Pro", "Hiragino Kaku Gothic Pro", メイリオ, Meiryo, Osaka, "ＭＳ Ｐゴシック", "MS PGothic", sans-serif;
```

セリフ系

```css
"Cinzel",serif,"游明朝体","ヒラギノ明朝 Pro W3",HiraMinProN-W3,"Hiragino Mincho Pro","ＭＳ Ｐ明朝","MS PMincho",serif;
```

###font-smooth
アンチエイリアスをかける。

```css
    -webkit-font-smoothing: antialiased;
    -moz-font-smoothing: antialiased;
    -ms-font-smoothing: antialiased;
    -o-font-smoothing: antialiased;
```

※モダンブラウザ：Chrome, Firefox, Safari対応。IE非対応。
[font-smooth - CSS | MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/font-smooth)

###font-weight
```css
font-weight: 200;
```
###letter-spacing
少しでもレタースペースをとるとオシャレ。

```css
letter-spacing: 0.1em;
```
###line-height
```css
line-height: 1.5em; 
```
###シャドウ
```css
text-shadow: 1px 1px 3px rgba(0,0,0,0.6);
```
###color
黒ではない色を使うとおしゃれ。
例：`color: #323232;`



#その他
Box要素には、
shadowをかけるとおしゃれ。

```css
border: #EBEBEB 1px solid;
box-shadow: 3px 3px 0 rgba(8, 1, 2, 0.03);
```


あとは、写真、マイクロインタラクションを工夫するなど。

メモ：
写真をぼかす/半透明フィルターかけて背景にする。
ボックスの右・左上に三角や、タイトルをいれる。

タイトル：日本語・記号・英語でサンドイッチするとおしゃれ。
モブプログラミングをやってみた感想

こちらに参加してきたのでそのメモ書きを
[モブプログラミングしよう！ -言葉が通じなくても、コードで通じ合える- - ギルドワークス | Doorkeeper](https://guildworks.doorkeeper.jp/events/62896?utm_campaign=event_62896_56839&utm_medium=email&utm_source=registered_message)

## モブプログラミング
**一つのモニタを見ながら、複数人でああだこうだ言いながら、みんなでプログラミングをすること。**
上記リンクより引用

コーダーは**ドライバー**
その他のサポートする人は**ナビゲーター**

n分区切りでドライバーは交代して、一周したら休む

環境はrepl->itを使った
色んな言語の実行環境を提供しているサービス
https://repl.it/

実験的にやる場合、
**みんなで使ったことない言語使うと一緒にパワーアップできていいらしいです**

## ドライバー
自発的に何か書く場合には、何をするかっていうのを表明する

## ナビゲーター
ドライバーに何をコーディングするか指示する

## やってみて

* ()はブラケットとか普段のプログラミング生活で聞かない単語を覚えた


* ドライバーはナビゲーターの指示を聞いてコーディングするのが基本なので
指示には、**n行目をこう**という風に言うとよい  


* 後ろから指示が飛んで来るのでやりやすい
みんなで作ってる安心感がある
ブラックボックスは生まれにくそう
生まれたとしてもその場でTodoとかに詳細に書けばいい
その文言もチームで考えられるのがよい
自分でメモを残しても他の人がわからなかったらそのメモは全く意味がないので

* ゴールを共有しとかないと発散してしまう
そのため、テスト駆動でやったほうがいいと思った
徐々に確かなものを作りながら開発できるので

* コメント書いていって概要設計だけでも面白そう
大事なことはみんなで決めて、決めたことを並列で各人が実装する
再度集合してレビューするとか

* 今回は10人でやったんだけど実際に発言するのは2 ~ 3人
→ 4 - 5人がいいのかな

* チームのレベルが均等になっていないときつい、プロジェクトの概要がわかってないときつい
例えば、新人がいると新人は聞いてばかりになってしまうし
とてもデキる人が1人で進めてしまったら意味がない
プロジェクトの概要がわかってないと、こうすればいいっていうことも
検討ハズレなことがある、自信がなくなったりするかなと
その点、みんなで新しいことをやってみるのにはいいのかも
実際の仕事では中々やる機会がないのかもしれないけど

* コードベースだと意外とコミュニケーションがとれる
画面にコードを書いてデバッグしたりすればいいので
話せたほうが画面に書かずに済むから早いとは思うけども

* 普段コードを書いているより、活発にコミュニケーションは行われる
複数人で問題解決をしているため
普段は、あるタスクについて一人でコードを書いているので
PlantUMLの準備 for Mac

## jarファイルをダウンロード
http://plantuml.com/download
「Last version : plantuml.jar」のところから。
広告の主張がえぐいので気をつけて下さい。

## jarファイルを適当な位置に移動する

```
mv plantuml.jar ~/installed/plantuml/path/
```

## HomebrewでGraphvizをインストール

```
$ brew install graphviz
```

## エディタ連携する

### Vimのひと

http://qiita.com/taketin/items/5cc7ff13b32492d9e2ad
こちらの記事がとても参考になりました。ありがとうございます。
上記の記事のようにシェルスクリプトを作って`$HOME/local/bin`に配置しました。

```bash
$ mkdir -p $HOME/local/bin
$ cd $HOME/local/bin
$ vim plantuml
```

```bash:plantuml
#!/bin/bash
java -jar $HOME/lib/java/plantuml.jar -tpng $@ # pngで書き出されます
```

下記のPluginを導入する
https://github.com/aklt/plantuml-syntax

### Atomのひと
http://dev.classmethod.jp/devenv/atom-plantuml-sequence/
http://qiita.com/moca_uni/items/dc3ac5f7a5e3834de3d5
上記の記事が参考になると思います。

プラグインやパッケージが用意されていて助かります。

### VSCodeの人
インストールするプラグイン
[PlantUML - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=jebbs.plantuml)
※JavaのRuntimeがインストールされているか確認し、なければインストール

1. VSCodeで`⌘+P`を押し、以下をペーストしてEnter
`ext install plantuml`

2. PlantUMLのプラグインをインストール後、VSCodeを再起動

## 書く

記法はこちら
http://plantuml.com/sequence-diagram

例

```:sample.pu
@startuml
autonumber
User -> Front: Sendボタンをクリック
activate Front
Front -> Front: /sample_page
activate Front
Front -> API: /a_resource params=somethig
activate API
API -> DB: 情報をDBに登録
activate DB
DB -> API: result_id を返す
deactivate DB
API -> Front: successとresult_idを返す
deactivate Front
deactivate API
Front->User: Thanks画面を表示する
Front -> Front: /submit/multi
activate Front
Front->API: /multi
activate API
API->API: something
API->DB: 何かの情報をテーブルに保存
API->Front: すべての処理結果の successとresult_idを返す
deactivate API
Front->Front: ユーザーにはまとめてメールを送信
deactivate Front
deactivate Front
@enduml

```

## 実行する

### javaコマンドで直接生成する場合

```bash
$ cd /path/to/file/ # sample.puファイルが有るところに移動する
$ java  -Dfile.encoding=UTF-8 -jar ~/installed/plantuml/path/plantuml.jar ./*pu -o .
``` 

`-o`で指定したディレクトリ（この場合はカレントディレクトリ）にsample.pngが生成されます。

### Vim上で実行する場合
http://qiita.com/taketin/items/5cc7ff13b32492d9e2ad#%E5%AE%9F%E8%A1%8C
こちらに記載されているように`:make`コマンドだけで画像を生成してくれます。この場合も`sample.pu`ファイルと同じディレクトリにsample.pngファイルが生成されます。

### VSCodeの場合
`sample.pu`を開いた状態で`Alt+D`でプレビュー表示。
ファイル出力をしたい場合は、`⌘+Shift+P`で、`PlantUML: Export Current Diagram`を選択、さらに出力したい拡張子を選択すれば、
`sample.pu`ファイルと同じディレクトリに`sample`ディレクトリが作成され、その中に選択した拡張子のファイルが出力されます。
[VSCodeのデモ](https://github.com/qjebbs/vscode-plantuml#preview-and-export-demos)

以上です。モデリングっていいですね。
CoreML Tools + macOS High Sierra だと apple pythonでないと動かない？

CoreML Tools を使って、Kerasで作成した学習済みモデルをiOSにポーティングしています。
正解率が著しく悪くなってしまったので、PC上で確認したくて `MLModel#predict()` をやろうとしたら High Sierraにアップデートしろと言われた。
仕方がないのでアップデートしたところ、状況が悪化したので備忘録。

## 前提
- macOS Sierra
- Python 2.7.13 (brew, /usr/local/bin/python)
- CoreML Tools 0.4.0
- モデルのコンバート(`coremltools.converters.keras.convert()`, `MLModel#save()`)は正常動作
- モデルのロード(`coremltools.models.MLModel`) しよとするとOSバージョンエラーが出る

## やったこと

### 1. macOS High Sierra beta4にアップデート
Appleのディベロッパーポータルからダウンロードしてインストール。40分くらい？

### 2. モデルのロードを試行  

```
>>> model = coremltools.models.MLModel('HogeModel.mlmodel')  
Fatal Python error: PyThreadState_Get: no current thread
Abort trap: 6
```
モデルのロード時にエラー

あわてて試すと、モデルのコンバート(正確には、保存処理の `MLModel#save()`)も同様のエラー発生

エラーについて調べると、CoreML ToolsがmacOSバンドル版のPython向けになっているからのよう。
http://qiita.com/hatchinee/items/b16ee02b3c93603aee0c

エラーを吐いているオブジェクトの詳細がわかれば install_name_toolで対象できるようだったが、CoreML Toolsの内部がよくわからないので(時間もなかったので)とりあえずバンドル版のPython(/usr/bin/python) に切り替える

### 3. バンドル版のPython(/usr/bin/python)に切り替える(中途半端)

といいつつ、Pyenvの古い設定が残っていたせいでうまく行かなかったので、バンドル版はフルパス指定で呼び出しつつ、pipのみ再インストールした。  
つらいのでこの辺りは近いうちに綺麗にしないと。

```
$ which python
/usr/local/bin/python
$ python --version
Python 2.7.13

$ /usr/bin/python --version
Python 2.7.10

$ which pip
/usr/local/bin/pip
$ pip --version
pip 9.0.1 from /Library/Python/2.7/site-packages/pip-9.0.1-py2.7.egg (python 2.7)
```

pyenv環境が汚れていなければ、systemにswitchするだけで済んだのだろうか・・・

### 4. SIPと向き合う
依存ライブラリ(coremltools, keras, tensorflow, numpy, h5py)の再インストールが必要だが、High SierraではSierraと同様SIP(rootless)のせいでpipでのインストールに失敗する。  
それが嫌でHomebrew版とかに逃げるわけだが、今回はそうはいかないので、 `--user` オプションでとりあえず逃げる。  

```
$ pip install --user tensorflow coremltools
```

もし、Homebrew版とかの(普段使いの方の)Python2.7で `/Users/username/Library/Python/2.7/lib/python/site-packages` を使っている場合は、インストール先が被るので、 `--user` オプションの向き先を変える必要がある。  
http://qiita.com/ronin_gw/items/cdf8112b61649ca455f5 とか、かしら？  

自分の場合は、Homebrew版の方が `/usr/local/lib/python2.7/site-packages` を向いていたので、ひとまず大丈夫なはず。。。


### 4. 失敗した処理の確認
- モデルのコンバート : OK
- モデルのロード : NG

ロード自体は成功したのだが、肝心の推論実行に失敗する。

```py
>>> result = model.predict({'image': x})
〜中略〜
Exception: Unable to load CoreML.framework. Cannot make predictions.
```

結局ダメか。


## 感想
- OSの機能使うだろうから仕方ないなーと思いつつ、バンドルPython縛り&2.7縛りめんどい。。。
- CoreML Toolsは、公式のAPIレファレンス見てても、メンバーがメソッドになってたり、結構ドラスティックに変わってる部分もあるっぽいので注意。
- 早くフル機能ためしたーい。
- またPython環境がよごれてしまった。
FBX解読④ Mesh描画編

http://qiita.com/gshirato/items/87a14ffd9844dd474b72
の続き

#固定ハフマンで展開していく。

Verticesを順に読んでくと

`0x00 0x00 (4,1) F0 3F (3,6) ...`というように続いていく
ここでカッコは(一致長、自分からの距離）を表しており、
例`9 8 4 (2,3)`→`9 8 4 *9 8*`
また、`一致長>自分からの距離`の場合は一致長に達するまで同じところをくりかえす
例`3 5 2 1 (6,3)`→`3 5 2 1 *5 2 1 5 2 1*`

つまりVerticesのDataは

```
0x00 0x00 0x00 0x00  0x00 0x00 0xf0 0x3f
0x00 0x00 0x00 ...
```
と翻訳できる。
終了コード読み込んだ時点でそのブロックは終了して良い。
複数ブロックがある場合は最後にそれらを連結させる。


このように翻訳していくと最終的に192byte=(8*24)の配列を発見でき、これはDouble型の大きさが8bytesであることを考えると納得の行く数字。
あとは出てきた数字をDouble型と同じく倍精度浮動小数点数型として8byteずつよんでいくだけ。

#Unityで表示

##Meshクラスを使う

```csharp:main
Mesh mesh = gameObject.AddComponent<MeshFilter>().mesh;
MeshRenderer renderer = gameObject.AddComponent<MeshRenderer>();

//配列から得た情報
Vector3[] vertices = new Vector3[]
    {
        new Vector3(1f, 1f, -1f),
        ... //上で得た頂点情報をそのまま使える
    }
Vector3[] normals = new Vector3[]{略}
int[] verticesIndex = new int[]
    {
        0, 1, 2, 3,
       ....
    }

//meshのセットアップ
mesh.vertices = vertices;
mesh.triangles = verticesIndex;//四角ポリゴンなのでtriangleを使うべきなのかは謎。
mesh normals = normals;
GetComponent<MeshFilter>.mesh = mesh;
mesh.SetIndices(makeIndices(8), MeshTopology.Quads,0);

```

```csharp:makeIndices()
int[] makeIndices(int n)
{
    int[] indices = new int[n];
    for(int i = 0; i<n;i++)
    {
        indices[i] = i;
    }
    return indices;

}

```

normalsはまだ手を付けてないのできれいには見えないはずだが立方体が見えるはず…

#結果

![tris.PNG](https://qiita-image-store.s3.amazonaws.com/0/186209/c464f2c9-3e84-b588-77b1-9fbc3dd6dcb4.png)
![lines.PNG](https://qiita-image-store.s3.amazonaws.com/0/186209/ec4cf2a5-6dba-3f94-e8ed-c1950d175e8f.png)
![LineStrip.PNG](https://qiita-image-store.s3.amazonaws.com/0/186209/31f24940-334b-7856-0e80-331fde1fd81f.png)



##WTF !!!

改善に向けて努めて行きます。決して遠くはない。


#HoloLensアプリ開発記事一覧
http://qiita.com/gshirato/items/6c026f2c67dc332f829b から
Kinesis Firehose & s3 & Athenaでビッグデータ処理！

#  背景
* ユーザーから送られてきた大量の位置情報ログをpostgresqlに保存するのがつらくなってきたのでs3に投げて処分するようにしたい。
* けれども**fluentdを入れたaws-ec2をログアグリゲータにしてスケールさせるのは面倒。**
* けれども、実証実験や営業資料の作成のニーズが多いためs3に投げたログは引き続きRDBMSのような何かで**気軽に検索＆集計できるようにしたい。**

# 構成
以下のように、サービスから投げたログをKinesisFirehoseが受け取ってs3に保存し、Athenaで検索するようにしました。

![cloudcraft - KinesisFirehose & S3 & Athena (2).png](https://qiita-image-store.s3.amazonaws.com/0/38693/99f22645-d198-5946-ead8-d17824e8e532.png)

# 実装とハマりどころ
## KinesisFirehose
ログ処理に特化したサービスで、流し込んだデータを塊にし圧縮してredshift、s3、elastic searchのいずれかに投げることができる。特徴は負荷に応じた同時実行数やインスタンス数の上限等を調整する必要がなく、使用者が**スケーラビリティを気にしなくて良い**こと。

現状では日本展開していないので西海岸で日本に近そうなオレゴン（us-west-2）で作る。

<img width="573" alt="スクリーンショット 2017-07-31 1.51.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/38693/be2ea3ad-f39e-f230-f50d-7e216d126cdd.png">

まずはバゲット名を指定し、s3にアクセスする用のロールを作る。s3に投げられると
```
バケット名/2017/07/30/時刻/ログ名
```
という風にログがモリモリ保存されていくが、s3 buffer sizeは最後のログファイルのサイズの上限で、S3 buffer intervalは１個のログの時間幅の上限。ちなみに**時間はUTC。**

また、rubyからjson形式で投げる場合は以下のようになるが、

```
firehose = Aws::Firehose::Client.new(region: 'us-west-2')
firehose.put_record(delivery_stream_name: ENV['KINESIS_DELIVERY_STREAM_NAME'], record: {data: data.to_json + "\n"})
```

json形式のログをAWS Athenaで解析できるようにする場合は **以下のように１つ１つのobjectが改行されている必要があるため１個のobjectだけを送る場合は末端に改行コードを入れる必要がある。**

```xxx-logs-stream-1-2017-07-06-01-04-09-466c7aa2-754a-11e7-88d3-5f6e237864f8.gz
{"user_id":1111,"coupon_id":2222, "created_at" :  "2017-07-06T01:03:36.356Z"}
{"user_id":3333,"coupon_id":4444, "created_at" :  "2017-07-06T01:03:37.356Z"}
```


## s3
言わずもがなの何でも置いておける格安ストレージ(１GBあたり2円）

## Athena
s3に放り込まれたログをSQLで検索できるシステム。BigQueryと同じクエリがスキャンしたデータ量に応じて課金される料金体系（1TBあたり$5）だが、以下のように**パーティション**を作成すると指定されたフォルダ以外のログはスキャンせずパケ死しなくなる。なお、**firehoseのYYYY/MM/DD形式のディレクトリにはデフォでパーティションが設定されてはいないので日毎にパーティションを作りたい場合は一日に一度の定期タスクでAthenaのクエリを叩いて作ってやる必要がある（ダルい！）。**

```
ALTER TABLE xxxx_logs.logs add partition (dt='20190630')
LOCATION 's3://xxx-logs/2019/06/30';
SELECT count(id) form logs where dt=20190630
```

使用するデータベースとテーブル名を設定し、ログが保存されているバゲットのリンク、データの形式、およびカラム（**日時はdate型でパースできるよう整形するのが面倒な場合はstring型にした方が良いかも**）を入力するとテーブルを作成するcreate文が作られ、成功すれば以後そのバゲットを検索できるようになる。

<img width="974" alt="スクリーンショット 2017-07-31 2.38.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/38693/e88430e1-0c1c-a7b1-aef2-025c4ba514c0.png">

なお、単なるs3ビューワーなので、以下のように新旧の形式が混在したログが入っていても整合性を意識せずに検索できるし、いつでも作り直せる。

```
{id: 1, latitude: 38.2345, longitude: 121.9876, user_id: 1
{id: 2, latitude: 38.2345, longitude: 121.9876, user_id: 1, app_id: 1}
select count(id) from logs where app_id is null
=> 1
```


# 結果
1.DBのコネクション数が劇的に減った♪
2.一日300MBずつ増えていたDBの増加が止まった！
3.Atehnaの検索早い！（100万件のログを２秒で検索可）
Ubuntu14.04にElasticsearchをインストール

# elasticsearchをインストール
### リポジトリの設定
```bash
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
sudo apt-get install apt-transport-https
echo "deb https://artifacts.elastic.co/packages/5.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-5.x.list
sudo apt-get update
```

### インストール
```bash
sudo apt-get install elasticsearch
```
 
### 起動
```bash
sudo service elasticsearch start
```

# 設定変更
### MAX_LOCKED_MEMORY
```bash
sudo vim /etc/init.d/elasticsearch
MAX_LOCKED_MEMORY=unlimited
```
 
### 再起動して設定反映
```bash
sudo service elasticsearch restart
```
 
### curlで確認
```bash
curl 'http://localhost:9200/_nodes/process?pretty'
```
 
# コマンドTips
### ヘルスチェック
```bash
http://localhost:9200/_cat/health?v
```

###
```bash:findAll
curl 'localhost:9200/[インデックス名]/_search?q=*&pretty'
```
Delphi 10.2 Tokyo でのスレッド変更

# Delphi 10.2 Tokyo のメインスレッド
Delphi 10.2 Tokyo の Android 向けアプリでは Delphi の UI Thread と Android の Java Native Thread の同一化が図られました。

> [Delphi 10.2 新機能](http://docwiki.embarcadero.com/RADStudio/Tokyo/ja/%E6%96%B0%E6%A9%9F%E8%83%BD#FireMonkey)
> Android における Delphi と Java のスレッドの統一化： CallInUIThread は非推奨にすべてのコードが、Java UI スレッドで実行されており、スレッド同期の必要はなくなりました。
CheckSynchronize メソッドを呼び出すために使用される ProcessMessages メソッド。これは、Java Native スレッドからコールバックを呼び出されます。かつては、Delphi UI スレッドと Java Native スレッドの 2 つのスレッドがありました。10.2 におけるリファクタリング作業により、1 つのスレッド、Java Native スレッドにだけに絞られました。これは Android からのすべての通知を受け、それらを Delphi イベント ハンドラに転送するようになっています。while サイクルを介してブロックされる一方、イベント ハンドラは実行されず、サイクルから出てしまうことが避けられます。コールバックやイベントは一般的に、アプリケーションのメイン スレッドを保持しているコードがない場合に呼び出されます。

これによって、Android 側にアクセスする度に 一々 CallInUIThread といったヘルパ関数を通す必要が無くなりました。
UI にアクセスする場合、大変便利になったわけですが、その反面、不都合もおきます。

#不都合
## 重たい処理
Delphi UI Thread と Java Native Thread が同一になった事で、Delphi 側でメインスレッドに対してのケアが必要になっています。
たとえば、Delphi UI Thread 内で重たい処理をすると ANR (Application Not Responding) としてアプリを落とされてしまいます。
きちんと、並列処理をしなくてはなりません。

## ダイアログ
Android のダイアログは非同期化されています。

> [FireMonkey モーダル ダイアログ ボックスの使用](http://docwiki.embarcadero.com/RADStudio/Tokyo/ja/FireMonkey_%E3%83%A2%E3%83%BC%E3%83%80%E3%83%AB_%E3%83%80%E3%82%A4%E3%82%A2%E3%83%AD%E3%82%B0_%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9%E3%81%AE%E4%BD%BF%E7%94%A8)
>メモ： Android は、モーダル ダイアログをサポートしていません。

Berlin までは UI Thread と Java Native Thread は別だったので、Java Native Thread を動かして UI Thread 側でループして待つ、といったことができました（簡易的なモーダルダイアログ化）。
しかし、Tokyo では UI Thread = Java Native Thread なので、ループで待てません（Java Native Thread が固まる事になる）。
ここも、きちんと並列化しないといけないのはもちろん、Berlin から移行するときに気をつけなければいけないポイントとなります。

# まとめ
つまり、Tokyo からは普通の Android アプリのように、きちんとスレッドによる並列化をやらないといけない、という事です。
ある意味、普通になったとも言えます。
CData コンポーネントの入手方法

# Enterprise Connectors
今回の[第３４回デベロッパーキャンプ](http://forms.embarcadero.com/developer-camp-overview)は [CData との提携](https://www.embarcadero.com/jp/products/enterprise-connectors)の話題で持ちきりでした。

ただ、入手方法について言及が余り無かったように思えました。
これはベータ版だからかもしれません。

そうなんです。
いまインストールできるのは**ベータ版**です！
正式リリース時には**年間サブスクリプションでお金かかります**！

# 入手方法
GetIt で CData と打ち込むだけです！
かんたん！！
![cdata.png](https://qiita-image-store.s3.amazonaws.com/0/12977/c4044b2b-2a8a-946e-d976-32a80696cd70.png)

とはいえ、途中で CData のインストーラーが出てきて、名前やメールアドレスを入れないといけません。

![cdatainst.png](https://qiita-image-store.s3.amazonaws.com/0/12977/3a303bd0-7c0c-741b-2d73-294a35b53220.png)

インストールが終わると RAD Studio を再起動するか聞かれるので再起動しましょう。

再起動すると、こんな感じで FireDAC のデータソースとしてインストールした CData のコンポーネントが現れます（今回は CData の Twitter 用データソースをインストールしました）。

![de.png](https://qiita-image-store.s3.amazonaws.com/0/12977/4be82866-6261-c6b8-5142-6d66b3353c74.png)

あとは、他のデータソース同様に右クリック「新規接続の追加」で各種パラメータを設定できるようになります。

![tw.png](https://qiita-image-store.s3.amazonaws.com/0/12977/9e928976-8bc6-3aec-c7ac-5e804f5d530d.png)

そんな感じでベータ版の入手方法の紹介でした！
最新バージョンGitインストール

サーバーの作ったり壊したり作らされたり壊したりをしてるうちにだんだん面倒になったので自分用として最新版gitのインストール方をメモっておく。

Gitインストール
=============
最新のGitのバージョンを確認し、ファイルパスを取得。
-------------
ここ→ [Git](https://git-scm.com/)で現在の最新のバージョンを確認する。

確認したバージョンのファイルパスを取得（マウス右クリックでリンクのアドレスをコピー）
 [Gitデータ一覧](https://www.kernel.org/pub/software/scm/git/) 
※下記コードのgit-2.13.3.tar.gzはwiki作成時の最新のもの。

    https://www.kernel.org/pub/software/scm/git/git-2.13.3.tar.gz

CentOS7にGitをインストール
-------------
Gitの導入に必要なツールを先にインストールする。

    $ sudo yum -y install curl-devel expat-devel gettext-devel openssl-devel zlib-devel

Gitを導入していきます。まずはソースコードを取得し、解凍する。

    $ cd /usr/local/src/
    $ sudo wget https://www.kernel.org/pub/software/scm/git/git-2.13.3.tar.gz
    $ sudo tar xzvf git-2.13.3.tar.gz

makeコマンドでインストールする。

    $ cd git-2.13.3
    $ sudo make prefix=/usr/local all
    $ sudo make prefix=/usr/local install
    $ source /etc/profile

確認する。

    $ git --version
    git version 2.13.3

気になる場合はtar.gzファイルは削除してしまう。

    $ rm -rf git-2.13.3.tar.gz



makeコマンドでエラーが出た場合
-------------
昔調べたときにどなたかがエラーの対応コマンドを載せていたのを借用させていただきます。
引用元を見つけたらリンクをはらせていただきます。

> /bin/sh: curl-config: command not found

    yum install curl-devel

> /bin/sh: cc: command not found

    yum install gcc

> git-compat-util.h:208:25: warning: openssl/ssl.h: No such file or directory g

    yum install openssl-devel

> http-push.c:14:19: warning: expat.h: No such file or directory

    yum install expat-devel

> Can't locate ExtUtils/MakeMaker.pm in @INC  at Makefile.PL line 3.
> BEGIN failed--compilation aborted at Makefile.PL line 3.
> make[1]: *** [perl.mak] Error 2
> make: *** [perl/perl.mak] Error 2

    yum install cpan

> MSGFMT po/de.msg make[1]: *** [po/de.msg] Error 127

    yum install gettext
WordPressを運用するなら最低限これだけはやっておけリスト

# WordPress運用を行うなら最低限これだけはやっておけリスト

事の始まり。ていうか、時すでに遅し。
既に事終えているのですが、弊社が管理しているサーバの一つに古いWordPressがインストールされており、Web ShellというBackdoorを仕込まれる事態になりました。

二度とこんなことは経験したくないため、誰でも容易に運用できるからこそ、誰でも簡単に攻撃できてしまうため、ある程度のリスクヘッジすることが必要と感じました。
しかしながら、攻撃手法も様々なためこれで全てとは思っていませんが、少なくともこれから挙げていくリストを守れば侵入を許すことは早々ないかな、と思います。

（っていう啓蒙活動はみんなやってるんですけど、なぜか広まらない。）

## 結果何が起きたか

WordPressの3.6を運用するサーバと独自のECパッケージが同居するサイトが瀕死になりました。
Shellログインができず、Nginxが起動しない(なんとかhttpdは生きてた)、yumパッケージの修復を試みるもOSのライブラリの一部が欠損しているため、どうしようもない状態です。

幸いしたのはDBサーバが元々はWebサーバから作られていたということもあり、OSのバージョンからライブラリまでほぼ全て同じであるということです。
このことから、Webサーバは仮復旧しましたが、以前としてウィルス感染したままです。

というわけで、急遽、DBサーバから改めてWebサーバを作り直しました。（今時Cent OS ***5.2*** ）

## これぐらいやっておけよって思うこと

- Pluginの導入一覧
 - [Edit Author Slug](https://ja.wordpress.org/plugins/edit-author-slug/)
     - authorを変更するためのプラグイン。管理者が誰であるかがわからなくようにするために必要。ググれば危険性がいくらでも出てきます。
      - https://example.co.jp/?auther=1 とかするとログインユーザがわかります。やめましょう。
 - [Acunetix Secure WordPress](https://ja.wordpress.org/plugins/secure-wordpress/)
      - これも有名です。WordPressのセキュリティに関わる部分に対し、良い感じにセキュリティを担保します。
      - config.phpを隠したりreadme.htmlを無効にしたりファイルパーミッションを適切にしてくれたり。
    - [Wordfence Security](https://ja.wordpress.org/plugins/wordfence/) or [AntiVirus](https://wordpress.org/plugins/antivirus/)
        - サイト改ざんを検出するPluginです。どちらかは最低入れましょう。
        - Themeが改ざんされ、侵入されるケースは割と多いです。
 - [Login LockDown](https://ja.wordpress.org/plugins/login-lockdown/)
     - 執拗にあるユーザでログインを試行した場合、そのユーザを一定回数で一定時間、そのユーザをロックするPluginです。
     - 他のPluginとの兼ね合いで自分がロックされることもありますが、入れておきましょう。特に会社のIPや自宅のIPが動的IPであれば、入れておくことをなおさらお薦めします。固定IPでしたらwp-login.phpとadminディレクトリにBasic認証をかけておくと良いと思います。
 - [Backwpup](https://ja.wordpress.org/plugins/backwpup/)
     - WordPressをDropboxにバックアップするPluginです。
     - これ入れて設定しておけば最悪前日分に戻せます。
 - [Akismet Anti-Spam (アンチスパム)](https://ja.wordpress.org/plugins/akismet/)
     - スパム投稿されたコメントをがっつり消してくれるプラグインです。
     - 個人ブログでもコーポレート系のブログなどでも入れておく方が良いプラグインです。
 - [Jetpack by WordPress.com](https://ja.wordpress.org/plugins/jetpack/)
     - markdownとかアクセス状況を見たりとか色々見れるので入れておく方が良いプラグインです。
     - 無料の範囲で十分使える上、自動アップデート（ログインは必要）にも対応してるのでオススメです。
     - WordPress標準の自動アップデートやコードによるアップデートは更新通知が発生するだけとのこと。

## しばらく運用してみて追加したプラグイン

- オプショナルで入れてもいいかも
    - [Two Factor](https://ja.wordpress.org/plugins/two-factor/)
        - いま話題になりつつあるU2Fを使えるプラグインです。管理画面にログインする際に登録したU2F対応デバイスでしかログインできなくなるのでオススメと言えばオススメ。個人でやってる場合は紛失したらプラグイン無効化するなど一手間必要です。

## 脆弱性診断に専用ツールもあるので使ってみる

wpscanというruby製でできた脆弱性診断ツールですが、このツールを使うだけでも自分のサイトの脆弱っぷりがわかったりもします。
テーマやpluginに脆弱性がある場合は発見することが可能で、先ほど挙げたEdit Author Slugを使っていない場合は、管理者名とDBにログインユーザ名が一致してるので、ユーザ情報がごっそり出力されます。
弊社は固定IPを設けていますので.htaccessで管理画面にアクセス制限を設けたりすることでセキュリティを担保するようにしています。

# まとめ

最低でもこれぐらいやっておかないと安心してWordPressの運用は利用者に任せられないと思います。
重くなるから嫌だとかそういうのはキャッシュを導入したり、サーバを増強すればなんとでもなります。
むしろ、これぐらいで重くなるようなサイトは色々Pluginの入れすぎか、jsやcssが最適化できていないとかそういう違う方面の努力が必要です。
あと、最近だと爆速になるwebサーバのミドルウェアがありますので、違う方向での努力を本当にお薦めします。

………弊社が運用するブログもPluginを入れすぎている関係で重い(表示が遅い)んですけどね………。
これは前任者が色々入れたからですけど………。
ALB の Default の Log を Athena に Import する方法

## (1) まず ALB の Default の Log の仕様

http://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-access-logs.html

## (2) Athena にテーブルを作る

下記の CREATE TABLE 文にて、

- YOUR_ATHENA_TABLE_NAME
- YOUR_ALB_LOG_BUCKET

を適用する環境にあわせて変えて実行する

```
CREATE EXTERNAL TABLE IF NOT EXISTS YOUR_ATHENA_TABLE_NAME (
 `type` string,
 `timestamp` string,
 `elb` string,
 `client_port` string,
 `target_port` string,
 `request_processing_time` double,
 `target_processing_time` double,
 `response_processing_time` double,
 `elb_response_code` int,
 `backend_response_code` int,
 `received_bytes` bigint,
 `sent_bytes` bigint,
 `request` string,
 `user_agent` string,
 `ssl_cipher` string,
 `ssl_protocol` string,
 `target_group_arn` string,
 `trace_id` string
 )
 PARTITIONED BY (year int, month int, day int)
 ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
 WITH SERDEPROPERTIES (
 'serialization.format' = '1',
 'input.regex' = '^([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([0-9-\.]+) ([0-9-\.]+) ([0-9-\.]+) ([0-9-]+) ([0-9-]+) ([0-9-]+) ([0-9-]+) ["](.*)["] ["](.*)["] ([^ ]+) ([^ ]+) ([^ ]+) (.*)$'
 ) LOCATION 's3://YOUR_ALB_LOG_BUCKET/elb-websocket/AWSLogs/XXXXX/elasticloadbalancing/YOUR_REGION/'
 TBLPROPERTIES ('has_encrypted_data'='false');
```
## (3) データをロードする

```
ALTER TABLE YOUR_ATHENA_TABLE_NAME
ADD IF NOT EXISTS PARTITION (year=2017,month=7,day=31)
location 's3://YOUR_ALB_LOG_BUCKET/elb-websocket/AWSLogs/XXXXX/elasticloadbalancing/YOUR_REGION//2017/07/31/'
```

## (4) データを確認する

↓とかで各 Status 毎の Count を見たり。

```
SELECT substr(timestamp, 1, 13) as time,
COUNT(IF(elb_response_code / 100 = 1, 1, NULL)) as count_1XX,
COUNT(IF(elb_response_code / 100 = 2, 1, NULL)) as count_2XX,
COUNT(IF(elb_response_code / 100 = 3, 1, NULL)) as count_3XX,
COUNT(IF(elb_response_code / 100 = 4, 1, NULL)) as count_4XX,
COUNT(IF(elb_response_code / 100 = 5, 1, NULL)) as count_5XX,
AVG(target_processing_time) as target_processing_time_average
FROM YOUR_ATHENA_TABLE_NAME 
WHERE year = 2017 AND month = 7 AND day = 31
GROUP BY substr(timestamp, 1, 13)
ORDER BY time
```
認証プロキシ配下でのGrails3を使った開発（create-app～run-app）

## はじめに
社内の認証プロキシに阻まれていたことで長らく敬遠していたGrails 3.xですが、このたびようやくプロキシを突破し開発スタートできたので、どのような設定をしたかを書いておきます。  
Grails 2.xまでは、Grailsコマンドのadd-proxy/set-proxyコマンドでプロキシ情報を設定できましたが、Grails 3.xではそこが大きく変わっているので、少し調査が必要でした。

## 前提条件
今回は以下の環境で試しました。

* OS：Windows8.1/10
* IDE：IntelliJ IDEA（ULTIMATE 2017.2）
* Grailsバージョン：3.3.0


## create-app
まずはcreate-appですが、この時点でプロキシの設定をしておかないと失敗します。

### システム環境変数の設定
いろいろ試した結果、以下の設定をシステム環境変数に入れればいいということがわかりました。

変数名は「JAVA_OPTS」、値は以下。

```
-Dhttp.proxyHost=proxy.host.com -Dhttp.proxyPort=1234 -Dhttp.proxyUser=username -Dhttp.proxyPassword=password -Dhttps.proxyHost=proxy.host.com -Dhttps.proxyPort=1234 -Dhttps.proxyUser=username -Dhttps.proxyPassword=password
```

関係ないですが、Windows10では環境変数を登録・編集で複数値をわけて入力できるようになるなどUIが進化していて、便利ですね。初めて見たときはちょっと感動しました。

### コマンドプロンプトから「grails」実行
さて、これで設定は完了なのですが、IDE（IntelliJ IDEA）からcreate-appしようとするとエラーが出てしまいます。が、実はコマンドプロンプトから1回grailsコマンドを実行するだけで、その後エラーなくcreate-appできるようになります。
Grailsのインストールディレクトリをコマンドプロンプトで開き、「grails」を実行しましょう（コマンドプロンプト等からGrailsコマンドを実行する想定であれば、Grailsのインストールディレクトリに対するPathの設定が必須ですが、今回はIDEでの実行を前提としているので割愛します）。


## run-app
アプリの実行をするには、Grails 3.xのビルドシステムであるGradleにプロキシ情報を教えてあげなければなりません。
「gradle.properties」をC:\Users\\\<user>\\.gradle 配下に作成し、以下の内容で保存しておきます。

```groovy:gradle.properties
systemProp.https.proxyHost=proxy.host.com
systemProp.https.proxyPort=1234
systemProp.https.proxyUser=username
systemProp.https.proxyPassword=password
systemProp.http.proxyHost=proxy.host.com
systemProp.http.proxyPort=1234
systemProp.http.proxyUser=username
systemProp.http.proxyPassword=password
```
この設定をすると、認証プロキシ下でもrun-appが成功するようになります。

ちなみにこの設定をしないと、

```
Could not resolve all dependencies for configuration ':detachedConfiguration24'.
```

というようなエラーが出てしまいました。
このようなエラーが出たら、Gradle側のプロキシ情報が正しく設定されているか確認してみてください。
認証プロキシ配下でIntelliJ IDEAのライセンス認証を行う

## はじめに
ついにIntelliJ IDEAを買ってしまったので、業務でもがしがし使っていこうと思います。個人ライセンスだと年間サブスクリプションが1万円台でかつ年々安くなり、しかも業務利用や複数PCへのインストールもOKということでポチってしまいました。
参照：http://samuraism.com/products/jetbrains/faq#installation

今回は、会社のPCにインストールしようとしたときに認証プロキシに邪魔されてすんなり入らなかったので、その話を書いておきます。

## 認証プロキシ
会社ではネットワークが認証プロキシによって守られているので、外部アクセスをするにはプロキシサーバーへの認証が必須です。
IntelliJ IDEAをインストールし、ライセンスをアクティベートしようとしたら、うまくいきませんでした。
いちおう、プロキシ情報を入力するダイアログが出てくるのですが、ホストとポートを入れる欄しかなく、ユーザー名/パスワードで認証するプロキシには対応していないようです。
<img src="https://qiita-image-store.s3.amazonaws.com/0/194664/4bf111e5-7c94-e6eb-4695-9e9799481932.png" width="300px" style="border:solid 1px #333">

ダメ元でここに

```
ホスト：username:password@proxy.host.com
ポート：1234
```

のように入力してみましたが、やっぱりダメ。少し考えた結果、意外と単純な方法で回避できました。

## いったん評価版で実行しプロキシ情報を設定する
その方法は、ライセンスをアクティベートせず、まず評価版でIntelliJ IDEAを起動し、そこでプロキシ設定を変えるという方法です。
ライセンス認証ダイアログで「Activate」から「Evaluate for free」に変更し、「Evaluate」を押します。

<img src="https://qiita-image-store.s3.amazonaws.com/0/194664/74c5abcf-6f49-5ab4-e216-974321215ad3.png" width="300px">


するとIntelliJ IDEAのスタート画面が表示されるので、右下の「Configure」→「Settings」から設定画面を開き、プロキシ設定を行います。

<img src="https://qiita-image-store.s3.amazonaws.com/0/194664/d7f985b0-81bd-81ce-a934-c2ffa943eecb.png" width="300px" style="border:solid 1px #333">

プロキシ設定は設定の「Appearance & Behavior」→「System Settings」→「HTTP Proxy」にあります。
<img src="https://qiita-image-store.s3.amazonaws.com/0/194664/fbcab50c-c08a-eaeb-57d6-02c2f83963a1.png" width="500px" style="border:solid 1px #333">

ここで認証情報までしっかり入力し、「OK」を押して戻ります。
最後に、「Configure」→「Manage License」から再度アクティベートを試みると、無事、プロキシを突破しライセンス認証に成功しました。

<img src="https://qiita-image-store.s3.amazonaws.com/0/194664/ad4171fc-37dc-70f1-1f44-8b03c140cfe0.png" width="300px" style="border:solid 1px #333">
Djangoのプロジェクトで静的ファイルを参照する方法

DjangoテンプレートのHTMLでCSSファイルなどの静的ファイルを参照したいとき、参照元に注意しないといけません。ローカル環境のみで使うのであれば、絶対パスでもいいのですが、チーム開発などでプロジェクト内に残しておきたい場合は別の書き方をしないといけません。

今知っている限りでは2つ静的ファイルを参照する方法があります。

作業環境:
macOS Sierra バージョン10.12.5
Python 2.7.10
Django 1.8.1

#アプリケーションのディレクトリに置く
デフォルトの設定では使うアプリケーション以下にstaticディレクトリを作成するとDjango側で読みこんでくれます。

```
my_app
  └── static  
        └── my_app
              ├── css
              └── js
```
#参照したいディレクトリのリストを定義する
別なところに置きたい場合はそのディレクトリが参照できるように、設定ファイルのSTATICFILES_DIRSにパスを追加するとファイルを検索してくれるようになります。

```
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),
]
```
<br>

***
特にDjangoのadmin画面のcssを変更したいといった場合は注意が必要です。admin画面で使用しているbase.cssなどはPCにインストールしたPython内のDjangoが参照元となっているため、プロジェクトのファイルとは別々の扱いになっています。プロジェクトでadmin画面を変更したい場合などは、Django内からテンプレートとCSSをコピーしてきて参照できるようにする必要があります。


***
参考文献
http://d.hatena.ne.jp/shinriyo/20130814/p4
認識困難な色の組合せを、最小の変換で改善する

# なにこれ
[この論文](http://ci.nii.ac.jp/naid/110006250173/)の状況を参考にして、下記の問題を[組合せ最適化](http://qiita.com/SaitoTsutomu/items/bfbf4c185ed7004b5721)を使って解きます。
(元の論文とは、別の問題です)

# 問題
> 100色 使用されている画像があります。ある人にとっては、赤と緑など、認識困難な色の組合せがいくつかあります。全ての認識困難な色の組合せに対し、色を変換することによって、認識しやすくなるようにしたいとします。なるべく変換する色数を最小化するには、どの色を変換したらいいでしょうか？

#### 前提
- 色は0から99の数字で表される。
- 認識困難な色の組合せは3色からなる。
- 3色のうち少なくとも1色を未使用にすれば、認識困難でなくなる。
- 未使用にされた色は、色番号が1つ隣の色に変更する。
- 色番号が連続するものは、未使用にしない。例えば、33と34を両方とも未使用にはしない。
- 認識困難な色の組合せの数は20とする。

# 問題のパラメータ
ここでは、ランダムに作成します。

```py3:python
import numpy as np
from pulp import *
from itertools import combinations
from ortoolpy import addbinvars
N = 100 # 色数
np.random.seed(183)
acmb = list(combinations(range(N), 3)) # 全組合せ
# ランダムに20個の組合せを「認識困難な組合せとする」
cmb = [acmb[i] for i in np.random.choice(range(len(acmb)), 20, False)]
print(cmb)
>>>
[(28, 31, 73), (13, 65, 76), (17, 50, 52), (10, 81, 89), (3, 17, 21),
 (3, 12, 92), (4, 23, 24), (12, 24, 39), (9, 16, 31), (38, 78, 99),
 (10, 15, 79), (24, 33, 72), (26, 57, 89), (6, 51, 65), (8, 24, 33),
 (40, 52, 88), (57, 75, 99), (16, 24, 75), (73, 86, 97), (20, 80, 97)]
```
# 定式化して解く
隣り合う色は未使用にしないので、「色XとYを未使用にしたが、Xの変更先がYになる」という状況は起こりません。なので、変更先は気にすることなく、未使用にする色だけ考えれば大丈夫です。

```py3:python
m = LpProblem() # 数理モデル
x = addbinvars(N) # 未使用にする色
m += lpSum(x) # 未使用にする色数の最小化
for i in range(N):
    m += x[i]+x[(i+1)%N] <= 1 # 隣り合う色を同時に未使用にしない
for s in cmb:
    m += lpSum(x[i] for i in s) >= 1 # 組合せ s の中の色を少なくとも1つは未使用にする
m.solve()
print('未使用にする色数 %d -> %d'%(len(np.unique(cmb)),
    int(round(np.vectorize(value)(x).sum()))))
>>>
未使用にする色数 41 -> 9
```
20個の組合せの中で、41個の色が使用されていました。
9個選んで未使用にすることにより、全組合せで認識困難さをなくすことができました。

以上
ぼくのかんがえたさいきょうのアイデア出し練習会


アイデア出し練習の必要性
==========================

「技術が目的」なエンジニアが好きな技術で仕事をしていくためには、その技術を軸としたいいアイデアを出して仕事として成立させる必要がでてくると思います。ただ、ぼくなどのアイデアをだすのに慣れていない人は、練習が必要そうです（例えば、世の中のあるアイデア出しのフレームワークをつかってみる勉強会＋実践？）。


なぜ（好きな）技術を軸とするべきなのか
======================================

「How Google Works」という本に下記のように記載されており、自分の好きな何らかの技術を軸として考えることでいいアイデアになる可能性が高そうです。

- "その後に大成功を収めたグーグルのプロダクトも、ほとんどが強力な技術的アイデアにもとづいていた。逆にあまり成功しなかったプロダクトには、それがなかった。"
- "革新的で成功しているグーグルのプロダクトには、技術系の学術誌に載るような重要な技術的アイデアが少なくとも一つはある。"

また、「How Google Works」の「組み合わせ型イノベーションの時代」では下記のように書かれています。

- "技術的アイデアを生み出す一つの方法は、新たに入手できるようになった技術やデータを活用し、自らの業界にすでに存在する問題に対する新たな解決策を見いだすことだ。"
- "技術的アイデアを見つけるもう一つの方法は、小さな問題の解決策に注目し、その適用範囲を広げる方法を考えることだ。"

「枯れた技術の水平思考」などにも似ていると思います。何らかの技術を軸にしたアイデア出しができたら良さそうです。

アイデア出しの方針・アプローチ
================================

ところで、最近NewsPicksで「特集:濱口秀司のつくり方」みたいなのが流行っていて興味をもって関連する記事や動画を見てみたのですが、下記のような主張だと理解しています。

- 「○○を変えたとき、〜のトレードオフがある」みたいなとき、別の何かと組み合わせて "バイアス" を崩せるといいアイデアがうまれる
  - そのためのやり方にもいろいろある
      - 直観と論理的な思考の中間で考えられる状態でアイデア出しをする
      - アイデアそのものではなく、思いついた理由からさらに深ぼる

例えばUSBメモリは下記のバイアスを崩してうまれたそうです：

- データサイズは今後どんどん増えていきそう
- フロッピーなどの物理メディアは減っていってネットワーク経由でのやり取りが増えていきそう
  - → （これらのバイアスを崩して）データサイズは増えるけれど物理メディアを使うケースがないのか　→ USBメモリ
  - https://vimeo.com/48997854

そもそも濱口氏の「見たこと・聞いたことがない、実行可能である」は特許における新規性・進歩性のことなので、特許発明のフレームワーク（TRIZ、智慧カード、発明原理40など）も参考にできるかもしれません。

アプローチとしては、（前述のHow Google Worksの話とも関連させて）下記のアプローチができそうです。

- 課題ベース
  - 既存のサービスには〜のトレードオフがあるが、〜の技術と組み合わせるとバイアスを崩せそう。

- 技術ベース
  - 〜の技術では〜のトレードオフがあるが、〜と組み合わせることで〜の効果があるサービスを生み出せそう。

上記のような方針・アプローチができるのではないでしょうか。
Ruby 引数の順番への依存を取り除く方法

クラスの初期化時に引数を渡す順番を固定しないようにする方法でなるほどなーと思ったので共有してみます。(レベルとしては初歩中の初歩)

# 引数への順番の依存
順番に依存する場合の例

```ruby:dependency.rb
Class Hoge
  attr_reader :foo, :bar, :fuga

  def initialize(foo, bar, fuga)
    @foo  = foo
    @bar  = bar
    @fuga = fuga
  end
  ...
end

#インスタンス生成時の引数を渡す順番が固定されている
Hoge.new(foo, bar, fuga)
```


#対応策
固定されたパラメーターの代わりにハッシュを受け取るようにする

```ruby:not_dependency.rb
Class Hoge
  attr_reader :foo, :bar, :fuga

  def initialize(args)
    @foo  = args[:foo]
    @bar  = args[:bar]
    @fuga = args[:fuga]
  end
  ...
end

#インスタンス生成時の引数を渡す順番はなんでもOK
Hoge.new(foo: foo, bar: bar, fuga: fuga)
```

###追記(2017/08/02)
Ruby2.0からはキーワード引数が導入されたため、以下のように記述することができます。

キーワード引数を使う

```ruby:not_dependency_2.0.rb
Class Hoge
  attr_reader :foo, :bar, :fuga

  #Ruby2.1からデフォルト値は省略可能
  def initialize(foo:, bar:, fuga:)
    @foo  = foo
    @bar  = bar
    @fuga = fuga
  end
  ...
end

#インスタンス生成時の引数を渡す順番はなんでもOK
Hoge.new(foo: foo, bar: bar, fuga: fuga)
```

さらに、キーワード引数を使用することで、

- （デフォルト値がなければ）必要な引数がないときにエラーになる
-  間違った引数を渡したときにエラーになる

ため必要な引数が過不足なく渡ることが保証できるそうです。

#まとめ
引数の順番をいちいち意識しなくていいのは便利。
引数が多い場合は使ってみると良いかも。

#参考書籍
オブジェクト指向設計実践ガイド(技術評論社)
AWS Amazon LinuxにMySQL5.7をインストール

### 前回の続き
サーバーはAWSのAmazon Linuxを利用。
php7.1 / nginx(fast CGI)
http://qiita.com/namixc/items/17c3617f247057d911cb

###  MySQLのインストール
Jsonが扱えるバージョン5.7を入れる。

```
sudo yum -y install http://dev.mysql.com/get/mysql57-community-release-el6-7.noarch.rpm`
sudo yum -y install mysql-community-server
```

バージョン確認

```
mysql --version
mysql  Ver 14.14 Distrib 5.7.19, for Linux (x86_64) using  EditLine wrapper
```

自動起動の設定
`sudo chkconfig mysqld on`

### MySQLを起動

```
$ sudo service mysqld start
Initializing MySQL database:                               [  OK  ]
Starting mysqld:                                           [  OK  ]
```

root@localhostのパスワードがログファイルの中にあるので確認する。

```Bash:/var/log/mysqld.log
[Note] A temporary password is generated for root@localhost: [これ]
```

パスワードを使ってMySQLにログインする。
初期のパスワードを変更しないとエラーが出続けるのでパスワードを変更しておく。
* 「8文字以上、英字・数字・記号をそれぞれ1つ以上含む」というかなり強固なパスワードを要求されるので注意

```
$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.7.19

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> ALTER USER root@localhost IDENTIFIED BY '新パスワード';
```

### my.cnfの編集

```Bash:/etc/my.cnf
character-set-server = utf8 #追加
```

### MySQL再起動
`sudo service mysqld restart`
FlowPlayer+hls.jsでfragLoopLoadingError

最近動画再生プレイヤーとして、
OSSの[FlowPlayer](https://flowplayer.com/)と[hls.js](https://github.com/flowplayer/flowplayer-hlsjs)を使っているのですが、
ちょっとハマったところがあったので備忘録兼、理解を深めるために記載。 

#概要
・FlowPlayer+hls.jsでのHLSのライブ動画配信で動画再生に失敗
・hls.jsのエラーとして以下が発生
>[warn] > level controller,fragLoopLoadingError on live stream, discard
>[warn] > mediaController: fragLoopLoadingError while loading frag,switch to IDLE state ...

tsファイルを取得する際に最初のtsファイルを取得後、
もう１度同じtsファイルをループして取得する事象が発生

#原因
・githubのissueから以下の記事を発見 ＃Githubに非常に感謝
[Infinite Frag Loop Loading Error on Live Stream](https://github.com/video-dev/hls.js/issues/272/)

>[log] > parsed video,PTS:[2.345,10.385],DTS:[2.145/10.225],nb:97
>[log] > parsed audio,PTS:[0.000,10.124],DTS:[0.000/10.124],nb:436

| 用語 | 説明 | 
|:-:|:-:|
|PTS (presentation time stamp)| PTSはいつ再生（表示）するのかを示したタイムスタンプのこと。再生開始後2秒の時点で表示しろとかそういうタイムスタンプ| 
|DTS(decoding time stamp)|DTSはいつデコードするのかを示したタイムスタンプのこと。再生開始後1秒の時点でデコードしろとかそういうタイムスタンプ| 
|nb|???|

例では、キーフレームがフラグメントの開始から2.345秒後に始まるため、
最初のキーフレームより前のtsファイルはドロップされるようである。
この差分により、最初のtsファイルのロードに失敗し、再度最初のtsファイルのリロードにより、
hls.jsのロジックを混乱させて、fragLoopLoadingErrorで動画再生に失敗する。

#解決方法
映像のキーフレーム間隔をTS秒数と合わせることで解決
HLSでの映像配信を行う際には、キーフレーム間隔をtsファイルの秒数と合わせることが非常に重要。
ABRを行う場合でも、キーフレーム間隔を合わせないと映像再生に失敗する場合もある。

映像技術は調べても解決方法が見つからないことが多いので、自分で技術ノウハウを蓄積すること。
あと、Githubのissueはしっかりと見るようにすること。

＃殴り書きなのであとで内容直します。
Arduino codeでipadからスケッチをコンパイルするさいのシステム構成。

iPadとarduinoだけでできそうに見えるので、実際に試してみたらこうでしたという図を残します。
結論から言うとPCが必須です。

![IMG_0611.PNG](https://qiita-image-store.s3.amazonaws.com/0/8538/722d000e-acbe-6d47-5bab-997fba10c723.png)
静的サイトジェネレーター Gatsby.js のプラグインを使い WordPress JSON REST API をデータ取得元としたサイト構築を試す [1]

# はじめに
Webサイト構築の手段として、WordPressのようなCMSが定番ですが、最近は静的サイトジェネレーターを利用したサイトも増えて来ています。
開発者やデザイナが運営するサイトを除けば、まだまだ一般に普及しているとは言い難いですが、静的サイトジェネレーター単独の記事やWordPressとの比較はよく見かけるようになりました。

今回は静的サイトジェネレーターの１つである Gatsby.js を調査していたところ、プラグインに gatsby-source-wordpress というものがあり、WordPress JSON REST API をデータ取得元とできることを知り、公式のサンプルをベースにGithubPageへの公開まで試してみることにしました。

あくまでAPIによる連携程度でWordPressの置き換えには至らないとは思いますが、比較ではなく連携という点で興味深く、まだ日本語記事もほとんど見つからなかったのでQiitaで記事にしてみました。

また、WordPressではReactを利用したテーマがあまりないですが、Gatsbyは標準でReactを利用してページ作成するのでReactユーザーがWordPressを使ったシステムを構築しようとする際の選択肢になるかもしれません。

なお Gatsby.js 自体についての詳細は本記事では省きますが、静的サイトジェネレーターとしては比較的シェアがあり、Node.js、Reactを利用している点などが特徴で、興味がある方は[公式サイト](https://www.gatsbyjs.org/)など参考にしていただければと思います。

# 1. Gatsby.jsのインストール

公式[Get started](https://www.gatsbyjs.org/docs/)の通り


> npm install -g gatsby


ここで[Get started](https://www.gatsbyjs.org/docs/)を進めチュートリアルまで読んでおくとより理解しやすいと思います。

# 2. ローカル環境でGatsby.js の example の using-wordpress を起動してみる

[using-wordpress](https://github.com/gatsbyjs/gatsby/tree/master/examples/using-wordpress)をダウンロードしてまずはサンプルをそのまま利用してみます。

> cd /path/to/using-wordpress
> npm install
> npm run develop

http://localhost:8000

でサンプルが確認できます。
ただしデータ取得元はサンプルとして用意された他人のWordPressなのでこれを自分のWordPressに置き換える必要があります。

![Screen Shot 2017-07-31 at 15.20.00-fullpage.png](https://qiita-image-store.s3.amazonaws.com/0/144303/1d065546-8c28-cf65-3a01-a318b099234f.png)

# 3. 自前のWordPress(wordpress.com)と連携させる

## 接続先のWordPress変更

gatsby-config.js の以下を編集します。
URLは新規作成した直後のWordPressのURLを指定してみます。

``` javascript:gatsby-config.js
baseUrl: 'gatsbyjsexamplewordpress.wordpress.com',

```

変更後gatsbyを起動します。

> npm run develop


するとブラウザに下記のようなエラーが表示されます。

> TypeError: this.props.data is undefined
> 
> render
> webpack:///src/pages/index.js:14

> (以下略)

コンソールにも色々メッセージが出ていますが、下記に注目します。

> Unknown field `tags` on type `wordpress__POST`

これですがサンプルコードが必要としているレスポンスが取得出来ないことが原因でした。
接続先に指定したWordPressの更新を行います。

## tagの作成

既存投稿に新規タグを作成して追加しました。

## サンプルが指定した固定ページが存在しない

上記エラーが解消すると以下のメッセージが表示されました。

> TypeError: currentPage is null
> 
> render
> webpack:///src/pages/index.js:30

pages/index.jsのコードを追って見ると

> this.props.data.wordpressPage

の値が取れていないことが原因のようです。

そこからGraphQLのクエリ

``` javascript:pages/index.js
// Set here the ID of the home page.
export const pageQuery = graphql`
  query homePageQuery {
    wordpressPage(id: { eq: "PAGE_5" }) {
```

にたどり着き、特定のIDの固定ページが存在しないことが原因と判明しました。
サンプルではここに指定したIDの固定ページがホームに指定されています。

> https://public-api.wordpress.com/wp/v2/sites/dummy.wordpress.com/pages

API(URLはダミーなのでご自身のWordPressで置き換えてください)から存在する固定ページのIDを確認し、上記GraphQLのクエリを修正します。

``` javascript:pages/index.js
// Set here the ID of the home page.
export const pageQuery = graphql`
  query homePageQuery {
    wordpressPage(id: { eq: "PAGE_2" }) {
```

これで自前のWordPressへの置き換えが出来ました。

![Screen Shot 2017-07-31 at 16.30.35-fullpage.png](https://qiita-image-store.s3.amazonaws.com/0/144303/ea6d1f39-c4b2-c9e1-ff0c-6514570c8fdf.png)

# 最後に

少し長くなったので今回はここまでにして、続きとしては

- 自前でインストールしたWordPressへの置き換え
- htaccess制限したWordPressへの接続
- レイアウトのカスタマイズや機能追加
- Githubページへのデプロイ

などを予定しています。
Filtering Unwanted  Messages with Identity Lookup 

![スクリーンショット 2017-07-31 16.08.42.png](https://qiita-image-store.s3.amazonaws.com/0/192913/cae76427-c636-db3a-7da2-016bc42745b9.png)

#機能
- 迷惑の内容をフィルタリング
- フィッシング詐欺をフィルタリング
- キャリア経由（SMS,MMSのみ）
- 専門的の知識を適応可能（AIなど）

#Message Filter extensions
##Message Filter extensions(Offline)
- New app extension point
- Part of Identity Lookup framework, new in iOS 11 
- Must be enabled by user in Messages settings 
- One extension enabled at a time
- Invoked for each SMS from an unknown sender
![スクリーンショット 2017-07-31 16.20.45.png](https://qiita-image-store.s3.amazonaws.com/0/192913/e932145e-dbe2-7439-da8f-5ab90c849d34.png)

##Message Filter extensions(Offline)の注意事項
- 受信者の電話番号をextensionに渡さないこと、送信者情報のみを渡す 
- extensionの制限
    - 連絡先アプリのシェアファイルに書き込みしないこと 
    - 通信しないこと
- Do not export messages outside extension’s container

##メッセージの基準(Requirements for messages to be sent to extension)
- SMS and MMS only
- Never iMessage
- Only unknown senders (not in recipient’s Contacts)
- After multiple responses
 - Stops sending to extension
 - Junk threads promoted to non-junk

##Message Filter extensions(Offline)の実装例
![スクリーンショット 2017-07-31 16.36.34.png](https://qiita-image-store.s3.amazonaws.com/0/192913/d6de50ec-d97e-5229-4931-da90bf1996f7.png)

#Network Deferral
##Message Filter extensions(With network deferral)
![スクリーンショット 2017-07-31 16.39.03.png](https://qiita-image-store.s3.amazonaws.com/0/192913/290e2298-8e80-e056-dc82-faecd10b1bf1.png)

##Network Deferralの制限
- ユーザーを特定するデータを送信しないこと
- extension’s Info.plistにURLを指定する必要
- HTTPS required, no App Transport Security (ATS) overrides
- Extension’s app must use Associated Domains (apple-app-site-association)
![スクリーンショット 2017-07-31 16.42.02.png](https://qiita-image-store.s3.amazonaws.com/0/192913/016402c9-870d-7521-fe41-69b98e97ea80.png)

##Network Request and Response Formats
- Network request uses JSON and includes
- Message sender (phone number or email) Message body
- Version of app (CFBundleVersion)
- Version of the JSON request format (currently 1)
- Response format is up to your app to define

```
// Example of Network HTTP Request Sent to Server

POST /server-url-path HTTP/1.1
Accept: */*
Content-Type: application/json; charset=utf-8 Content-Length: 148

{ "_version": 1, "query": {
"sender": "14085550001", "message": {
"text": "This is a message" }
}, "app": {
"version": "1.1" }
}
```

##Network Deferralの実装例
![スクリーンショット 2017-07-31 16.48.06.png](https://qiita-image-store.s3.amazonaws.com/0/192913/4a978bc4-4700-2854-0e28-88dacc950449.png)

#参考資料
https://developer.apple.com/videos/play/wwdc2017/249/