月別アーカイブ 3月 2019

村上 著者:村上

【Swift】KVO(Key-Value Observing)を触ってみた

昔他の人が開発したiOSアプリを修正していたのですが、現行の環境で実行したところエラーが発生しました。
で、エラー発生個所が KVO の処理のところだったので、修正もかねてちょっと触ってみました。
ちなみに、エラー修正前のアプリは、実行した直後に落ちました。

KVO について参考にさせていただいた記事はこちら。

Swift4のKVOに感動した。 – Qiita
https://qiita.com/ObuchiYuki/items/d00ce5f44725672184da

なお、KVO とは、オブジェクトの値の変更の監視をしてくれる Swift の機能です。

 

コードの修正ですが、下記の場所を修正しました。

func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutableRawPointer) {
    // 実行したい処理
}

こちらは、監視しているオブジェクトの値が変更されたら呼び出される関数なのですが、override しているわけではなかったので、これが怪しいのでは…?と思ったんですよね。
実際、KVO の処理をまるっとコメントアウトしてみたら、アプリは落ちることもなく動作したので、怪しいのはこのあたりのはず。

で、こちらを下記のように書き直しました。

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    // 実行したい処理
}

念のため、Xcode の関数補完機能を使ったので、問題はないはず。
若干、ここ以外にもコードの修正は必要でしたが、こちらを修正したところ、アプリが落ちることなく、問題なく実行できました。

とりあえず動くようにはなったので、今後は、時間があれば実際にここの処理が具体的に何をしているのかをみてみたいと思います。

 

以上、Swift の KVO 機能を修正してみた、でした。
参考になれば嬉しいです。

  • この記事いいね! (0)
著者:杉浦

ライブラリ等の英語ドキュメントの和訳サイトにほんご。の紹介

| にほんご。
 コード中でライブラリを用いるために英語ドキュメントの中身を理解する必要がでてくる時があります。google翻訳は便利ですが、ソースコードや固有名詞の和訳するべきでない部分も和訳することがあります。自分自身で和訳しながら読むのは日本語を読むより時間がかかります。”にほんご。”はそういった英語ドキュメントを和訳しているサイトです。ドキュメントの内容は最新ではないですが最終更新日が2019.01.25と精力的に活動しています。
 にほんご。では多くのオプションを持ち、成熟したライブラリのドキュメントのAPIを扱っています。最近ではChart.jsのページが特に役に立ってくれました。

  • この記事いいね! (0)
takahashi 著者:takahashi

Google+が4/2に終了。サービス終了に備えてできることまとめ。

GoogleのSNSサービス”Google+”が4/2にサービス終了予定となっています。

終了する理由としては、利用者の増加が見込めなくなった点、そして、 “Google+ People API” の不具合が原因で非公開設定にしている個人データ(名前、メールアドレス、職業、性別、年齢など)に開発者がアクセスできてしまう事件が発生し、トドメになってしまったようです。

“世界中の情報を整理する”ことを野望とし、実際に世界中の情報を整理するというかもはや牛耳る勢いで様々なサービスを出してきたGoogleですが、そんなGoogleであっても他の巨大なSNSサービスに勝つことができなかったという事実に無常観を感じます。

なお、G Suite (有料の企業向け) 版Google+は継続される予定のようです。

利用者が伸びなかったとはいえ、Google+を愛用していたユーザーは一定数いるはずです。
そんなユーザーの皆さんには、せめてデータをバックアップしておきたい、という方もいらっしゃるかと思います。

ありがたいことに、GoogleはGoogle+に限らずGoogleアカウントを利用したあらゆるサービスのデータのバックアップを取得することができる仕組みを用意しています。

バックアップを取得するには、まずGoogleアカウントの”自分のデータをダウンロード“ページへ移動します。

すると、バックアップ可能なGoogleのサービスの一覧が表示され、バックアップを取得したいサービスにチェックボックスを入れる画面が出てきます。

Google+のみをフルバックアップしたい場合はこの4項目にチェックを入れておけばよさそうです。

バックアップを取得する際には形式や取得方法などのオプションを選ぶことができます。

オプションを指定したら”アーカイブを作成”をクリックします。

アーカイブ作成中の画面へ移行します。
僕の場合はデータ量が少なかったのですぐにダウンロード可能な状態になりましたが、Google+に多くの投稿をしていたユーザーの場合はアーカイブが準備されるまで、かなりの時間がかかるかもしれません。

