Xcode6のLaunchScreen.xibにカスタムフォントが適用されない

LaunchScreen.xibのプレビュー画面ではカスタムフォントが適用されているのに、実機やシミュレータで確認するとカスタムフォントが適用されない。

どうもバグっぽい。
画像としてテキストは用意した方がいいかも。
参考:http://stackoverflow.com/questions/25794314/using-custom-fonts-with-xcode-6-ios-8-interface-builder-launch-screen

Xcode6から実機にインストールしたアプリのアイコンが真っ黒になるとき

xcassetsにのAppIconの各サイズにきちんと設置しているはずなのに、なぜかアプリのアイコンが真っ黒になってしまう場合。

原因は、透過処理の入った画像を使っていることだった。
警告がでないので気付かず。
透過している部分にも、きちんと背景を設定しよう。

PHPでServer Sent Eventを簡単に試してみる

これを読んでるとやたらと楽しそうかつ簡単に導入できそうだったので試してみる。

参考:https://developer.mozilla.org/ja/docs/Server-sent_events/Using_server-sent_events

see_test1.php

<?php
header("Content-Type: text/event-stream\n\n");

$counter = rand(1, 10);
while (1) {
  // "ping" イベントを毎秒送信
  
  echo "event: ping\n";
  $curDate = date(DATE_ISO8601);
  echo 'data: {"time": "' . $curDate . '"}';
  echo "\n\n";
  
  // シンプルなメッセージをランダムな間隔で送信
  
  $counter--;
  
  if (!$counter) {
    echo 'data: This is a message at time ' . $curDate . "\n\n";
    $counter = rand(1, 10);
  }
  
  ob_flush();
  flush();
  sleep(1);
}

index.html

<html>
    <head>
        <title>Server Sent Event テスト</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">

        <script>
            window.onload = function() {
                var evtSource = new EventSource("sse_test1.php");
                var eventList = document.getElementById("log");
                
                evtSource.onmessage = function(e) {
                    var newElement = document.createElement("li");

                    newElement.innerHTML = "message: " + e.data;
                    eventList.appendChild(newElement);
                }
                evtSource.addEventListener("ping", function(e) {
                    var newElement = document.createElement("li");

                    var obj = JSON.parse(e.data);
                    newElement.innerHTML = "ping at " + obj.time;
                    eventList.appendChild(newElement);
                }, false);
            }
        </script>

    </head>
    <body>
        <div>TODO write content</div>

        <div id ="log"></div>
    </body>
</html>

これで、index.htmlにアクセスしてみるとずらずらとテキストストリームが表示される。

CentOSにMySQL 5.5をバージョン指定してインストール

MySQLの現在の最新バージョンは5.6であり、yumにrpmリポジトリを追加して普通にyum installするとMySQL5.6が入る。
ホスティング会社の提供するDBサーバーのMySQLバージョンが5.5のとき、テストサーバーには同じバージョンである5.5をインストールしたい。
その方法を示す。

まず、既存のMySQLをアンインストール。

$ sudo yum -y remove mysql*

rpmリポジトリをyumに追加。

$ sudo yum -y install http://dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm

このままインストールすると最新版のMySQL5.6が入ってしまうのでリポジトリファイルを編集。

$ sudo vi  /etc/yum.repos.d/mysql-community.repo

下記のように編集。

# Enable to use MySQL 5.5
[mysql55-community]
name=MySQL 5.5 Community Server
baseurl=http://repo.mysql.com/yum/mysql-5.5-community/el/6/$basearch/
enabled=1   #ここを1に
gpgcheck=1
gpgkey=file:/etc/pki/rpm-gpg/RPM-GPG-KEY-mysql

# Enable to use MySQL 5.6
[mysql56-community]
name=MySQL 5.6 Community Server
baseurl=http://repo.mysql.com/yum/mysql-5.6-community/el/6/$basearch/
enabled=0  #ここを0にする
gpgcheck=1
gpgkey=file:/etc/pki/rpm-gpg/RPM-GPG-KEY-mysql

yumでインストール。

$ sudo yum -y install mysql mysql-devel mysql-server mysql-utilities

起動と自動起動設定。

