明日も楽をするために

めんどくさがりなITエンジニアが書くメモ帳

iOSでTabbarのテキストの色を変更する

選択後の色に関しては別の方法もあるが、選択前の色も変える方法

let font:UIFont! = UIFont(name:"HiraKakuProN-W3",size:10)
let selectedAttributes = [NSFontAttributeName : font, NSForegroundColorAttributeName : UIColor.whiteColor()]
UITabBarItem.appearance().setTitleTextAttributes(selectedAttributes, forState: UIControlState.Normal)
UITabBarItem.appearance().setTitleTextAttributes(selectedAttributes, forState: UIControlState.Selected)

xcodeで分からないエラーや調子が悪いと思ったら

以下のコマンドをターミナルで実行するのをオススメ
ビルドした中間コードなども入っているので、消すとエラーが消えることもある
Xcodeのバージョンアップ後なんかも一回打っておくといいかも

rm -rf ~/Library/Developer/Xcode/DerivedData/*

html5 Audioタグ Videoタグ スマホ TIPS

複数スマホ端末情報を取得する機会があったので、そこで分かったことを書きたいと思います。


■Video

■Source

Videoタグは、sourceとしてmp4、webm、oggと指定できますが、
調査した結果mp4を再生できないスマホ端末は存在しませんでした。

かなり古い端末ならありえますが、私の情報では該当の端末の発見はできませんでした。

それと逆にoggを再生できる端末もほとんど存在しませんでした。

なので動画をsourceとして指定する際はmp4さえあれば充分だと思います。

■FullScreen

Androidだと約10%の端末がFullScreenに対応していませんでした。

iPhoneは強制的にFullScreenになりますが、FullScreen関数に対応しているわけではありません。なので閉じることもできません。ユーザが自分で閉じるしかありません。

画面遷移を行えば閉じることもできますが。。。。。ちなみにAndroidは画面遷移してもFullScreenは解除されません。


■Audio

■Source

Audioタグのsource指定はwav、mp3、oggとありますが、8割がmp3対応の再生に対応しています。あと意外にoggにしか対応していない端末もあります。

現実的には無圧縮のwavを使うのは選択肢としては可能性は低いと思いますのでmp3とoggは必須な気がします。

スマホで使う<audio>タグの動作検証

html5からaudioタグが追加されましたが、スマホだとどういった風に動作するのか検証してみました。

<script>
var audio = new Audio();
audio.src = "http://foo.mp3";

function play() {
    audio.load();
    audio.play();
}
</script>
<a href="javascript:void(0)" onClick="play()">play</a>

これが一番簡潔なコードで、PCだと特に問題ないのですがスマホだと色々な挙動をします。

そもそも大前提としてスマホで使った場合はどうなるのか?
iPhoneAndroidでは一回は画面にタップしないと、読み込みと、再生が出来ないように制限されている。

しかしiOS8.4のiPhone6で検証した所、タップをしないでも読み込みができることに気づきました(バグ?

<script>
var audio = new Audio();
audio.src = "http://foo.mp3";
audio.load();//iOS8.4だと動作する
function play() {
    audio.play();
}
</script>
<a href="javascript:void(0)" onClick="play()">play</a>

ちなみに読み込みのload()関数は書かなくても動作します。srcにソースを指定したタイミングと、play()を呼び出した際にも自動的に読み込みが始まります。

それとAQUOS PHONE SERIE(shl23)だとplay()の前にload()を書くと何故か再生されないバグがあります。

<script>
var audio = new Audio();
audio.src = "http://foo.mp3";

function play() {
    audio.load();//shl23だと再生されなくなる・・・・
    audio.play();
}
</script>
<a href="javascript:void(0)" onClick="play()">play</a>

audioタグにはイベントリスナを設定できるのですが、iOS8.4だと画面をもどった際にイベントリスナが効かなくなります(バグ?

<script>
var audio = new Audio();
audio.addEventListener("ended", function(){}, false);//画面を戻った際に反応しない
audio.src = "http://foo.mp3";
audio.load();

function play() {
    audio.play();
}
</script>
<a href="javascript:void(0)" onClick="play()">play</a>

対処方法としては再度audioインスタンスを生成するしかありません。

<script>
function play() {
    var audio = new Audio();
    audio.addEventListener("ended", function(){}, false);
    audio.src = "http://foo.mp3";
    audio.load();
    audio.play();
}
</script>

Apache+nodejs+socket.ioを使ったリアルタイムWeb

普段のサーバーはApacheを使っているのですが、少し前にnodejsというサーバーからクライアントまでJavaScriptで書ける物がリリースされました。

nodejsはV8エンジンというGoogleChromeで使われている高速なエンジンを使用していたり、またApacheのC10K問題を解決しようとするものでした。

メリットも多いながらデメリットもそこそこあり、デプロイ時に再起動しないと新しいリソースが反映されなかったり(現在は解決してるのかな?)、イベント駆動ループ型なので、どこかでエラーが発生すると止まったり、またシングルスレッドで動くので最近主流のマルチコアCPUとは相性が悪かったりするんですが、デメリットを理解して使えれば色々と面白いです。

以下のBlog記事がとても面白かったです。実際のGreeの導入事例や、アメリカチェーンのスーパーマーケットWalmartブラックフライデー時の高負荷時にもサーバーが落ちずに耐えきった話など。

GREEが悩むNode.jsの問題を考えるヒント - ぼちぼち日記

隠れていたNode.jsの4バイトメモリリーク、Walmart問題の解決 - ぼちぼち日記

少しタイトルと話がそれましたが、そのnodejsはhtml5のsocket.ioの実装もとても簡単にできます。これが出来るとリアルタイムWeb(情報の更新をリアルタイムに反映し共有する概念やその仕組み)が使えます。

要するに、いままではブラウザ画面を更新したり、画面遷移をしたりと、クライアント(ブラウザ)側からアクションを起こさないと画面が切り替わりませんでしたが、これを使うとサーバーから好きなタイミングでクライアント(ブラウザ)に情報を送信できます。例えばチャットや、簡単なオンラインゲームなんかも作れたりします。

これ自体はnodejsだけでも出来るのですが、今回は裏の通信部分だけをnodejsで実装します。
以下がサンプルソースです。Apacheは80ポートで使用しているので、nodejsは今回は8080ポートを使用した想定です。

サーバー側

var io = require('socket.io').listen(8080);
io.sockets.on('connection', function (socket) {
    socket.emit('connected', 'connected');
/*
    socket.emit('news', { hello: 'world' });
    socket.on('my other event', function (data) {
        console.log(data);
    });
*/
    // クライアントが切断したときの処理
    socket.on('disconnect', function() {});
});