“ダウンロードリンクをメールで送信”を選択した場合、準備が完了するとメールが送信され、その中にある”アーカイブをダウンロード”をクリックするとこのような画面になります。

ダウンロードしたzipファイルを解凍すると、このような形でデータが格納されていました。

Twitterのエクスポートと違い、画像ファイルなどもすべて出力してくれるのはありがたいですね。
投稿もスタイルこそなかったものの完全な状態で保存できていました。

エクスポートがちゃんとできることは分かりましたが、そうはいってもサービスの終了というのはなかなか大きな影響を与えるものです。

利用者の得られなかったGoogle+ですが、同じGoogleから独立したNiantic社で開発・配信されている位置情報ゲーム”Ingress“では、Google+がエージェント(Ingressでは参加ユーザーのことを”エージェント”と呼ぶ)同士のコミュニケーションや公式からのアナウンス情報を受け取るのに欠かせないツールとなっていたようで、少なからず影響を受けるようです。

そんな状況を鑑みてIngress公式では、新たな”専用のSNS”へ移行する、という計画を立てているようです。

『Ingress』Google+終了後どうなるの!? グローバルコミュニティマネージャー アンドリュー・クルーグ氏に対策を訊く – ファミ通

新しいSNSでもGoogle+同様の役割を担わせることができるのか、注目ですね。

Google+の順次閉鎖開始まで残りわずかです。

Googleは公式アナウンスで”2019 年 3 月 31 日より前にダウンロードを開始してくださいますようお願いいたします。”としています。

Google+を使用中のユーザーの皆さんは早めにデータのエクスポートや他サービスへの移行をしておいた方がよさそうです。

  • この記事いいね! (0)
著者:杉浦

【Laravel】artisan view:cacheでBladeの中身を読めるようにする

 LarvelはBladeなるテンプレート言語を備えています。
Bladeテンプレート 5.7 Laravel
 便利は便利なのですが独自な上、説明もざっくばらんなので詳細に中身を把握するのは難しいです。
 artisan view:cacheはresources以下のBladeファイルのキャッシュを生成するコマンドです。このコマンドで生成されるPHPファイルはBladeをPHP言語にコンパイルした結果です。コンパイル後のファイルを読むことでBladeが何をやっているのか少しわかりやすくなります。
 例えば次のコードをコンパイルすると

@section('header')
@endsection
@yield('header')

@section('footer')
@show

@section('body')
@overwrite
@yield('body')

次の様になります。

<?php $__env->startSection('header'); ?>// @section
<?php $__env->stopSection(); ?>// @endsection
<?php echo $__env->yieldContent('header'); ?>// @yield

<?php $__env->startSection('footer'); ?>// @section
<?php echo $__env->yieldSection(); ?>// @show

<?php $__env->startSection('body'); ?>// @section
<?php $__env->stopSection(true); ?>// @overwrite
<?php echo $__env->yieldContent('body'); ?>// @yield

 こうやってPHPコードに直すとやっていることを追いかけられるようになり、中身を知ることが出来ます。
 @endsection, @yield, @show, @overwriteはそれぞれ@sectionと密に関わるディレクティブです。
