OmniAICreator/Qiita-1.07M huggingface dataset:
iOSを外注するときにこれだけは統一してもらいたい8個のポイント


社内のiOS開発のリソースが足りないときにアプリを出したいことはあるはず。コード規約を渡しても読んでもらうのは難しい。
そういう時に、コードが全く無駄にならないためにこれだけは守っておいてもらう。

### 必ず統一してもらうもの
1. インデント
- クラスのprefix
- product name, company identifier
- autolayoutの使用の有無
- cocoapodの使用
- ライブラリの指定
- storyboardの使用の有無
- ディレクトリ構成

### 例えばこんな感じで

- インデントの設定はspaceで4つ
- クラスのprefixは``WTD``で
- company identifierは、``com.wantedly``で
- AFNetworkingは必ず使ってもらいたい
- autolayoutは使ってもらいたい
- cocoapodを使ってもらいたい
- SDWebImageとRestKitも使って欲しい
- 他迷ったときは既存プロジェクトと同じライブラリを使って欲しい
 * RNCryptor
 * UICKeyChainStore
 * SVProgressHUD
 * TTTAttributedLabel
 * NUI
- できればstoryboardも使ってもらいたい
- ディレクトリ構成

```
.
+-- Classes
|   +-- WTDAppDelegate.h
|   +-- WTDAppDelegate.m
|   +-- WTDConstants.m
|   +-- Extensions
|   +-- Controllers
|   +-- Models
|   +-- Views
+-- Resources
|   +-- Stylesheets
|   +-- Storyboards
|   +-- IB Files
|   +-- Locales
|   +-- Images.xcassets
+-- Supporting Files
```


### メモ
* インデントやクラスのprefixは、確認しておいたほうがよい。完全に動いていても他のプロジェクトと統一できてないと直すのがつらい。
* ライブラリも、なるべく慣れたものがある場合は指定するほうがいい。あとでデバッグに時間かかるし、他のプロジェクトで問題が解決した問題を共有できる。
Windows+ccl+Clack