$ sudo service mysqld start
$ sudo chkconfig mysqld on

確認

$ mysql --version
mysql Ver 14.14 Distrib 5.5.40, for Linux (x86_64) using readline 5.1

これでMySQL5.5がインストールできた。

NodeJSでCron処理を実現し、デーモン化させる。

NodeJSで作ったプログラムをCronのように動かしたい。

どうやらnode-cronというモジュールがあるらしい。

Node.jsで特定の処理を指定日時、あるいは特定のパターンの日時に繰り返し実行する方法: node-cronを使う

上記サイトを参考に、関連モジュールをnpmでインストール。

$ npm install cron
$ npm install time

サンプルコード内のjob.stop();をコメントアウトさせ、いつものように $ node crontest.js と実行させると、1秒毎にHelloが表示される。

// Stops your job.
// job.stop();  コメントアウト

Ctr + C で終了。

次に、過去に作ったNodeJSプログラムをCronで動かしたい。
サンプルコードをみるとonTickの中にで過去のプログラムを動かせばよさそうだ。

…
 onTick: function() {
    console.log('Hello.');
  }
…

下記のサイトを参考に外部ファイル化させ、上記メソッド内で実行させるとOK。

node.jsで外部ファイルのJavaScriptを呼び出す

※NodeJSに限らず、Cronのような処理を行うときは、プログラム内のファイルへのパスを絶対パスで記述しないと動かないので注意。

次にCronをデーモン化させる。

foreverモジュールを利用。グローバルインストールさせないとなぜかコマンドが認識されないので下記のようにインストール。

$ npm install -g forever

下記のコマンドでデーモン化。

$ forever start crontest.js

稼働中のデーモン一覧を見る時は

$ forever list 

どうやらログファイルも自動生成されるようで、プログラム内のエラーやconsole.logがそのログに記録されていく。

停止させるときは

$ forever stop (listで確認したuid)

以上。

NodeJSでMAMPのMySQLにアクセスする。

mysqlモジュールをnpmでインストール後、下記のようなコードでMySQLにアクセスできるといろんなサイトに掲載されているが、MacのMAMPだと失敗する。

var connection = mysql.createConnection({
    host: 'localhost',
    database: 'dbname',
    user: 'username',
    password: 'password'
});

下記のようにMAMP内のMySQLサーバーのポートである8889を指定するとアクセスすることができる(念のためMySQLのポートはMAMPの設定から確認してほしい)。

var connection = mysql.createConnection({
    host: 'localhost',
    database: 'dbname',
    user: 'username',
    password: 'password',
    port:8889
});

以上。

htmlファイルのリンクをチェックするブックマークレットを作った

フロントエンドコーディングの品質管理において何か良いツールはないかと探していたところ、知人に下記を紹介してもらった。

alt属性を確認するブックマークレット。

ブックマークレットということでブラウザさえ対応していればWindows,Macを選ばずサクサクと実行することができる。
このブックマークレットにインスパイアされ、ページ内のリンクをチェックするブックマークレットを自作してみた。