クライアント側

<html>
<head>
<meta charset="utf-8">
<script src="http://foo.co.jp:8080/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://foo.co.jp:8080');
/*
socket.on('news', function (data) {
    console.log(data);
    socket.emit('my other event', { my: 'data' });
});
*/
socket.on('connected', function (data) {
    console.log(data);
});
socket.on('disconnect', function (data) {
    //console.log(data);
    socket.disconnect();
});
</script>
</head>
<body>
HelloWorld
</body>
</html>

これで最低限の接続と切断が行えます。送信したいときはemitで受け取りはonで使用できます。

これを使って何か作ってみたいところです。

追記
Firefoxや、Thunderbirdを作ったMozillaが公開しているサンプル↓
nodejsとsocket.ioを使ってますbrowserquest.mozilla.org

PHP5.2でより良い乱数生成

PHPの乱数生成で偏りを感じるので、異なる方法での乱数生成を調べてみました。

乱数の取得にはrand()とmt_rand()があり、mt_rand()がより良い乱数を取得とドキュメントに書いてあるのですがイマイチです。

mt_rand()はmt_srand()によりシードを生成できますが、指定がない場合は自動でやってくれるみたいです。ここに問題があると思われるので、ここを別の方法でシードを生成します。


PHP5.3だとopenssl_random_pseudo_bytes()を使用して乱数を初期化する方法があるようです。

<?php
mt_srand(hexdec(bin2hex(openssl_random_pseudo_bytes(4))));

しかし私の職場環境だとPHP5.2なので、この方法は使えません(ノД`)・゜・。

そこでLinuxの疑似乱数生成器/dev/urandomを利用することにします

<?php
$file = file_get_contents('/dev/urandom', false, null, 0, 1000);
$file = base64_encode($file);
exec("echo {$file} | tr -dc 0-9 | head -c 8", $output);
mt_srand($output[0]);

これで8桁の乱数を取得できます。

Mysqlの最大接続数の設定

作ったサービスのMysqlの接続数の設定とか全然してかったなぁ~と思いつき色々調べたのでメモ(笑

現在設定してある最大接続数の設定確認

show global variables like 'max_connections';

起動してからこれまでの最大同時接続数

show global status like 'Max_used_connections';

スレッドの色々な状態

show global status like 'Thread_%';

↑でThreads_createdが異常に多い場合はキャッシュの数が足りない
(私のでは2万ぐらいになってた。キャッシュの設定はしていなかったので)

キャッシュ接続数の確認

show variables like 'thread_cache_size';

/etc/my.cnfに以下を追加して再起動

[mysqld]
thread_cache_size = 100

即時反映なら

set global thread_cache_size=100;


キャッシュサイズの値は最大同時接続数の1~3倍ぐらいがいいかも