思い立って[Clack](http://dev.ariel-networks.com/wp/archives/365)
をインストールしてみた。
ちょっとだけ詰まったのでメモする。


どうもSLIME上で以下のエラーが出る。

> Unable to load foreign library (LIBSSL).
>   Error opening shared library libssl32.dll : %1 は有効な Win32 アプリケーションではありません。 .
>    [Condition of type CFFI:LOAD-FOREIGN-LIBRARY-ERROR]

よくよく考えてみたら、emacsのinit.elで、

```el:init.el
 (setq inferior-lisp-program "C:\\usr\\ccl\\wx86cl64")
```

って64bit版cclを指定しているせいだった。
当たり前だけど、32bit版cclで32bit版のlibssl32.dllを使用する分には問題ない。

cl-gtk2-gtkも、wx86cl64.exeを使用すると、同様のエラーが出て失敗だった
gtk2はdllを32bitにしたら、エラーは起きなくなった。
が、No Value;って出て、Windowが表示されない・・・。


それにしても、Common LispでWebアプリなんて楽しいですね。
ずっとJVM上の言語ばっかりだったから、開放感がある。
ipaファイル生成とDeployGateへのアップロードをXcode上で自動化する


こちらの記事を参考にさせていただきました。
「[.ipa ファイル生成を自動化する](http://qiita.com/shu223/items/5bfba10e642b453e6d30)」

Run Scriptを利用して、XCode上でCommand+Bを押した時に
1. ビルド
2. ipaファイル生成
3. DeployGateへアップロード・テスターへ配信 
までを自動で行います。

開発中のiOSアプリを同じテスターへ繰り返し配信したいなどの理由で利用しています。
基本的には、shu223さんのスクリプトへDeployGateのAPIを一行追加しただけで出来ました。簡単。

## 準備
※ 以下を進めるにはDeployGateのアカウントとAdHoc配布用のProvisioning Profileが必要ですが、それらの作り方については説明を省略します。[こちらの記事](http://qiita.com/k_kinukawa/items/bbb3e98239e51fc3c803)を参考にしてください。

### 1. DeployGate用のSchemeを追加する

Configurationを複製して、配布用のものを追加します。

![1.png](https://qiita-image-store.s3.amazonaws.com/0/29477/5519299f-ce8c-7ad7-323f-65da3746e845.png "1.png")

![3.png](https://qiita-image-store.s3.amazonaws.com/0/29477/a16052ed-03b4-6ebd-2e18-c036d36aff06.png "3.png")

配布用のSchemeを追加します。DeployGateへアップロードするときにはこいつを選択した状態でビルドします。

![2.png](https://qiita-image-store.s3.amazonaws.com/0/29477/bfca5707-b8d0-f691-0e53-76e6a2b2174a.png "2.png")


配布用SchemeのBuild Configurationを、先ほど作成したConfigurationにします。
![5.png](https://qiita-image-store.s3.amazonaws.com/0/29477/b5f975a2-6c32-814f-3551-7b616e52e7b6.png "5.png")
![Screen Shot 2014-02-27 at 17.19.10.png](https://qiita-image-store.s3.amazonaws.com/0/29477/6b7ea93b-4e90-d2fb-a286-95da9a84c5b5.png "Screen Shot 2014-02-27 at 17.19.10.png")


配布用Schemeの設定が追加されました。このスキームでビルドした時に、ipaファイルがDeployGateへアップロードされるようにします。


### 2. ipa作成・DeployGateアップロードのRun Scriptを書く

まずTargetのBuild Phaseタブへ移動します。
Add Build Phase > Add Run Script Build Phase
でRunScriptを追加します。
![Screen Shot 2014-02-27 at 16.26.43.png](https://qiita-image-store.s3.amazonaws.com/0/29477/b8b13513-decb-838b-ced7-cc982a2fa4e3.png "Screen Shot 2014-02-27 at 16.26.43.png")


追加されたRun Scriptのテキストエリアへ、以下のようなスクリプトを入力してください。

```bash:RunScript
if [ "${CONFIGURATION}" = "Adhoc" ]; then
  xcrun -sdk iphoneos PackageApplication \
    "${BUILD_DIR}/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}/${WRAPPER_NAME}" \
    -o <出力するipaファイルのパス> \
    --embed ~/Library/MobileDevice/Provisioning\ Profiles/<プロファイルのファイル名>
  curl "https://deploygate.com/api/users/<ユーザー名>/apps" \
    -F "file=@<ipaファイルパス>" \
    -F "token=<DeployGateのAPIトークン>"
fi
```
CONFIGURATIONには先ほど作成した"Adhoc"を指定します。
SchemeのConfigurationが"Adhoc"の場合に、ipaファイルの作成とDeployGateへの配信を行います。
xcrunコマンドの<プロファイルのファイル名>には、作成したプロビジョニングプロファイルを指定してください。
DeployGate APIの詳細は[こちら](https://deploygate.com/docs/api)を御覧ください。

## 実行

SchemeにAdhocを選択した状態でcommand+Bを押すと、作ったコードをipaファイルにしてDeployGateへアップロードしてくれます。


## 関連記事

ブラウザからDeployGateへアップロードしたい

+ [DeployGateでiOSアプリを配布する方法](http://qiita.com/k_kinukawa/items/bbb3e98239e51fc3c803)

JenkinsからビルドしてDeployGateへアップロードしたい

+ [deploygate for iOS に Jenkinsからアップロードする](http://qiita.com/ginrou@github/items/498d02acbbe9e1327bb7)

コマンドラインからビルドしてDeployGateへアップロードしたい

+ [iPhoneアプリをmakeコマンド一発でビルドしてDeployGateで自動配布する方法](http://qiita.com/k_kinukawa/items/42c240a9e9e8b6cb4923)
パッケージ管理ツールのlockファイルをバージョン管理すべき理由


Rubygemsを始めとして最近ではどの言語にも便利なパッケージ管理ツールが使えるようになった。多くのパッケージツールはインストールしたパッケージを記載した``Gemfile.lock`` のようなlockファイルを作る。

``Gemfile.lock`` を消したら動いた、結果オーライみたいなことをウェブで見かけたりして、lockファイルをバージョン管理から外すべきという話があったりする。これはRubygemsに限ったことでなくCocoaPodsの ``Podfile.lock`` などでも結構混乱している人が多いような気がしたのでこれを書いておこうと思った。

lockファイルを管理すべきかどうかはもちろんそのチームの運用による。特に理由がなければアプリケーション開発においては基本的にはバージョン管理し、チームメンバーで共有したほうがよい。

## メンバーが同じ環境を構築するため

bundlerであれば ``Gemfile.lock`` があれば ``Gemfile.lock`` ファイルにあるパッケージのバージョンをインストールする。なければ ``Gemfile`` ファイルに従いパッケージをインストールする。

これで何が変わるか？

もし ``Gemfile`` に ``gem 'rails'`` とだけ記載されていた場合 **インストールを実行した時点の最新の安定バージョンがインストールされる**。つまり **lockファイルがないと実行したタイミングでパッケージのバージョンが変わる** ということになる。後から実行するばするほど新しいものが入る。

例えば ``Gemfile.lock`` ファイルがなく``Gemfile`` にrailsのバージョンが記載されていないならそれがrails3のアプリケーションでもrails4など新しいバージョンがインストールされてしまう。

つまりlockファイルがないと後からチームに加わった人、マシンの買い替えで新しくセットアップしたとき、時間が経ってから昔のプロジェクトをセットアップしたとき、といったケースで新しいパッケージのバージョンがインストールされてしまい、環境によって動作が異なったり、パッケージのi/fが変わった場合は最悪プログラムが動かなくなる。

他のメンバーや自分があとで同じ環境を構築するためにlockファイルは共有しなければならない。

### 運用環境と同一にするため

メンバーの環境だけではなく、サーバーアプリケーションでは運用サーバ、クライアントアプリケーションではビルドマシンでも同様にlockファイルは共有すべきである。これらと同じ環境を構築しておかないと自分の環境では起きないのに運用サーバでは起きる、リリースしたビルドバージョンでは起きるという状態になりかねない。

## 旧バージョンを実行するため

lockファイルを管理する目的は他にもある。アプリケーションの旧バージョンを実行したいとき。

例えばiOSアプリの2.0を進めているときに致命的な問題で1.1をリリースしなければならなくなったとする。このとき1.0のタグから修正を行おうとするが、 ``Podfile.lock``  をバージョン管理していなければその1.0の時点で利用していた依存パッケージのバージョンがわからないので **アプリの旧バージョンと同じ実行環境を構築できない** という問題が発生する。

最新バージョンの依存パッケージで動けばより改善されたアップデートを作れるかもしれないが、それはあくまで結果オーライであってこういった前回のビルドから何が変わったのかわからない予測不能な状態は避けなければならない。

旧バージョンの実行環境を構築するためにlockファイルはバージョン管理しなければならない。

## 明示的にバージョンを記載する

lockファイルだけでなく、明示的に ``Gemfile`` や ``Podfile`` にはパッケージのバージョンを明示的に記載しておくのも有効である。lockファイルではあくまで結果的に使うバージョンという意味が強いが ``Gemfile`` や ``Podfile`` に記載すればこのパッケージのこのバージョンを使うというより強い意図を表現できる。

プロトタイプや１人で開発する分には ``>= x.x.x`` といた書き方でも良いと思うが、重要な依存ライブラリについては明示的にバージョンを固定しておき、そのパッケージの更新履歴を確認した上で新しいバージョンに更新するような運用が望ましいと思われる。

## まとめ

開発者の環境をなるべく同一にするため、旧バージョンの実行のためlockファイルはバージョン管理すべきファイルである。

lockファイルを共有せず多少パッケージのバージョンが異なってもなんとなく動いてしまうのが怖いところ。時間が経つにつれ差分が大きくなる性質から問題があとになって顕在化してしまう。

lockファイルを管理しない方が良いケースももちろんあるのだが、 **動きを理解しないまま自分の環境でlockファイルがなくても動いたので管理しない** というやり方だと後で困るよいうだけの話。

今回はRubyGemsやCocoaPodsを例に挙げたが、多くのパッケージ管理ツールがlockファイルを作成し、同じ運用を用いることから同様のことが言えると思う。
Google Analyticsの情報をAPI経由で取得するスクリプト。

メモ

Google Analytics から情報を引っ張ってくるスクリプト。初回はブラウザで認証して、以降はファイルに保存した認証情報を使用する。

Google consoleなどの手順は

http://blog.naberon.jp/post/2013/08/25/google-analytics-api/

の通りにやってできました。

```ruby:analytics.rb
#!/usr/bin/env ruby
# coding : utf-8

# 参考
# https://github.com/google/google-api-ruby-client
# https://github.com/google/google-api-ruby-client-samples/tree/master/adsense
# https://developers.google.com/api-client-library/ruby/guide/aaa_oauth
# http://blog.naberon.jp/post/2013/08/25/google-analytics-api/

# こっちのモジュールも良さそう
# http://tsuchikazu.net/googel_analytics_gar/

require 'pp'
require 'json'
require 'pry'

require 'google/api_client'
require 'google/api_client/client_secrets'
require 'google/api_client/auth/installed_app'
require 'google/api_client/auth/file_storage'

CREDENTIAL_STORE_FILE = "#{$0}-oauth2.json"

# Analytics profile ID.
# https://www.google.com/analytics/web/#home/a42353636w43552078pXXXXXXXX/
# なURLのpのあと数字がProfile ID
profileID = 'XXXXXXXX'

client = Google::APIClient.new(
  :application_name => 'TestProject',
  :application_version => '0.0.1'
)

analytics = client.discovered_api('analytics', 'v3')

authfile = Google::APIClient::FileStorage.new(CREDENTIAL_STORE_FILE)

unless authfile.authorization.nil?
  client.authorization = authfile.authorization
else
  # ここでDLしたJSONを読み込んでいるので同じディレクトリにclient_secrets.jsonを置いておくこと
  client_secrets = Google::APIClient::ClientSecrets.load

  flow = Google::APIClient::InstalledAppFlow.new(
    :client_id     => client_secrets.client_id,
    :client_secret => client_secrets.client_secret,
    :scope         => ['https://www.googleapis.com/auth/analytics.readonly']
  )

  client.authorization = flow.authorize
  authfile.write_credentials(client.authorization.dup) # 認証情報をファイルに保存
end

startDate = DateTime.now.prev_month.strftime("%Y-%m-%d")
endDate   = DateTime.now.strftime("%Y-%m-%d")

result = client.execute(
  :api_method => analytics.data.ga.get,
  :parameters => {
    'ids'        => "ga:" + profileID,
    'start-date' => startDate,
    'end-date'   => endDate,
    'metrics'    => 'ga:visitors,ga:visits,ga:pageviews',
    'dimensions' => 'ga:pagePath,ga:pageTitle',
    'sort'       => '-ga:pageviews'
  }
)

body = JSON.parse(result.response.body)
body['rows'].each do |row|
  pp row
end
```
AndroidおよびiOSでWebApp化するためのメタタグ・リンクなど

```html
<!-- WebAppモード -->
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<!-- アイコン -->
<link rel="shortcut icon" sizes="196x196" href="icon-196x196.png">
<link rel="apple-touch-icon" href="apple-touch-icon.png" />
```

```js
//フルスクリーン
navigator.standalone = navigator.standalone || (screen.height-document.documentElement.clientHeight<40)
```

参考：
[Home screen web apps for Android thanks to Chrome 31+ | Breaking the Mobile Web]
(http://www.mobilexweb.com/blog/home-screen-web-apps-android-chrome-31)
[Add to Homescreen - Google Chrome Mobile — Google Developers]
(https://developers.google.com/chrome/mobile/docs/installtohomescreen?hl=ja)
[Chrome Beta for Android has full screen browsing very well hidden]
(http://phandroid.com/2013/01/26/chrome-beta-full-screen/)
[APIに新機能追加：Google、「Chrome 31」のβ版公開 - ＠IT] (http://www.atmarkit.co.jp/ait/articles/1310/04/news103.html)
iOS で広告識別子 ASIdentifierManager.advertisingIdentifier を使っていないか調べる方法

最近は iOS アプリ審査で広告を使っていないのに ASIdentifierManager.advertisingIdentifier を用いていると審査に落ちたりします。

自分たちは使っていないことを認識していても、サードパーティ製のライブラリが使っていたりすると大変。
審査提出前に簡単に確認するなら次のようなコマンドでできます。

```
nm -u libThirdParty.a | grep ASIdentifierManager
```

grep でヒットしたら危険なのでサードパーティに問い合わせておきましょう。
nmコマンドでオブジェクトからシンボルのリストを表示

nmコマンドを使うとオブジェクトからシンボルを表示させることができて便利です。

たとえば、

```hello.c
#include <stdio.h>

int a;
static int b;

void
hello(void) {
    static int c;
    c = 3;
    int d = a + b + c;
    printf("Hello %d\n", a);
}

int
main(void) {
    a = 1;
    b = 2;
    hello();
    return 0;
}
```

をコンパイルしてシンボルを表示させてみます。

```shell-session
$ gcc -c hello.c
$ nm hello.o
```

結果は以下のようになります。

```
0000000000000004 C a
0000000000000000 b b
0000000000000004 b c.2046
0000000000000000 T hello
0000000000000047 T main
                 U printf
```

シンボルの型とシンボル名が表示されています。
シンボルの方は大文字がグローバル、小文字がローカルです。
bはデータセクションにあり、 Tはコードセクションにあることを表しています。
chkrootkit 誤検知の対応方法


##経緯
Linuxサーバを管理していて、サーバに導入されているchkrootkitから毎日メールが届く。

```
件名：chkrootkit report in hostname
本文：Checking `bindshell'... INFECTED (PORTS:  番号)
```

調べてみると誤検知しているようだが、常にメールを確認する者としては何とかしたいと思っていた。

##対策(CentOSの場合)
この誤検知は該当ポートを使用しているプロセスを再起動すればよいとの情報を聞いたので、その方法を共有したい。
（注意：再起動してよいプロセスであるか、確認して実施して下さい。）

・サーバにログインして再度確認

```
# chkrootkit | grep INFECTED
Checking `bindshell'... INFECTED (PORTS:  番号)
```

実際に出力されることを確認。

・該当ポートはどのプロセスが利用しているか確認。

```
# lsof -i -P | grep 番号
# netstat -anp | grep 番号
```

・実行されているプロセス名で再起動できるか確認

```
# ls /etc/init.d/
```

① そのプロセス名がある場合

```
# /etc/init.d/プロセス名 restart
# chkrootkit | grep INFECTED
```

出力されないことを確認。

② そのプロセス名がない場合

```
# /bin/grep プロセス名 /etc/init.d/*
```

/etc/init.d/プロセス名 と再起動するプロセスが表示される。

```
# /etc/init.d/プロセス名 restart
# chkrootkit | grep INFECTED
```

これで出力されず、メールも届かなくなると思います。
「Sublime Text 2で全角スペースをハイライト表示するプラグインを作る」で、ハイライトとアウトラインできるようにしてみた


[全角スペースをハイライト表示するプラグイン](http://qiita.com/kuronekomichael/items/865e1a6605b1146d4341)を弄らせて頂きました。

## 変更点
[参考サイト](http://qiita.com/kuronekomichael/items/865e1a6605b1146d4341)では、パターンにマッチしている部分をアウトラインする
だけだったので、ちょっと改造して、アウトラインとハイライト両方できるようにしました。

### ソース

```python:AlwaysHighlight.py
#!/usr/bin/python
# -*- coding: utf8 -*-
import sublime
import sublime_plugin

class AlwaysHihghlight(sublime_plugin.EventListener):
    # highlight
    def highlight(self, view):
        pattern = view.settings().get('alwayshighlight_pattern')
        if pattern:
            view.add_regions('AlwaysHighlight_Highlight',view.find_all(pattern), "invalid", sublime.DRAW_EMPTY)
    # outline
    def outline(self, view):
        pattern = view.settings().get('alwayshighlight_outline_pattern')
        if pattern:
            view.add_regions('AlwaysHighlight_Outline',view.find_all(pattern), "invalid", sublime.DRAW_OUTLINED)

    def update(self,view):
        if view.settings().get('enable_alwayshighlight') == True:
            self.highlight(view)
            self.outline(view)
        else:
            view.erase_regions('highlight')

    # Called after changes have been made to a view.
    # @override
    def on_modified(self, view):
        self.update(view)

    # Called when a view gains input focus.
    # @override
    def on_activated(self, view):
        self.update(view)

    # Called when the file is finished loading.
    # @override
    def on_load(self, view):
        self.update(view)
```

### 設定

```Preferences.sublime-settings
    // パッケージの有効化
    "enable_alwayshighlight": true,

    // ハイライトしたい文字パターンを設定
   "alwayshighlight_pattern": "[｛｝「」￥＝”’＋＠：；・＿ー　０-９Ａ-Ｚａ-ｚ]",

    // アウトラインしたい文字パターンを設定
    "alwayshighlight_outline_pattern": "[\n\t\r\n]",
```

以上です。

参考にさせていただきました m(_ _)m

- [Sublime Text 2で全角スペースをハイライト表示するプラグインを作る](http://qiita.com/WelinaNana/items/47742a4fee048f5156ab)
- [「Sublime Text 2で全角スペースをハイライト表示するプラグインを作る」コメント欄のTipsをマージしてみた。](http://qiita.com/WelinaNana/items/47742a4fee048f5156ab)
絶対ハマる、不思議なnil

goのnilは直感的ではない、これは強烈にハマりそう。

# 型を持つnil
nilと一口に書くが、実際には型がある。

## nilとnilが等価でないように見える
nilが型情報を持つので、nil == nilがtrueになるとは限らない。
trueとなるためには、右辺と左辺の「nil」の型が一致しているという条件が必要。

```go
package main

func main() {
        var x *int32 = nil
        var y *int64 = nil

        equals(x, y)
        return
}

func equals(x, y interface{}) {
        println(x == y)
}
```

```output
> false
```

より凶悪なのが以下のようなパターンで、equals()内ではxがinterface{}として扱われているので、ここでnilを書くと左辺もinterface{}型のnilとして扱われる。
型が一致しないため、この結果もfalseとなる。

```go
package main

func main() {
        var x *int32 = nil

        isnil(x)
        return
}

func isnil(x interface{}) {
        println(x == nil)
}
```

```output
> false
```

## nilはキャスト出来る
型があることを実感できる事実として、nilは型キャストすることが出来る。先のコードでfalseとなっていた例も、等価式のnilをキャストしてやればtrueを返せる。

```go
package main

func main() {
        var x *int32 = nil

        isnil(x)
        return
}

func isnil(x interface{}) {
        println(x == (*int32)(nil))
}
```

```output
> true
```

つまり、オブジェクトをinterface{}として扱っている場合、等価演算子のみを用いてもnilであることを確実に知ることはできない。

## 確実に「nil」を検出する
nilを検出するにはreflect.ValueのIsNil()を併用しなければならない。
ただし、reflect.ValueOf(nil)の場合はZeroValueが返却されるのでIsNil()が呼べない。なので、xがnilであるかの検査は先に行わなければならない。
＃ nilの型を意識する話なので補足しておくと、ここでreflect.ValueOf()はinterface{}型を引数として要求する。したがって、(interface{})(nil)の場合にZeroValueが返却される。

簡単に書けば以下のような感じ。
ちなみに、xがstructなどだとIsNil()がpanicになるので、実際には注意しなければいけない。

```go
func isnil(x interface{}) {
        println( (x == nil) || reflect.ValueOf(x).IsNil() )
}
```

# 型かと思う振る舞いをするnil
先のようにnilは型情報を持つが、nilが型そのもののように振舞っているように見えるケースがある。それが型スイッチ構文を使う場合で、以下のようにcaseに型と一緒にnilを含めることが出来る。
このとき、nilのケースにはinterface型のnil(つまりinterface{}(nil))の場合にのみ入る。

```go
package main

func main() {
        var x *int32 = nil

        typeswitch(x)
        return
}

func typeswitch(hoge interface{}) {
        switch hoge.(type) {
        case nil:
                println("hoge is nil")
        case *int32:
                println("hoge is *int32")
        case *int64:
                println("hoge is *int64")
        default:
                println("unknown")
        }
        return
}
```

```
> hoge is *int32
```

「hoge is nil」と出すためには、main()の中で宣言しているxをinterface{}型にしておかなければならない。これは[Language Specification](http://golang.org/ref/spec#Switch_statements)の「Type switches」にわかりやすい説明がある。

# わかりづらい
goは比較的直感的に使える言語だと思うけれど、nilに関しては直感性が無く辛い。言語仕様を読めば、まぁソレっぽい事はちゃんと書いてあるんだけど･･･
また何か面白い挙動を見つけたら追記する。
UnityでAnimationControllerをscriptから指定する

Unityでanimation clipの中のsprite画像を動的に指定したい。

例えば、walkモーションの動きは同じで表示する画像だけ変えたい！
がやり方がわからなかったので、A@walk, B@walkみたいに
animation clipとanimation controllerをそれぞれつくって
animation controllerをscriptで動的に指定できないかやってみた。

用意したもの

```
Resouces/Animations/A.controller
Resouces/Animations/A@walk.anim
Resouces/Animations/B.controller
Resouces/Animations/B@walk.anim
```

script内から下記のようにanimation contollerの指定したら動いた！

```
void Start() {
  animator = GetComponent<Animator>();
  animator.runtimeAnimatorController = (RuntimeAnimatorController)RuntimeAnimatorController.Instantiate(Resources.Load ("path/to/controller_file"));
}
```

コントローラー同じで表示する画像だけ変える方法を見つけたい。。。
Cursor画像もRetina対応したい

`cursor`には`url()`関数で画像を指定することができるが、backgroundと違って`background-size`のようにサイズを指定できないので、そのままではRetina対応できない。

この場合Webkit拡張の`-webkit-image-set()`関数を使えばよい。

```css
cursor: url('/img/cursor.png'), pointer;
cursor: -webkit-image-set(
  url('/img/cursor.png') 1x,
  url('/img/cursor@2x.png') 2x
), pointer;
```

Safari、Chromeは対応している模様。
yumでJenkinsをインストールする

備忘録として

* http://oscasierra.net/2013/05/jenkins-to-redhat/

----

## 環境
* CentOS6.5

## やること
* yumでJenkinsをインストール

### 作業内容
1. yumリポジトリの追加
> $ sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
> $ sudo rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key

1. インストール
> $ sudo yum install jenkins

  * 設定ファイルは /etc/sysconfig/jenkins
Java の外部プロセスが返って来ない場合の対処方法

Java で外部プロセスを起動する際は ProcessBuilder クラスを使いますが、
たまに処理が戻ってこない場合があります。

そんな場合に原因として考えられるのは、標準出力または標準エラー出力にバッファが溜まってしまっているという理由です。


例えば以下のコードの場合、標準エラー出力のバッファがいっぱいになっていた場合は
 __proc.getInputStream()__ から処理が返って来なくなります。
 
```java
String[] cmds = {"./foo.sh"};

ProcessBuilder pb = new ProcessBuilder(cmds);
Process proc = pb.start();

String str;
BufferedReader brstd = new BufferedReader(new InputStreamReader(proc.getInputStream()));
while((str = brstd.readLine()) != null) {
	trace(str);
}
brstd.close();
```

とはいえ、以下のようなコードにすると、今度は標準出力のバッファが溜まってしまった場合に
 __proc.getErrorStream()__ から処理が返って来なくなります。
 
```java
String[] cmds = {"./foo.sh"};

ProcessBuilder pb = new ProcessBuilder(cmds);
Process proc = pb.start();

String str;

BufferedReader brerr = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
while((str = brerr.readLine()) != null) {
	trace(str);
}
brerr.close();

BufferedReader brstd = new BufferedReader(new InputStreamReader(proc.getInputStream()));
while((str = brstd.readLine()) != null) {
	trace(str);
}
brstd.close();
```

標準出力とエラー出力が混ざってもOKという場合であれば、
__redirectErrorStream__ が有効かと思います。

```java
String[] cmds = {"./foo.sh"};

ProcessBuilder pb = new ProcessBuilder(cmds);
Process proc = pb.start();

// 標準出力と標準エラー出力をMIX
pb.redirectErrorStream(true);

String str;
BufferedReader brstd = new BufferedReader(new InputStreamReader(proc.getInputStream()));
while((str = brstd.readLine()) != null) {
	trace(str);
}
brstd.close();
```

これで、 __proc.getInputStream()__ から処理が返って来なくなることはなくなります。

どうしても標準出力と標準エラー出力を分けなければいけない場合は、
片方を別スレッドで処理すればなんとかなります。
（あまり美しくないですが・・・）

```java
String[] cmds = {"./foo.sh"};

ProcessBuilder pb = new ProcessBuilder(cmds);
final Process proc = pb.start();

//エラー出力は別スレッドで吐き出す
Thread th = new Thread(new Runnable() {
	@Override
	public void run() {
		String str;
		BufferedReader brerr = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
		try {
			while((str = brerr.readLine()) != null) {
				trace(str);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				brerr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
});
th.start();

String str;
BufferedReader brstd = new BufferedReader(new InputStreamReader(proc.getInputStream()));
while((str = brstd.readLine()) != null) {
	trace(str);
}
brstd.close();


```
Python:ECDSAのキー生成と署名検証の確認(P-521/SHA-512)


[python-ecdsa](https://github.com/warner/python-ecdsa) を使ってみた

```py
    class TestEcKey(unittest.TestCase):
        def test_generate(self):
            from ecdsa import SigningKey, NIST521p
    
            sk = SigningKey.generate(curve=NIST521p)
            pri = sk.privkey
            pub = pri.public_key
            param = dict(
                crv=sk.curve,
                x=pub.point.x(),
                y=pub.point.y(),
                d=pri.secret_multiplier)
    
            # Curve
            from ecdsa.ellipticcurve import Point, CurveFp
            from ecdsa.ecdsa import curve_521
    
            self.assertTrue(isinstance(curve_521, CurveFp))
            self.assertTrue(isinstance(param['crv'].curve, CurveFp))
            self.assertEqual(curve_521, param['crv'].curve)
            self.assertEqual(pub.point.curve(), curve_521)
    
            # Point
            p_new = Point(curve_521, param['x'], param['y'])
            self.assertEqual(p_new, pub.point)
            self.assertTrue(isinstance(pub.point, Point))
    
            # Public Key
            from ecdsa.ecdsa import Public_key, generator_521
            self.assertEqual(generator_521, pub.generator)
            pub_new = Public_key(generator_521, p_new)
    
            # Private Key
            from ecdsa.ecdsa import Private_key
            pri_new = Private_key(pub_new, param['d'])
    
            # Signature
            from ecdsa.ecdsa import string_to_int, Signature
            from hashlib import sha512
            from uuid import uuid1
            rnd = uuid1().int
            msg = "hello, it's me."
            digest = string_to_int(sha512(msg).digest())
            signature_new = pri_new.sign(digest, rnd)
            signature_old = pri.sign(digest, rnd)
            self.assertTrue(isinstance(signature_new, Signature))
            self.assertEqual(signature_new.r, signature_old.r)
            self.assertEqual(signature_new.s, signature_old.s)
            self.assertEqual(type(signature_new.r), long)
            self.assertEqual(type(signature_new.s), long)
    
            #Verify
            print pub.verifies(digest, signature_new)
            print pub_new.verifies(digest, signature_old)

```
Pythonで半角・全角の変換を高速に行う


Pythonで日本語文字列を高速に半角・全角変換できるライブラリ「[mojimoji](https://github.com/studio-ousia/mojimoji)」を紹介します。

mojimojiは、Pythonでの全角・半角変換を高速に行うことが出来ます。[こちら](http://qiita.com/ikuyamada/items/6b69c0e9b2f8bf337eeb)で紹介した方法を使って、内部的にCython及びC++のunordered_mapを用いて変換処理をしており、従来実装よりかなり高速に動作します。

## インストール


```
% pip install mojimoji
```

## 概要

mojimojiには、han_to_zenとzen_to_hanの二つのメソッドがあります。また、それぞれkana、digit、asciiというキーワード引数を取り、カタカナ、数字、アルファベットの変換をそれぞれ無効化できます。

### 全角から半角への変換

```python
>>> import mojimoji
>>> print mojimoji.zen_to_han(u'アイウａｂｃ０１２')
ｱｲｳabc012
>>> print mojimoji.zen_to_han(u'アイウａｂｃ０１２', kana=False)
アイウabc012
>>> print mojimoji.zen_to_han(u'アイウａｂｃ０１２', digit=False)
ｱｲｳabc０１２
>>> print mojimoji.zen_to_han(u'アイウａｂｃ０１２', ascii=False)
ｱｲｳａｂｃ012
```

### 半角から全角への変換

```python
>>> import mojimoji
>>> print mojimoji.han_to_zen(u'ｱｲｳabc012')
アイウａｂｃ０１２
>>> print mojimoji.han_to_zen(u'ｱｲｳabc012', kana=False)
ｱｲｳａｂｃ０１２
>>> print mojimoji.han_to_zen(u'ｱｲｳabc012', digit=False)
アイウａｂｃ012
>>> print mojimoji.han_to_zen(u'ｱｲｳabc012', ascii=False)
アイウabc０１２
```

### パフォーマンス

同じくPythonで半角・全角を変換するライブラリzenhan及びjctconvと動作速度を比較してみます。

```
% pip install zenhan
% pip install jctconv
```

```python
% ipython
In [1]: import mojimoji
In [2]: import zenhan
In [3]: import jctconv
In [4]: s = u'アイオエオ０１２３４５' * 10
In [5]: %time for n in range(1000000): mojimoji.zen_to_han(s)
CPU times: user 3.90 s, sys: 0.03 s, total: 3.93 s
Wall time: 3.97 s
In [6]: %time for n in range(1000000): zenhan.z2h(s)
CPU times: user 71.05 s, sys: 0.16 s, total: 71.22 s
Wall time: 71.45 s
In [7]: %time for n in range(1000000): jctconv.z2h(s)
CPU times: user 19.75 s, sys: 0.06 s, total: 19.81 s
Wall time: 19.86 s
```

Pure Pythonで実装されたzenhanライブラリと比較して約18倍、jctconvと比較して約5倍、高速に処理できていることが分かります。

### ダウンロード

* ソースコード: https://github.com/studio-ousia/mojimoji
* PyPI: https://pypi.python.org/pypi/mojimoji
nvmで管理するnode.jsの実行ファイルはいずこ？

nvmを使うと簡単にnodejsのバージョン管理が行えます。
がしかしNode Interpreterが通常のインストール場所とは異なるために、
エディターのnode補完機能が使えなくなってしまい、ちょっと焦ったのでメモ。

####(ﾟДﾟ≡ﾟДﾟ)



###通常

```
/usr/local/bin/node
```


###nvm

```
/Users/username/.nvm/v0.10.24/bin/node
```
brew doctor Warning対応

Warning: Unbrewed dylibs were found in /usr/local/lib.

* [Mountain Lion環境へのHomebrew & gitインストール手順 | momoiro](http://blog.pinkpinkpink.net/2012/07/homebrew.html)

```
rm -rf /usr/local/lib/libssl.0.9.8.dylib
```

Warning: Unbrewed .la files were found in /usr/local/lib.

* [Mac OSX に Homebrew をインストールする - asa nisi masa](http://d.hatena.ne.jp/january/20130723/1374538421)

```
rm -rf /usr/local/lib/libosxfuse_i32.la
rm -rf /usr/local/lib/libosxfuse_i64.la
```

Warning: Unbrewed .pc files were found in /usr/local/lib/pkgconfig.

* [Mac OSX に Homebrew をインストールする - asa nisi masa](http://d.hatena.ne.jp/january/20130723/1374538421)

```
rm -rf /usr/local/lib/pkgconfig/osxfuse.pc
```

Warning: You have a non-Homebrew 'pkg-config' in your PATH:

* [MacOSX - パッケージ管理システム Homebrew - Qiita](http://qiita.com/b4b4r07/items/6efebc2f3d1cbbd393fc)

```
sudo mv /opt/local ~/macports
※PCのパスワード入力
```

Warning: Broken symlinks were found. Remove them with `brew prune`:

* [Homebrew導入 エラー 解決法 - Labo Memo](http://alice345.hatenablog.com/entry/2013/08/13/030424)
* [Mac OSX に Homebrew をインストールする - asa nisi masa](http://d.hatena.ne.jp/january/20130723/1374538421)

```
brew prune
```

Warning: Unbrewed dylibs were found in /usr/local/lib.

* [Mac OSX に Homebrew をインストールする - asa nisi masa](http://d.hatena.ne.jp/january/20130723/1374538421)

```
rm -rf /usr/local/lib/libmacfuse_i32.2.dylib
rm -rf /usr/local/lib/libmacfuse_i64.2.dylib
rm -rf /usr/local/lib/libosxfuse_i32.2.dylib
rm -rf /usr/local/lib/libosxfuse_i64.2.dylib
```
pwgenでのパスワード生成と一括変更

現在全サーバ、全ユーザでパスワードがユニークなシステムを担当してます。(他にはない？)
構築後時は簡単なパスワードを設定しているのですが、本番運用前に一気全台に変更します。
Qiita初投降のテストということでお手柔らかなネタ。

* pwgenのインストール

```
sudo yum install -y pwgen
sudo which pwgen
```

* オプションつけずに実行するとパスワードがたくさん作成されます

```
sudo pwgen
PeeThie2 ooCee0Ri eiNgahs3 Yoo0yeig ceech6Ap ooth7ieX aong1Quo eicheiT5
Uo3ahk1C pie4loPh Aitie2fi atee6ieJ aeFufie1 ohquaR5e sho1Fie7 raipie7K
tha7Ohgu xae6eeGh uyoiZ6me roorei3F AetiCh4u qua3ooLi Osh6maPh eimooTh8
noopah9I iejiGu4i ia9aiWu2 eiNahl9S aeHoh4oh edie8IiD vu9Ruch5 waich2Su
uP4aj4Ai Voh1waiz uTh5lee1 ieP1Ophi fieKai3Y ToQu8Cee Vae7eeng eeCee9zi
hoo6ieWe Ij7Xie1D aajooD6t Aed6phei uTev1ECa eeWah8oh eez9Aa2i ahHo2Mah
xieGhoo2 Otoip3sh eew6aQui yeiLoo9i Kequaiy1 uL4chah9 si9Givai Ukoh5atu
Mau1aeta ooc2Uso7 yuh4Duha eeBoh3ah Oop3uCoh ohamoo5G ieg3Dei9 Oongei7D
waiHae9e ACaes6th ohthe2Wi aiS4meef ohKuQu7d Zaet7ach ogh1ooJe koNgie3u
Ee6pheiy aech7Ain ieM5ael8 laeD4yie Ieyai5ud ieva1Ohk Ahgo6cha aiRi0ua9
eon4dahV ULai4vae ahBeez2d kee0neK0 zo1ohLie eijeeF0u soqu3Phi ub0Chohr
ieteiM7x eeThohj9 cae6Weez iNao4muo Ohquas5i aD0caeka xohZ4Gei Och0choo
Uzoe8che chiequ3I vo4Powov faitae8S Chohhuu1 Omu9eepo UoJoh0th chae1ohF
eiX0gai5 aiHii4Oh ohFie5oo go1uu1eM Ziequoh9 woGe1shi bei6raeL Oih1shoh
eg9ohk9V Pagie3ah Kie6Neij Fu6aiSho Maec3dae IuV4echa saiR2eis ego6Hiel
eThahs2z dai9shaL eikohV7R meZir2el UChu7eis tac7Shoo ueS8ihoj Imei3ii4
Rah0Eich tee0Deis Phaesie2 eet3wu7D eeT2aiy5 Wa8Fipho ieD8oos7 Ke4eibox
Rashah4x cu0Nohbi Aruju4ui zauKa4Ee riejo8Ai ooCh9aim Yies9tuw Xee5yuuc
Ugievah8 Yai2GaiS queuy6Vi kohk8Ual Of2quaoh kah4Phee aeni8eiJ aiPhee4u
Ahg3xooc Bai4jie7 eiyii0uH Iex7ceeg eija7AeB iemi7aeP uoNgai1o Urei4aht
```

* オプションを使うこともできます(例では8文字のパスワードを1つ作成)

```
sudo pwgen 8 1
Ief4lo3e
```

* 下記のようなサーバ台数分ファイルを作成します

```websv001.dat
root:PeeThie2
user1:Uo3ahk1C
user2:tha7Ohgu
```

* chpasswdで変更(ssh鍵交換済み)

```
sudo ssh websv001 chpasswd < websv001.dat
```

これらをshellで組み込むことにより数百台のサーバの全ユーザパスワードを数分で変更できます。

以上メモ。
MySQLでINSERT時にDATETIME型のカラムに指定した時刻のミリ秒が四捨五入される

```sql
CREATE TABLE `datetimetest` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
);
```

上記のようなテーブルを用意します。datetimeは括弧なしなので秒単位です。

```sql
mysql> INSERT INTO datetimetest set time='2014-01-01 00:00:00.499';
mysql> INSERT INTO datetimetest set time='2014-01-01 00:00:00.500';
mysql> SELECT * FROM datetimetest;
+----+---------------------+
| id | time                |
+----+---------------------+
|  1 | 2014-01-01 00:00:00 |
|  2 | 2014-01-01 00:00:01 |
+----+---------------------+
```

こんなふうにINSERT時にミリ秒まで指定すると、ミリ秒が四捨五入されて秒が進んでしまいます。

```sql
mysql> SELECT * FROM datetimetest WHERE time<='2014-01-01 00:00:00.999';
+----+---------------------+
| id | time                |
+----+---------------------+
|  1 | 2014-01-01 00:00:00 |
+----+---------------------+
mysql> SELECT * FROM datetimetest WHERE time>='2014-01-01 00:00:00.999';
+----+---------------------+
| id | time                |
+----+---------------------+
|  2 | 2014-01-01 00:00:01 |
+----+---------------------+
mysql> SELECT * FROM datetimetest WHERE time>='2014-01-01 00:00:00.100';
+----+---------------------+
| id | time                |
+----+---------------------+
|  2 | 2014-01-01 00:00:01 |
+----+---------------------+
```

条件式にミリ秒を含む時刻を指定するとそれはそのまま扱われるようです。

----
追記：MySQL5.5では再現しないとの情報あり。MySQL5.6以降のみで発生する現象かも？
Pythonでランダムな文字列をつくる



```python:random.py
# 16進数(0-9, a-f)
def gen_rand_str_hex(length):
    import os
    import hashlib
	buf = ''
	while len(buf) < length:
		buf += hashlib.md5(os.urandom(100)).hexdigest()
	return buf[0:length]


# アルファベット大文字小文字+数字(0-9, a-z, A-F)
def gen_rand_str(length, chars=None):
    import random
    import string
	if chars is None:
		chars = string.digits + string.letters
	return ''.join([random.choice(chars) for i in range(length)])


```
[iOS7]navigation PopGestureが効かなくなる問題解消

## 現象
iOS7でnavigationViewController 使ってるのであればデフォルトpopGestureがYESに状態になっているはずだが,back buttonをカスタマイズしたら効かなくなる現象に気づいた。
解決法は結構簡単〜interactivePopGestureRecognizerをdelegate設定し直せば復活~~

## コード
```objc
    self.navigationItem.leftBarButtonItem = [MySuperTheme backButton];

    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) { //iOS6サポートするための判定

        self.navigationController.interactivePopGestureRecognizer.delegate = (id <UIGestureRecognizerDelegate> )self;
    }
```
＊を使って次の図を書くプログラムを作成せよ。ただし、必ずfor文を使用すること

> ＊
> ＊＊
> ＊＊＊
> ＊＊＊＊
> ＊＊＊
> ＊＊
> ＊

っていうネタをTwitterで見かけたので、JavaScriptで140文字制限でやってみた。


```js
!function(){e='＊',w=4,f=true,t='';for(i=1;i>0;(f)?i++:i--){c='';for(m=0;m<i;m++){c+=e}t+='<p>'+c+'</p>';if(i>=w)f=false}document.write(t)}()
```

もっと短くならないかな……？
高速化したGNU grepをインストール出来ない環境でも高速化

[高速化したGNU grepをインストールする](http://qiita.com/quattro_4/items/e75f2b4156ef45fb6640)
という記事と、そこで引用されている
[いまさらgrepが10倍高速化したのはなぜか](http://hamukazu.com/2014/02/24/why-grep-can-be-accelerated/) 
を読んでいたところ、以下のような記述がありました。

>そこで発想を変えて、検索される文字列を同値な正規表現にあらかじめ変換すると速くなった。
>つまり「foo」という文字列を検索するときは「[fF][oO][oO]」という正規表現に変換してから検索する。

「あれ、つまり旧バージョンのGNU grepでも-iのかわりに正規表現指定すれば速くなるんじゃね？」と思い、試
してみた結果が以下になります。

grepのバージョンは2.5.1です。

```
$ grep --version
egrep (GNU grep) 2.5.1
```

適当なファイル群を大文字小文字を問わない「test」で検索した結果が以下です。

```
$ time grep -r -i test * | wc -l
60929

real    0m15.540s
user    0m8.221s
sys     0m7.295s

$ time grep -r [tT][eE][sS][tT] * | wc -l
60929

real    0m7.295s
user    0m6.519s
sys     0m0.616s
```

他にも何パターンか試してみましたが、大体半分程度まで処理時間が短縮されました。
長い文字列だと投入自体が面倒となるかもしれませんが(bashrcに関数記載で上手く処理出来れば良いですが)、既に構築済みの環境等で今更grepのバージョンアップをするのも…でも大文字小文字区別なしでの検索を実施してて処理時間が…、というような稀にある？環境では何かの役に立つかと思われます。
GoogleSpreadsheetに追記していく

何かのデータを取ってきてGoogleSpreadsheetに追記していきたいときに。

```rb
#!/usr/bin/env ruby
# encoding: UTF-8
require 'google_drive'
 
session = GoogleDrive.login("loginID", "Password")
ss = session.spreadsheet_by_url("SpreadSheetURL")
ws = ss.worksheet_by_title("SheetTitle")
TARGET_COL = 1 #Column you want to increase
 
ws[ws.num_rows()+1, TARGET_COL] = "hoge" #Value you want to insert
ws.save
```

で、 **ここからgraphを生成してiframeで好きなところに埋め込む** といろいろ捗る
as3signals で ActionScript3 の Event をやめよう

# Event な書き方
AS3 で自作の Event を使うとき、だいたいこんな感じになる。

```as3:ButtonEvent.as
public class ButtonEvent extends Event
{
    public static const CLICKED:String = 'CLICKED';
    public function ButtonEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
    {
        super(type, bubbles, cancelable);
    }
}
```

```as3:Foo.as
public class Button extends EventDispatcher
{
    public function click():void
    {
        dispatchEvent(new ButtonEvent(ButtonEvent.CLICKED));
    }
}
```

```as3:Bar.as
var button:Button = new Button();
button.addEventListener(ButtonEvent.CLICKED, function(e:Event):void {
    trace("The button clicked.");
});
```

# as3signals での書き方

```as3:Foo.as
public class Button
{
    public const clicked:Signal = new Signal;
    public function click():void
    {
        clicked.dispatch();
    }
}
```

```as3:Bar.as
var button:Button = new Button();
button.clicked.add(function():void {
    trace("The button clicked.");
});
```

## メリット

* Button クラスがむやみに EventDispatcher を継承しなくて良い
* 文字列を使ったイベントの識別を行わなくて良い
  * 例えば ButtonEvent.CLICKED と ToggleEvent.CLICKED が同じ "CLICKED" だったりするとバグっても気づきにくい
* Button が dispatch するイベント（シグナル）がソースコードに明示的に書かれていて、コンパイル時に決定されている
  * Event Metadata というのもありますが・・・。 http://stackoverflow.com/questions/675402/as3-eventname-type-what-is-the-significance
* 記述量がすくない

ギッハブ→ https://github.com/robertpenner/as3-signals
iOSライセンス＆配布方法まとめ

# 注: 記事記載当時からライセンス形態が変わっています
「iDEP表記をADEP表記に変更」の編集リクエストは反映しましたが、コメントにもあるように諸々変わっておりますのでご注意ください。


# 1. iOSのライセンス体系

iOSのライセンスには以下の３種類がある。
![ios_license.png](https://qiita-image-store.s3.amazonaws.com/0/38461/465f080c-1fe8-ca0e-98c1-1d6989f05ac5.png)

※ADEP(Apple Developer Enterprise Program)の取得方法については省略
https://developer.apple.com/programs/enterprise/jp/


# 2. 配布方法の違い

AdHocとIn-Houseの違いは以下の通り。

## 評価用配布（AdHoc）
- App Storeを介さずに、最大100台のデバイスまでアプリ配布可能。
- インストールを許可するデバイスのUDIDをProvisioning Profileに登録する必要がある。
- デバイス追加の都度、UDID登録、Provisioning Profile更新、リビルド等の作業が必要。
- Provisioning Profileの有効期限が切れるとアプリが起動できなくなる。
- アプリの署名に使った証明書が無効になるとアプリが起動できなくなる。

## 組織内配布（In-House）
- App Storeを介さずに、デバイス無制限でアプリ配布可能。
- AdHocで必要となる煩雑な作業（UDID管理等）が一切不要。
- Provisioning Profileの有効期限が切れるとアプリが起動できなくなる。
- アプリの署名に使った証明書が無効になるとアプリが起動できなくなる。
- **In-House版アプリが関係者以外にインストールされないよう厳重管理が必要。**
- **In-House版アプリの利用者はADEP契約主体法人の従業員に限る。**

In-Houseは企業向けに強力な機能を備えている一方、配布にあたって厳格な管理が求められます。
故意か否かに関わらず、利用規約に反して契約主体法人以外にアプリ配布があった場合はADEPライセンス取り消し等のペナルティが課されます。

**受託開発ではADEP契約主体である自社以外に顧客企業へのアプリ配布が必要となる場合があるため、AdHocを採用します。**
（または、顧客のAppleIDでIn-Houseで配布する形式になるかと思います）

### AdHocでの配布デバイス数制限について
上記のとおり、AdHocでは配布デバイス数に上限があります。
ADEPライセンスは企業につき1つのみとなるため、大量のデバイス登録が必要な場合はプロジェクト毎に別途Standardライセンスを取得の上でAdHocにてアプリ配布を行ってください。


# 3. 通常のAdHoc配布
通常、 AdHocによるアプリ配布は開発用端末にデバイスを1台ずつUSB接続して行います。
ただしこの方法は非常に手間がかかる上、開発ロケーションが離れている場合等に迅速なアプリ配布を行うことができないといった問題が伴います。

![ios_adhoc.png](https://qiita-image-store.s3.amazonaws.com/0/38461/74482a72-7403-619b-5e57-d0151f8f6e03.png)


# 4. TestFlightを利用したAdHoc配布
AdHocによるアプリ配布をサポートするWebサービスとしてTestFlight（ https://testflightapp.com ）があります。
TestFlightを利用することで、Web経由で複数デバイスに対して一斉にAdHoc配布を行うことが可能になります。
加えてデバイスの一元管理・アクティビティ確認といった機能も備えているため、誰がどの端末でどのように配布アプリを使用しているかを容易に把握することも可能になります。

![ios_testflight.png](https://qiita-image-store.s3.amazonaws.com/0/38461/efda4973-8346-633f-f26f-743c80a34ecb.png)
kivy-iosメモ kivy v1.8.0（MAC）


#Deprecated this article (Reference to [New article](http://qiita.com/leon_AKQJT/items/1ced42822e7262f24bd9))



Mac環境(osx 10.10)上でkivy-iosをビルドしてデバイス上で動作させるメモ
※現状はarmv7対応のみの対応なので2015年2月1日からは App Store には新規登録できなくなる。登録できれば、2015年5月末までは更新可能。

[http://qiita.com/b4b4r07/items/6efebc2f3d1cbbd393fc](http://qiita.com/b4b4r07/items/6efebc2f3d1cbbd393fc)
[http://stackoverflow.com/questions/21242107/pip-install-pil-dont-install-into-virtualenv](http://stackoverflow.com/questions/21242107/pip-install-pil-dont-install-into-virtualenv)
[http://www.renedohmen.nl/blog/2013/08/installing-kivy-on-mac-osx-10-6-with-brew/](http://stackoverflow.com/questions/21242107/pip-install-pil-dont-install-into-virtualenv)
[http://kivy.org/docs/guide/packaging-ios.html](http://kivy.org/docs/guide/packaging-ios.html)

###1.HomeBrew環境のクリア

```bash:console
cd `brew --prefix`
rm -rf Cellar
brew prune
rm `git ls-files`
rm -r Library/Homebrew Library/Aliases Library/Formula Library/Contributions
rm -rf .git
rm -rf ~/Library/Caches/Homebrew
```

###2.HomeBrewインストール

```bash:console
cd
sudo chown -R $USER:admin /usr/local
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew doctor
```

###3.pythonインストール

```bash:console
brew install python
brew link --overwrite python
```

###4.kivy インストール

```bash:console
brew install mercurial
brew link --overwrite mercurial
brew install sdl sdl_image sdl_mixer sdl_ttf portmidi
pip install -Iv http://cython.org/release/Cython-0.20.2.tar.gz
ln -s /usr/local/include/freetype2 /usr/local/include/freetype
pip install PIL --allow-external PIL --allow-unverified PIL
pip install kivy
```

###5.kivy-iosインストール

```bash:console
brew install autoconf automake libtool pkg-config
git clone git://github.com/kivy/kivy-ios
cd kivy-ios
tools/build-all.sh
```

###6.kivy-ios動作確認（プロジェクト作成＆ビルド）

```bash:console
tools/create-xcode-project.sh test test
cd app-test
mkdir test
mkdir YourApp
cd test
vi main.py
```

```py:main.py
import kivy
kivy.require('1.0.7')
from kivy.app import App
from kivy.uix.button import Button

class TestApp(App):
    def build(self):
        roodWidget = Button(text='hello world')
        # return a Button() as a root widget
        return roodWidget
if __name__ == '__main__':
    TestApp().run()
```

```bash:console
cd ..
open test.xcodeproj
```

##iOS deviceで動作したら完了

Apple Store に登録する際は、以下のコマンドを実行してスリムにする必要がある。

```bash:console
tools/reduce-python.sh
```
##
Google AnalyticsのProfile IDってなんぞ

https://productforums.google.com/forum/#!topic/analytics/dRuAr1K4waI

> The other answers are based on using the OLD VERSION analytics page and are correct that the ID=xxxxxxxx is the profile ID 
https://www.google.com/analytics/reporting/?reset=1&id=XXXXXXXX&pdr=20110702-20110801 

> For the NEW VERSION analytic page it is the number at the end of the ERL starting with p 
https://www.google.com/analytics/web/#home/a11345062w43527078pXXXXXXXX/

うん、まんまなのですが、上記のURLのp以下の数字を埋め込む必要がありました。
gemでTo eliminate this warning, please install libyaml and reinstall your ruby.のエラーが出た場合の対処


## 環境

- OSはMac OS X
- rubyはHomebrewで入れた
- libyamlはHomebrewで入れた
- rubyがバージョン毎にいくつか入っていた。
  - 2.0系2つの内1つをメインで使っていた
  - 2.1.1を最近インストールしたが使ってはいない。



## エラー内容

`$ gem --version` と打つも以下の様エラーが表示された。

```
$ gem -v

/usr/local/Cellar/ruby/2.0.0-p353/lib/ruby/2.0.0/yaml.rb:4:in `<top (required)>':
It seems your ruby installation is missing psych (for YAML output).
To eliminate this warning, please install libyaml and reinstall your ruby.
...

```

## 対処方法

#### 取り敢えずlibyamlを再インストール

```
$ brew uninstall libyaml
...

$ brew install libyaml
...

$ brew doctor
Your system is ready to brew.
```


#### 使ってないrubyをアンインストール

まず、現在使っているrubyのバージョンを調べる

```
$ brew witch ruby
/usr/local/Cellar/ruby/2.0.0-p353/bin/ruby
```

2.0をちゃんとみてる…が、凄いあやしい…


とにかく、最新版のrubyがあやしいので取り敢えずrubyを消す。

```
$ brew uninstall ruby
Uninstalling /usr/local/Cellar/ruby/2.1.1...
```

やっぱりおかしい！最新版のrubyが削除された！


```
$ brew doctor
Your system is ready to brew.

$ gem -v
2.2.2
```

直ったみたいです。
無料でbitbucketのリポジトリをCI


# ゴール
* bitbucketのレポジトリにpushしたら、jenkinsに通知されてビルドが実行される

# 使うもの
[CloudBees](http://www.cloudbees.com/) (javaのpaasサービス / 最初からjenkins入ってる)


# 手順
## ステップ1.  まずは手動でbuildするところまで設定
### CloudBees側
1. CloudBeesアカウント取得
1. jenkins(すでにインストールされてる)を起動(10分位かかる)
1. 新しくビルドジョブを作成
 * ソースコード管理のURLを記入 例) git@bitbucket.org:XXXXX/XXXX.git
 * ビルド手順を設定(テストの実行とか)
 * CloudBees Public Key※1を手元にコピーしておく

### BitBucket側
1. アカウント設定設定画面からssh key※1を登録  
注)レポジトリの設定ページの”デプロイ鍵”に設定しても手動ビルドは通るが、  
pushを検知してbuildさせるためにはアカウントの設定が必要

### -> jenkinsページから手動でジョブを実行して通れば成功！

## ステップ2. pushされたら自動でbuildされるように設定
### CloudBees側
1. jenkinsのプラグイン管理ページから bitbucket pluginをインストール
2. ジョブの設定画面に”Build when a change is pushed to BitBucket” が追加されているのでチェックして保存

### BitBucket側
1. レポジトリの設定画面から”フック”を選択
2. “POST” を選択し、https://「CloudBeesのアカウント名」.ci.cloudbees.com/bitbucket-hook/　で追加

### -> レポジトリにpushして、jenkinsでbuildが走れば成功！

## トラブルシュート
#### pluginをインストールしたらテスト実行時に、javaでエラーがでた！
-> インストールされてるプラグインを一通り最新にしたら治りました
#### pushしてもビルドされない！
-> jenkinsを再起動したら成功しました。

****
記事作成時間 : 50分
Vimでカーソル配下の単語を大文字や小文字に統一


| 方向 | 操作 |
|--------|--------|
| 小文字に統一|`guiw`|
| 大文字に統一|`gUiw`|
| 大小反転|`g~iw`|


## 参考
[Vim-users.jp - Hack #166: ローマ字の大文字/小文字を変換する](http://vim-users.jp/2010/08/hack166/)
Dependency Injectionを特定のDIコンテナに頼らず実現する

Pimple風の名前ベースでインジェクション設定を書いていくやり方なら、ただのファクトリで再現できそうに思った。

# Pimpleのコア機能はPimpleがなくても実現できる仮説

DIのサンプルはPHPメンターズのものを流用させていただく。
[PHPメンターズ -> Pimpleでシンプルに正しくDIを理解する](http://phpmentors.jp/post/28548053449/pimple-di)

Pimpleの場合。

```php:di.php
<?php
$container = new \Pimple();

// オブジェクトコンストラクションのコンフィギュレーション
$container['infrastructure.mailer'] = function($container) {
    $mailer = new \SendmailMailer();

    return $mailer;
};
$container['domain.transfer.newsletter'] = function($container) {
    $newsletterTransfer = new \NewsletterTransfer($container['infrastructure.mailer']);

    return $newsletterTransfer;
};

return $container;
```

素のクラスにしてみる。

```php:FactoryDefault.php
<?php
class FactoryDefault
{
  function createInfrastructureMailer()
  {
    return new SendmailMailer;
  }

  function createDomainTransferNewsletter()
  {
    return new NewsletterTransfer($this->createInfrastructureMailer());
  }
}
```

```php:example.php
<?php
$container = new FactoryDefault;
// オブジェクトの利用
$newsletterTransfer = $container->createDomainTransferNewsletter();
$newsletterTransfer->send('ニュースレター本文');
```

メソッド名をラベルとして使うスタイルです。実現できてますね！

# ファクトリによるDI設定のテクニック

## オブジェクトの生成を使いまわす(疑似シングルトン)

static変数でキャッシュすればおｋ。
たとえばさっきの例でInfrastructureMailerは毎回作らなくても、同じオブジェクトを使いまわせばいいのなら、こんな感じか？

```php
  function createInfrastructureMailer()
  {
    static $mailer;
    return $mailer ?: ($mailer = new SendmailMailer);
  }
```

## 設定を上書きする
[DIコンテナなんていらない - usagidropの日記](http://d.hatena.ne.jp/usagidrop/20071206/1196876611)
このページだと、ファクトリをグローバル関数で書いてしまっている。PHPの関数は一度定義すると上書きできないので、拡張性を担保するならばクラスで書いてメソッドにした方がよいだろう。
ファクトリによるDIコンテナなら上書きが可能である。

たとえばさっきの例で、テストをしたいからInfrastructureMailerはモックに差し替えたい、という場合。

```php:FactoryTest.php
<?php
class FactoryTest extends FactoryDefault
{
  function createInfrastructureMailer()
  {
    return new SendmailMailerMock;
  }
}
```

```php:test.php
<?php
$container = new FactoryTest; //こっちに差し替える
//...
```

Mockに差し替えられた。

## 設定を継承して追加する
もちろんクラスの継承なので、parent::も使える。
たとえばさっきの例で、InfrastructureMailerに何か設定を追加したい場合。こんな感じでいける。

```php
//...
  function createInfrastructureMailer()
  {
    $mailer = parent::createInfrastructureMailer();
    $mailer->setOption('hogehoge');
    return $mailer;
  }
//...
```


# 素のFactoryをDIコンテナとして利用するメリット
- 特定のDIコンテナライブラリが不要
- たぶん速い
- コア機能は割となんとかなりそうな気がする
- IDEで入力補完がきく

# 素のFactoryをDIコンテナとして利用するデメリット
- PHP<5.4だと設定ファイルの分割ができない。traitが必要
- 複数の設定ファイルをマージできない。traitが必要
- 所詮は名前ベースのインジェクタなので、大規模になると名前管理で破綻する
- AOPなどの豪華機能はない
macにcomposerをinstallするまでのあれこれ


https://github.com/composer/composer


こちらのinstallに従って実行

```sh
$ curl -sS https://getcomposer.org/installer | php
#!/usr/bin/env php
Some settings on your machine make Composer unable to work properly.
Make sure that you fix the issues listed below and run this script again:

The detect_unicode setting must be disabled.
Add the following to the end of your `php.ini`:
    detect_unicode = Off

A php.ini file does not exist. You will have to create one.
If you can not modify the ini file, you can also run `php -d option=value` to modify ini values on the fly. You can use -d multiple times.
```

php.iniがないよ。ない形で実行するのであれば、`detect_unicode = Off`こんな感じで実行してねという意味だと受け取った！


http://www.andrew-kirkpatrick.com/2012/10/install-composer-for-php-on-zend-server-mac-os-x/


↑のサイトにもそのような事が書いてあったので実行してみる。

```sh
$ curl -sS https://getcomposer.org/installer | php -d detect_unicode = Off
Could not open input file: =
curl: (23) Failed writing body (0 != 1674)
```

何が起きたんだ。。。
参考サイトをよく見るとオプションが間違っていた。
`curl -sS`→`curl -s`でした。。。

```sh
$ curl -s getcomposer.org/installer | php -d detect_unicode=Off
#!/usr/bin/env php
All settings correct for using Composer
Downloading...

Composer successfully installed to: /Users/mapyo/vagrant/cmsp/cmsp-admin/composer.phar
Use it: php composer.phar
```

という事で無事に入りました。


http://www.d-wood.com/blog/2013/06/16_4017.html


↑のサイトを参考に扱い易いようにパスの通ったところに移動させてみます。

```sh
$ mv ./composer.phar /usr/local/bin/                       
$ ln -s /usr/local/bin/composer.phar /usr/local/bin/composer
```

参考サイトでは`composer.phar`のファイル名をそのまま書きかえてましたが、
それだと忍びないのでシンボリックリンクを貼る形にしてみました。

```sh
$ composer
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
```

めでたしめでたし！
10.9.2にしたら電源ボタンでスリープの方法が変わった？

10.9.1までは電源ボタンを触れただけで即スリープでしたが、
10.9.2は電源ボタンを`1秒くらい押し続ける`ことでスリープになった。

なお、ダイアログを表示させてスリープさせるのは`ctrl+電源ボタンを押してsキー`

(MacbookAir13 2012)
luaでlinuxのコマンドを実行する

luaで外部コマンドの実行結果を取得する方法です。popenを使うとコマンドの結果がとれるようです。
文字列をテーブルに変換する処理がなかったので、splitを書いてみました。

```lua:sample.lua
function split(str, delim)                                                                                                                                    
        assert(str,  "文字列が設定されていません")
        assert(delim,"区切り文字がしていされていません")
        local pattern = "[^"..delim.."]*"..delim
 
        local result = {}
        for item in string.gmatch(str, pattern) do
                local tmp = item:gsub(delim,"")
                table.insert(result, tmp)
        end 
        return result
end
 
function getPid(name)
        local command='pidof '..name
        local commandResult = execCommand(command)
        local result = string.gsub(commandResult, "\n", "") 
        return  result
end
 
function getDirList(dirname)
        local command='find '..dirname..' -type d'
        local commandResult = execCommand(command)
        local result = string.gsub(commandResult, "\n", ",")
        return split(result, ",")
end
 
function execCommand(command)
        local handle = io.popen(command,"r")
        local content = handle:read("*all")
        handle:close()
        return content
end
```
MavenでJUnit 4をテストするためのpom.xml

JUnit 4のテストクラスは、mvn testしてもテストクラスがテストされない。どうやら、標準ではJUnit 3の方式で*Testクラスを探しに行ってる？っぽいので、pom.xmlで調整。

```xml
<build>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.16</version>
    <configuration>
      <argLine>-Dfile.encoding=UTF-8</argLine>
      <includes>
        <include>**/*.class</include>
      </includes>
      <excludes>
        <exclude>**/HogeTestRule.class</exclude>
      </excludes>
    </configuration>
  </plugin>
</build>
```

工夫した点は2つ。

- configulationのargLineでfile.encodingをUTF-8に
	- 日本語メソッド名・クラス名・属性名を使っている所があるので、指定しないとエラーになる
- ExternalResourceクラスを継承したテストルールクラスをテスト対象外へ
	- includesで全てのクラスを指定してるけど、テストルールはテストしないのでexclude化

これで、JUnit 4を使っていても、Mavenでビルド・テストできる。