Bladeテンプレート 5.7 Laravel#レイアウト定義
 @endsectionはsectionで定義を始めたコードの終点を示し、@yieldはsectionの出力を示し、@showはsectionで定義を始めたコードの終点であり即時展開を示し、overwriteは同名sectionの上書きを行うsection定義の終点を示します。これだけだとどういうこととなりますがコードを読むと少しわかります。@sectionの中身であるstartSectionの内容が次です。

    /**
     * Start injecting content into a section.
     *
     * @param  string  $section
     * @param  string|null  $content
     * @return void
     */
    public function startSection($section, $content = null)
    {
        if ($content === null) {
            if (ob_start()) {// ここが大事
                $this->sectionStack[] = $section;
            }
        } else {
            $this->extendSection($section, $content instanceof View ? $content : e($content));
        }
    }

 obstart()でこれ以降の出力(ブラウザに映る予定のHTMLコードなど)をバッファにため込みます。これは改めて命令されるまで出力されません。ついで@endsection,@overwriteの中身であるstopSection()が次です。

    /**
     * Stop injecting content into a section.
     *
     * @param  bool  $overwrite
     * @return string
     *
     * @throws \InvalidArgumentException
     */
    public function stopSection($overwrite = false)
    {
        if (empty($this->sectionStack)) {
            throw new InvalidArgumentException('Cannot end a section without first starting one.');
        }

        $last = array_pop($this->sectionStack);

        if ($overwrite) {
            $this->sections[$last] = ob_get_clean();
        } else {
            $this->extendSection($last, ob_get_clean());
        }

        return $last;
    }

 ob_get_clean()でバッファの内容を取得し、出力バッファを削除します。@overwriteはこの$overwrite=trueでstopSectionを呼び出しています。これにより問答無用でプロパティsectionsの末尾にバッファを書き込んでいます。@overwriteに引数がないのは必ず末尾を参照していたせいです。
 $overwrite=falseの時はextendSection()へ回って、もし以前に定義していればそちらを呼び出すようにしています。
 @showの中身であるyieldSection()、@yieldの中身であるyieldContent()が次です。

    /**
     * Stop injecting content into a section and return its contents.
     *
     * @return string
     */
    public function yieldSection()
    {
        if (empty($this->sectionStack)) {
            return '';
        }

        return $this->yieldContent($this->stopSection());
    }
    
    /**
     * Get the string contents of a section.
     *
     * @param  string  $section
     * @param  string  $default
     * @return string
     */
    public function yieldContent($section, $default = '')
    {
        $sectionContent = $default instanceof View ? $default : e($default);

        if (isset($this->sections[$section])) {
            $sectionContent = $this->sections[$section];
        }

        $sectionContent = str_replace('@@parent', '--parent--holder--', $sectionContent);

        return str_replace(
            '--parent--holder--', '@parent', str_replace(static::parentPlaceholder($section), '', $sectionContent)
        );
    }

 yieldSectionは短縮形の様なものです。stopSection、yieldContentの順に呼び出し、最後に宣言したsectionを閉じ、出力しています。
 yieldContentはプロパティ$this->sectionsの中から目当てのsectionを選び、整形して返しているのみです。
 @endsection, @yield, @show, @overwriteはBlade内部では糖衣構文として役割に応じた大きく違う名前を与えられていましたが、実際にはちょっとした違う引数で呼び出される同じ関数らであることがわかります。

  • この記事いいね! (0)
著者:ym

ロボットと人

Web サイトに対して突然大量のリクエストを投げつけてくるボット。検索エンジンのクローラ系もありますが、全く関係の無いボットもあります。

プロセスで CGI 特定したり、netstat -anl 結果から攻撃元を特定、 さらにはアクセスログと格闘していましたが、今更ですが今回は Apache の server-status 表示を”プログラム”で取得し、集計して判断をするようにしました。 これであれば、リクエスト URI や、常にポートを専有しているかの判断ができそう。

この Status モジュールによりサーバ管理者はサーバがどのくらい の性能で動作しているかを知ることができるようになります。 現時点でのサーバの統計情報を読みやすい形式で表した HTML ページが 表示されます。必要であれば、このページは自動的にリフレッシュさせる こともできます (互換性のあるブラウザを使用している場合)。 別に、現時点でのサーバの状態を単純な機械読み取り可能なリストで 表すページもあります。

https://httpd.apache.org/docs/2.4/ja/mod/mod_status.html

  • この記事いいね! (0)
村上 著者:村上

【CSS】Android、iOSでリンクをタップしたときのハイライトを無効にする方法

上司に教えてもらった方法なので、忘れないように、参考リンクもあわせてまとめ。
Android や iOS でページのリンクをタップした際に表示される、グレーのハイライトを無効にする方法です。
私の場合、react-tabs をアプリに導入したところ、iOS でページ遷移時に画面のほぼ全面が一瞬グレーがかったようになり、非常に見辛い状況でした。
それの対処法として、タブパネルにかかっていたリンクのハイライトを無効にしました。

教えてもらったリンクがこちら。

iOS や Android でリンクをタップした時に灰色の背景色が付くのをなくす CSS – Corredor
http://neos21.hatenablog.com/entry/2017/10/18/080000

 

実装方法ですが、まったく複雑なことはなく、ハイライト無効にしたい項目に下記のプロパティを追加するだけです。

a {
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}

上記を追加すると、原則全てのテキストリンクのハイライトが無効になります。

なお、iOS のみの機能ですが、ハイライトの色や透明度を指定することができるようです。
Android は無効化することしかできません。

a {
  /* 透明度50%の緑 */
  -webkit-tap-highlight-color: rgba(0, 255, 0, 0.5);
  /* 紫色 */
  -webkit-tap-highlight-color: #ff00ff;
}

指定するときは、上記のように指定します。

 