javascript:(function(d) {
    function l() {
        (function($) {
            var rid = 'ALL_link_check';
            if (document.getElementById(rid))
                return;
            function e(t) {
                return document.getElementsByTagName(t);
            }
            function a(o, a) {
                return o.getAttribute(a);
            }
            anchors = document.getElementsByTagName('a');
            if (anchors.length <= 0)
                return;
            var r = document.createElement('div');
            var rcss = 'padding:5px;position:absolute;top:0;left:0;background:#fff;border:solid #ccc 1px;z-index:2999;';
            var tblcss = ' style=\'border-collapse:collapse;background:#fff;\'';
            var tdlcss = ' style=\'padding:4px;border-bottom:solid #ffffff 2px;text-align:right;\'';
            var tdrcss = ' style=\'padding:4px;border-bottom:solid #ffffff 2px;text-align:left;\'';
            r.id = rid;
            r.style.cssText = rcss;
            var h = '';
            h += 'Checking link existence....';
            for (var j = 0; j < anchors.length; j++) {
                h += (j % 2 == 0) ? '' : '';
                h += '' + anchors[j].innerHTML + '' + a(anchors[j], 'href') + '';
            }
            h += '';
            e('body')[0].appendChild(r);
            r.innerHTML = h;
            r.onclick = function() {
                this.parentNode.removeChild(this);
            };
            window.scrollTo(0, 0);
            function checkurl(id, geturl, maxcnt) {
                $.post(geturl, {value: 1}, function(data) {
                }).fail(function(error) {
                    if (error.status == 404) {
                        $('#existcheck' + id).css('background-color', '#ff0000');
                    } else {
                        $('#existcheck' + id).css('background-color', '#0000ff');
                    }
                }).always(function() {
                    if (geturl == '#') {
                        $('#existcheck' + id).css('background-color', '#ff0000');
                    }
                    if (!geturl) {
                        $('#existcheck' + id).css('background-color', '#ff0000');
                    }
                    if (id == maxcnt - 1) {
                        $('#checkinglink').html('Done!!');
                    }
                });
            }
            var maxcnt = anchors.length;
            for (var j = 0; j < maxcnt; j++) {
                var geturl = a(anchors[j], 'href');
                checkurl(j, geturl, maxcnt);
            }
        })(jQuery)
    }
    if (typeof jQuery == 'undefined') {
        var j = d.createElement('script');
        j.type = 'text/javascript';
        j.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js';
        d.body.appendChild(j);
        j.onload = l
    } else {
        l()
    }
})(document);

本来であれば直接ブックマークに追加できるよう掲載したかったが、なぜかうまくいかなかったので、上記コードをコピーし、このサイト でブックマークレット形式に変換して利用してほしい。

ブックマークバーに保存したあとは、対象のウェブサイトで実行すると、下記のように全てのリンクの一覧が表示される。
その後、ajaxで各リンクの存在チェックを行い、リンク切れのところは赤に、外部リンクは青にハイライトされる仕様だ。
Chromeの最新版で動作確認済み。
ブックマークレット

フロントエンドコーディング担当者には品質チェックの一環として、担当ページの提出前にこれを実行してもらおうと思う。

PHPのcurlでeuc-jpのページを取得したときに文字化けするのを防ぐ

俺日記のしんじです。一人称は僕です。

下記のようなcurlの関数を用意し、euc-jpのページを取得し、シェル内でで取得したページを確認すると文字化けしていることに気づいた。

function curl_get_contents($url, $timeout = 60) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

上記コードを下記のように変更することで文字化けを防ぐことができる。

function curl_get_contents($url, $timeout = 60) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    $result = curl_exec_utf8($ch);
    curl_close($ch);
    return $result;
}

/** The same as curl_exec except tries its best to convert the output to utf8 * */
function curl_exec_utf8($ch) {
    $data = curl_exec($ch);
    if (!is_string($data))
        return $data;

    unset($charset);
    $content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);

    /* 1: HTTP Content-Type: header */
    preg_match('@([\w/+]+)(;\s*charset=(\S+))[email protected]', $content_type, $matches);
    if (isset($matches[3]))
        $charset = $matches[3];

    /* 2:  element in the page */
    if (!isset($charset)) {
        preg_match('@ element in the page */
    if (!isset($charset)) {
        preg_match('@<\?xml.+encoding="([^\s"]+)@si', $data, $matches);
        if (isset($matches[1]))
            $charset = $matches[1];
    }

    /* 4: PHP's heuristic detection */
    if (!isset($charset)) {
        $encoding = mb_detect_encoding($data);
        if ($encoding)
            $charset = $encoding;
    }

    /* 5: Default for HTML */
    if (!isset($charset)) {
        if (strstr($content_type, "text/html") === 0)
            $charset = "ISO 8859-1";
    }

    /* Convert it if it is anything but UTF-8 */
    /* You can change "UTF-8"  to "UTF-8//IGNORE" to 
      ignore conversion errors and still output something reasonable */
    if (isset($charset) && strtoupper($charset) != "UTF-8")
        $data = iconv($charset, 'UTF-8', $data);

    return $data;
}

参考:http://stackoverflow.com/questions/2510868/php-convert-curl-exec-output-to-utf8

以上。