以上、リンクをタップしたときのハイライトを無効にする方法でした。
ただ、ハイライトがないと、リンクを押せたかどうかがわからないため、個人的にはあったほうがいいのでは…とも思います。
実際に使用してみて、導入するかを決めることをお勧めします。
私のように、変な場所にハイライトがかかっており、使っている時にストレスを感じる!使用感が悪い!という時には非常に有効だと思います。

  • この記事いいね! (0)
takahashi 著者:takahashi

LaravelをNginxで動作させる際の設定

LaravelではどのURLを指定されても、(自分の担当するパス配下へのリクエストであれば)Laravel自身を起動させるために必ずpublic/index.phpを経由させる必要があります。

この設定はPHPだけでは限界があるため、Webサーバー側の設定で対応する必要があります。

Laravelのパッケージにはこの”index.phpを必ず経由させる”という設定が書かれた設定ファイルがデフォルトで含まれています。
具体的には

public/.htaccess

上記のファイルがこの設定ファイルにあたります。
ところが、この.htaccessファイルは基本的にApacheなどのごく一部のWebサーバーでしか認識しないので、たとえは先日の記事のようにnginxにPHPをインストールした環境で動作させようとしても、そのままではうまく動いてくれません。

この場合、.htaccessに書かれている設定と同様の働きになる設定をWebサーバーの設定ファイルに指定する必要が出てきます。
ただし、その記述の仕方もApacheとは異なってきますので、各Webサーバー用の書き方に書き換えないといけません。

nginxの場合、.htaccessの中身をnginx用の設定に書き換えてくれるWebサービスがあり、まず最初にこのサービスを使って変換した設定ファイルを使って設定を行ってみました。

元の.htaccess

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    RewriteEngine On

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

上記サイトで変換後のnginxコンフィグ

# nginx configuration

location / {
  if (!-e $request_filename){
    rewrite ^(.*)$ /%1 redirect;
  }
  if (!-e $request_filename){
    rewrite ^(.*)$ /index.php break;
  }
}

実際に入れ込むと以下のようになります。

server {

  listen        80;
  listen        443 ssl;

  server_name  example.com;

  ssl_certificate       /path/to/ssl/fullchain.pem;
  ssl_certificate_key   /path/to/ssl/privkey.pem;

  root /path/to/docroot;
  client_max_body_size 1g;
  location / {
        if (!-e $request_filename){
                rewrite ^(.*)$ /%1 redirect;
        }
        if (!-e $request_filename){
                rewrite ^(.*)$ /index.php break;
        }      
        index index.php index.htm index.html;
  }
  location ~ \.php$ {
    if (!-e $request_filename){
        rewrite ^(.*)$ /%1 redirect;
    }
    if (!-e $request_filename){
        rewrite ^(.*)$ /index.php break;
    }
    fastcgi_pass   unix:/var/run/php-fpm.sock;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;
    allow all;
  }
}

ところが、上記のような設定を行ったところ、リダイレクトループに陥ってしまいます。

いろいろ調べたところ、Nginx向けのLaravel用の設定が公開されていました。

nginxをLaravel5.4用に設定する – Qiita

上記の記事を基に今回の場合の設定ファイルを書き換えてみます。

server{
   listen        80;
   listen        443 ssl;

   server_name  example.com;

   ssl_certificate       /path/to/ssl/fullchain.pem;
   ssl_certificate_key   /path/to/ssl/privkey.pem;

   root /path/to/docroot;

   location / {     
        index  index.php index.html index.htm;
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass   unix:/var/run/php-fpm.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}

全然違うじゃん…

やはり、ただ設定を変換しただけではうまく行かないみたいですね。

参考元の記事ではLaravel5.4となっていましたが、5.6の環境でも同様の設定で問題なく動作しました。

Laravel + Nginxの構築でお困りの方の参考になれば幸いです。

  • この記事いいね! (0)
takahashi 著者:takahashi

AmazonLinux 2 + Nginx でPHPを使えるようにする方法

Nginxはリバースプロキシとしてかなり優秀なサーバーアプリケーションで、自分も愛用しているのですが、あくまでリバースプロキシとしてしか使っていませんでした。

しかし、Nginxの本来の役割はWebサーバーですので当然Nginx自身がアプリの動作環境になることも可能です。

今回機会があってAWS EC2上のNginxで直接アプリケーションを動かす必要が出てきたので、実際にセットアップしてみました。

NginxにはApacheのようにモジュールを組み込んでPHPを動作させるような仕組みがない為、CGIを利用して動作できるようにします。
ただ、通常のCGI版PHPだと重いので、Fast CGI版のPHPが利用できるphp-fpmを利用します。

今回はPHP7.1の環境をインストールします。

まずは必要なパッケージをインストールします。

#epelリポジトリをインストール
sudo yum -y install epel-release

#remi リポジトリをインストール
sudo yum -y install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm

#nginxをインストール
sudo yum -y install nginx

#php-fpm(php7.1)をインストール
sudo yum -y install --enablerepo=remi,remi-php71 --disablerepo=amzn2-core  php-fpm
#※--disablerepo=amzn2-coreしておかないと古いphp-fpmがインストールされます。

インストールが完了したら設定していきます。

sudo vi /etc/php-fpm.d/www.conf

次の項目を編集します。

;localから参照するのでUNIX SOCKETを設定。
- ;listen = 127.0.0.1:9000;
+ listen = /var/run/php-fpm.sock

;UNIX SOCKETファイルのユーザーとグループの指定(指定しないとrootとなるが、nginxからアクセスできなくなる。)
- ;listen.owner = nobody
- ;listen.group = nobody
+ listen.owner = nginx
+ listen.group = nginx

Nginx側も設定を変更します。
Nginxでは各バーチャルホストごとの設定を定義するserverセクションに記述します。

server {

  listen        80;
  listen        443 ssl;

  server_name  example.com;

  ssl_certificate       /path/to/ssl/fullchain.pem;
  ssl_certificate_key   /path/to/ssl/privkey.pem;

  client_max_body_size 1g;
  location / {
        root /path/to/docroot;
        index index.php index.html index.htm;
        allow all;
  }
  location ~ \.php$ {
    root           /path/to/docroot;
    fastcgi_pass   unix:/var/run/php-fpm.sock;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;
    allow all;
  }
}

基本的には上記のような設定でOKです。

設定が完了したらphp-fpmとnginxを再起動します。

sudo systemctl start php-fpm nginx
sudo systemctl enable php-fpm nginx

あとはおなじみのphpinfo();をドキュメントルートに置いて、phpが実行されているか確認します。

vi /path/to/docroot/phpinfo.php
<?php
    phpinfo();
?>

あとは

http://example.com/phpinfo.php

のようにして、phpの環境情報が表示されれば成功です。

  • この記事いいね! (0)
著者:杉浦

【JavaScript】フレームワーク環境付きオンラインエディタCodeSandbox

CodeSandbox: Online Code Editor Tailored for Web Application Development
 CodeSandboxはJsFiddleなどと同じJavaScript用のオンラインエディタです。CodeSandboxの特徴は次の画像の様にフレームワークを使うことを前提とした部分です。

 上画像にある様にJavaScriptのフレームワークを広くカバーしており、サーバサイド用のフィドルにもなれます。

 自分はよくVue.jsの単一ファイルコンポーネントを使うのでJSFiddleでVue.jsを操るのは少々苦手でしたが、CodeSandboxならば簡単です。一度に複数のファイルを扱えるため、単一ファイルコンポーネントを複数集めて一つのページを作る手法がそのまま使えます。

 青色のShareボタンからコードを見せるためのリンクとHTMLコードを発行することもできます。

  • この記事いいね! (0)
takahashi 著者:takahashi

ある意味Google検索よりもすごいかもしれない。NICT “WISDOM X”

NICTが公開しているサイトに WISDOM X と呼ばれるサイトがあります。
WISDOM Xは入力されたワードをもとにインターネット上から関連しそうな情報を探し出す、いわゆる”検索エンジン”なのですが、他の検索エンジンとは異なる特徴があります。

それは自然な文で質問をするような形式で検索ができること。

例えば、”地球温暖化が進むとどうなる?”とか”なぜスペースシャトルは退役したのか”などの質問文で検索をかけることができ、WISDOM XのAIがネット上全体から質問に関連しそうな情報を集めて一覧で表示してくれます。

NICTはWISDOM Xを開発した理由として 一つの検索ワードからあらゆる情報が手に入れられるような仕組みを作ることで、 “イノベーションを促すこと”としています。

大規模Web情報分析システム「WISDOM X(ウィズダム エックス)」をWeb上に試験公開 – NICT

従来とは違う、別の切り口から検索を行うという試みもとても面白いですね。

最近調べ物で困っている…という方は是非試してみてはいかがでしょうか。

  • この記事いいね! (0)