月別アーカイブ 7月 2019

takahashi 著者:takahashi

AndroidのGPUレンダリングを有効にすれば描画が快適になる…かも?

Androidで描画の速度が遅い…という方はGPUレンダリングの設定を行うことで改善する場合があるようです。

Androidのスクロールを大きく改善する?「GPUレンダリング」機能をONにしてみよう – TeraDas

まず、システム設定を開きます。

中からシステムをタップすると下のような画面になります。

開発者向けオプションをタップ。

“GPUレンダリングを使用” “HWオーバーレイを無効” の2項目を有効化します。

これで画面の描画に常にGPUが使用されるようになり、画面描画時のCPUの負荷が減ります。

ただし、機種によってはGPUの性能が低かったりするとかえって動作が遅くなってしまったり、CPUで処理させた方が高速だったりするケースもありますし、あまり変わらいケースもあるようです。

ON/OFFそれぞれの状態で動作を確認してみてどちらの方が動作が早くなるか確認しながら設定するといいかもしれません。

ちなみに、開発者オプションは初期状態では表示されていないので、端末情報のビルド番号を複数回タップして表示させる必要があります。

Androidスマホ/タブレットで「開発者向けオプション」をオンにする – @IT

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

【Cordova】「phonegap-plugin-csdk-image-editor」プラグインをiOSに実装する時の注意点

先週に引き続き、本日も「phonegap-plugin-csdk-image-editor」プラグインについてです。
結構苦しめられたので、二度と同じ轍を踏みたくない…ということで、未来の私のための備忘録です。

 

今回は、iOS への実装時につまづいた点について。
GitHub のページにも記載がある通り、iOS にこのプラグインを追加する際には、別途 Framework を手動で追加しなければなりません。
が、ページが更新されていないのか、記載されているダウンロード先リンクからは当該の Framework が見つからない!
これがないとプラグインのインストールすらできなくて、phonegap-plugin-csdk-client-authphonegap-plugin-csdk-image-editor を追加しようとしてもエラーが発生しているかと思います。

…ということで、まずは、この Framework のダウンロード方法について。
ダウンロードは下記の URL があったので、こちらからダウンロードしてください。

SDK · 9e4c4586e17b6462eb5e2dd556e91c8698640da9 · AppUnite / aviary · GitLab
https://git.appunite.com/appunite/aviary/tree/9e4c4586e17b6462eb5e2dd556e91c8698640da9/SDK

画面右上の方に、ダウンロードアイコンがあるので、こちらをクリックしてダウンロードしてください。
ダウンロードが完了したら、解凍しておきます。

あとは、「phonegap-plugin-csdk-image-editor」を追加したプロジェクトの plugins ディレクトリの、まずは phonegap-plugin-csdk-client-auth を開きます。
その中の src > ios ディレクトリ内に AdobeCreativeSDKFrameworks という名前でディレクトリを作ってください。
そして、この中に AdobeCreativeSDKCore.framework をコピーします。
残りの AdobeCreativeSDKImage.framework は、plugins > phonegap-plugin-csdk-image-editor > src > ios に AdobeCreativeSDKFrameworks ディレクトリを追加し、そこにコピーします。

作業は以上です。
あとは、再度プラグインのインストールをお試しください。
なお、コマンドには --save オプションを追加してください。
おそらく、これでプラグインのインストールは成功するはずです。

あとは、通常通り cordova prepare ios を実行後、Xcode で Clean → Run をお試しください。
私の環境では問題なく動作しました!

 

以上、iOS に「phonegap-plugin-csdk-image-editor」プラグインを実装する際の注意点でした。
ちょっと手間ですが…機能自体はすごく使いやすくてオススメですので、画像加工機能を実装したいときは、ぜひご検討ください。

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

カプセル化となんちゃってカプセル化のアンチパターン

 カプセル化はオブジェクト指向の中で述べられている手法の一つです。オブジェクトに関する詳しい処理や情報をオブジェクト内部に閉じ込めておき、外部からは必要な分だけのまとまった簡単な部分にのみにアクセスできるようにする方法です。よくある例えに車の例えがあります。運転手はアクセルを踏めるしギアも変えられるが、エンジンのシリンダー一つ一つや空気の流入量を操作することはできない、というものです。これは動力のカプセル化で、車の内部を深く知らず瞬時に燃料の爆発に最適な環境を計算できない多くの人間からエンジン内部の詳しい動作を隠し、まとまった操作であるギアとアクセルにだけアクセスできる様にしています。こうすることで誤った操作を減らし、操作の混乱を防ぎます。
 コーディングにおけるカプセル化は例えば次の様になります。

/**
 * @property-read int    $id    読み取りのみ可能
 * @property      string $mail  読み取りと特定形式の書き込みのみ可能
 * @property      string $name  読み書き自由
 */
class User
{
    private $id;
    private $mail;
    public  $name;
    private $secretProperty;  // 内部処理の何かしらにだけ使う完全に外から隠れるプロパティ

    /**
     * 主キーで検索.
     * @param int $id
     * @return User
     */
    public static function find(int $id): User
    {
        return DB::select()
            ->from('users')
            ->where('id', $id)
            ->first();
    }

    /**
     * 任意のプロパティにまとめて代入. 代入後の$thisと代入予定の引数が一致すればtrue, しなければfalse.
     * @param array $values
     * @return boolean
     */
    public function fill(array $values): bool
    {
        $this->name = $values['name'] ?? $this->name;
        isset($values['mail']) ? $this->setMail($values['mail']) : null;

        return $values === array_intersect_key(['name' => $this->name, 'mail' => $this->mail], $values);
    }

    /**
     * データベースに保存.
     * @return boolean
     */
    public function save(): bool
    {
        return DB::select()
            ->from('users')
            ->where('id', $this->id)
            ->updete([
                'mail' => $this->mail,
                'name' => $this->name,
            ]);
    }

    /**
     * プロパティの読み取り範囲を通常の可視性を超えて操作.
     * @param $propertyName
     * @return mixed
     */
    public function __get($propertyName)
    {
        return $propertyName === 'secretProperty' ? null : $this->$propertyName;
    }

    /**
     * setterがあるプロパティならばprivateでも書き込める.
     * setterがないプロパティならば新規追加も許さない.
     * @param $propertyName
     * @param $value
     * @return bool
     */
    public function __set($propertyName, $value): bool
    {
        $setMethodName = 'set'.ucfirst(camel_case($propertyName));

        return $this->$setMethodName($value);
    }

    /**
     * 存在しないメソッドが呼ばれたらfalseを返す.
     * @param $methodName
     * @param $arguments
     * @return bool
     */
    public function __call($methodName, $arguments):bool
    {
        return false;
    }

    /**
     * 存在するprivateプロパティに対してisset()をかまされた時にtrueを返すために必要.
     * @param $propertyName
     * @return bool
     */
    public function __isset($propertyName): bool
    {
        return isset($this->$propertyName);
    }

    /**
     * メールとして認められる文字列ならばsetして良し.
     * @param $value
     * @return bool
     */
    private function setMail($value): bool
    {
        if(preg_match('/メールアドレスを表す適当な正規表現/u', $value)){
            $this->mail = $value;

            return true;
        }

        return false;
    }
}

 id, mail, nameの三つの要素を持つユーザクラスです。それぞれの可視性と代入時の操作を設定することでカプセル化の利点の誤った操作の軽減を実現しています。プロパティの増減まで縛っているのはわかりやすさの点で微妙ですが。大体のフレームワークのモデル周りの機能にもっと洗練したものが載っているので手書きで作るよりそちらを使った方が良いです。
 カプセル化をやりたかった時に起きるアンチパターン対策として重要なのは上記の内のmailプロパティのset機能です。mailプロパティに代入する際にバリデーションが働き、mailプロパティに入っている文字列はメールアドレスとして認められる文字列だと整合性を保っています。データベースの型のみではできないバリデーションで特に有効です。この手のプロパティにアクセスする際にわざわざメソッドを増やす意味を無視するとただただカプセル化処理のめんどくささだけが残ります。
 ありがちなカプセル化っぽいことをするアンチパターンが次です。

class Engine
{
    private $gear
    
    public function setGear($value)
    {
        $this->gear = $value;
    }

    public function getGear($value)
    {
        return $this->gear;
    }
}

 ただprivateプロパティを書き換えてるだけで、こんなことをするぐらいならpublicで宣言すれば良いです。set, getメソッドの長さの分むしろ読み難くなります。これがあるあるの間違いになるのはset, getを自動で生やす機能がIDEには大体備わっているためです。適切に使えば便利なのですが、とりあえずメソッドを介してプロパティにアクセスすればカプセル化になると考える人とこの機能が組み合わせると上記アンチパターンが発生し、後に続く人がコードを読む際に苦しみます。

 正しくオブジェクト内部に留めておくと変更も楽です。これはオブジェクト内部しか影響しない、とわかりきっているコード部が増えるためです。

  • この記事いいね! (1)
asaba 著者:asaba

【react】mapで新しく配列を作る際に気を付けること

javascriptではリストとして表示したい時・リスト別に値を持たせたいときにはmapがよく使われますが、mapで

新しく配列を作る際にん?と思ったことがありました。

まず、動的にリストを作りたい場合はコンストラクタ生成時に配列を定義するのが普通ですが

ここで{}を定義するとmap is not definedで跳ね返されます。

 

なぜこうなるかというと、{}はオブジェクトを新しく作る時、連想配列を作る時、スコープに用いるといった

役割があり、通常の新しい配列を作ることに向いたmapにはカッコを変換する機能が備わっておらず

ここで不適合とみなされるためです。

なのでmapで新しくカッコを作りたい時はコンストラクタに[]を定義しておきましょう。


this.state = {

//<strong>{}</strong>ではなく<strong>[]</strong>であること
count : [],
}

render() {

{ hallo.map((hallo, index) => {

//処理

})}

}

 

普通の配列を使いたい時はmap、連想配列でmapを使いたい場合は

const map = new Map([’a’,’January’],[’b’,’February’])と書き方が変わってきます。

 

こちらはあまり実用性がないので使ったことがないですね・・・。

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

AdobeXDにAlexaのプロトタイピング機能が追加されるらしい!?

AdobeXDは、Webサービスやアプリの開発に入る前に、UIを設計・プレビューする際に大変便利なアプリです。

無料でも利用することができる上、実際にボタンを押したら別のページに飛ぶなどの動作も付けることができる”動くモック”を作ることができます。

そんなXDですが、Alexaなどの音声アシスタント用ツールのモックアップにも対応したようです。

AdobeのプロトタイピングツールXDがAlexaを統合 – TechCrunch

詳細はまだ触っていないのでわかりませんが、記事によると、XDにAlexaが搭載されていて、呼びかけた際の動作のデモや、またAxelaのXDプラグインを使って、XDで作成したスキルのモックを 実際に Alexaで試すこともできるそうです。

ここまでできるプロトタイピングツールってなかなかないと思いますので、AdobeXDがさらに開発者から手放せない存在になっていきそうですね。

Adobe XD

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

【PhpStorm】PHPSTORM 2019.2の新機能

 PhpStormの新バージョンがリリースされました。詳しく機能は次リンクです。

What’s New in PhpStorm 2019.2
 色々増えましたが自分が特に注目したのは次の3つです。
 ”Locate Duplicates on the fly”重複コードを自動検出します。共通化できるコードを自動で見つける機能です。閾値設定次第では共通化すべきでないところまで誤検出してしまいますが、気づかない内に実装してしまった共通化すべきコードを先んじて見つけてくれます。サービスとかtraitとかabstract classとかにまとめてるべきモノは後になって気づきがちなのでかなりありがたいです。
 ”Better support for Vue.js”Vue.jsのサポートが強力になりました。新機能としては注目してませんでしたが、更新した日の内に威力を感じられたので紹介。Vueデフォルトの機能の予測、検証が強力になりました。Vue.useやVue.componentなどのグローバル定義を追いかけるようになり、単体テストを考えなければかなり楽に使用ライブラリの定義が出来ます。
 ”Syntax highlighting for over 20 languages.”Ruby, Python, Goなど20以上の言語のシンタックスハイライトをカバーする様になりました。PhpStormですがPHP以外もかなりいけます。スニペットぐらいならPyCharm等を立ち上げるまでもなくPhpStormで満足に完結できます。

  • この記事いいね! (1)
asaba 著者:asaba

【react】onClick内の関数に引数を付けるのに少しコツがほしかった

タイトルの通りですが、いつも使っているためかonClickに正しく引数を付ける方法を全く知らずにここまで来てしまいました。

今回は普通にこんな感じで

 


<span class="p"><</span><span class="nt">button</span> <span class="na">onClick=</span><span class="si">{</span><span class="k">this</span><span class="p">.buttonClick</span><span class="p">(</span><span class="mi">member.count</span><span class="p">)</span><span class="si">}</span><span class="p">></span><span class="p">

 

この書き方だとonClickの機能を果たさずにrenderした瞬間に処理をして後にクリックしても無反応になってしまいます。

とりあえず公式に沿ってbindをした後に引数をつけてあげると期待した動きをしてくれるようになりました。

こんな感じ↓


onClick={this.buttonClick.bind(this, member.count)}>

 

あんまり変わっていないですね・・・。でもこれさえできれば動的に値を操作できるので応用が利きやすいのも強みですね、

onClickで引数とりたいなと思っている方には一番おすすめの方法です。

 

ちなみに公式ページがこれ(^.^)/~~~

https://reactjs.org/docs/handling-events.html#passing-arguments-to-event-handlers

 

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

【Cordova】Abobeの画像加工機能を実装できるプラグイン「phonegap-plugin-csdk-image-editor」

本来ならばこちらの記事を先に投稿するべきだったかも…。

昨日の記事で、「phonegap-plugin-csdk-image-editor」というプラグインを導入した際に遭遇したエラーについての対処法について紹介しましたが、今日はそのプラグインの導入方法についてです。

GitHub のページはこちらから。

GitHub – CreativeSDK/phonegap-plugin-csdk-image-editor: A PhoneGap plugin for the Creative SDK Image Editor.
https://github.com/CreativeSDK/phonegap-plugin-csdk-image-editor

 

実装方法ですが、まずは本命のプラグインを導入する前に phonegap-plugin-csdk-client-auth プラグインをインストールする必要があります。
で、その際に、各プラットフォームの クライアントIDクライアントシークレットが必要になるので、下記の URL から登録する必要があります。

Adobe I/O Console
https://console.adobe.io/integrations

あとは上記で登録した ID などを使って、下記のコマンドを実行します。

cordova plugin add --save phonegap-plugin-csdk-client-auth --variable CSDK_CLIENT_ID_IOS="[iOS のクライアントID]" --variable CSDK_CLIENT_SECRET_IOS="[iOS のクライアントシークレット]" --variable CSDK_CLIENT_ID_ANDROID="[Android のクライアントID]" --variable CSDK_CLIENT_SECRET_ANDROID="[Android のクライアントシークレット]"

こちらの実行が完了したら、下記のコマンドを実行し、画像加工用のプラグインをインストールします。

cordova plugin add --save phonegap-plugin-csdk-image-editor

準備はこれで完了です。
あとは、任意の場所で下記のコードを実行すればOKです。

function success(newUrl) {
    // 画像加工が成功した時の処理
    console.log("Success!", newUrl);
}
function error(error) {
    // 画像加工が失敗した時の処理
    console.log("Error!", error);
}

var imageUrl = "[加工したい画像のURI]";
var options = {
    outputType: CSDKImageEditor.OutputType.JPEG,
    tools: [
        CSDKImageEditor.ToolType.EFFECTS,
        CSDKImageEditor.ToolType.CROP
    ],
    quality: 50
};
// エディターを起動
CSDKImageEditor.edit(success, error, imageUrl, options);

メソッドやオプションについてのガイドは下記からご確認頂けます。

API guide
https://github.com/CreativeSDK/phonegap-plugin-csdk-image-editor/blob/master/docs/api.md

 

以上、Adobe Creative SDK の画像加工機能を実装できるプラグイン「phonegap-plugin-csdk-image-editor」のご紹介でした。
ただし、昨日の記事でも書きましたが、別途ライブラリの追加が必要なのでご注意ください。

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

Linux(Systemd搭載)の/tmpディレクトリの内容が破棄される時間を調べる方法

エンジニアやUNIX・Linux系のOSを触ったことがある方であれば、/tmpというディレクトリの存在はとても馴染みが深いかと思います。

/tmpディレクトリは、基本的にあらゆるLinuxおよびUNIX系OSのルートディレクトリに初めから作られています。

/tmpは、主に一時的なファイル置き場としてよく使われます。

例えば、ブラウザなどからアップロードされたファイルを正しい場所に移動するまでの間ファイルを保管しておいたり、ファイルの変換を行うために、一時的に元のファイルを置いておくファイル置き場としたり…など、とりあえずずっとは保管しない、一時的に置いておきたいファイルやディレクトリの保管場所として使うことができます。

そういった用途のディレクトリになっているので、だれでもアクセスできる代わりに、残存しているファイルはOS側のプロセスによって定期的に削除されるようになっています。

/tmpディレクトリの中身が削除されるタイミングを知るには、下記のコマンドを入力します。

sudo systemctl list-timers

すると下記のような結果が表示されます。

NEXT                         LEFT     LAST                         PASSED       UNIT                         ACTIVATES
土 2019-07-27 10:07:41 JST  19h left 金 2019-07-26 10:07:41 JST  4h 58min ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service

1 timers listed.
Pass --all to see loaded but inactive timers, too.

UNITがタイマーの名前、ACTIVATESが決められた時間が来たときに実行される処理の名前です。
NEXTに出ている時間が次回実行される時間となっています。

たとえば、なんらかのプログラムで/tmpを使っていて、本来であればファイルが存在しているはずなのにいつの間にか消えている…というときはこのコマンドでシステム側から消されていないか確認することができるようになっています。

/tmpについて困ったときは、一度確認してみるとよいかもしれません。

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

【Laravel】データベースと無関係のEloquentっぽいモデルを作るためのFluentクラス

 LaravelはEloquentクラスにモデルをまとめています。Eloquentはデータベース中のテーブルに対応して扱われることを前提としたORMです。
Eloquent:利用の開始 5.8 Laravel
 webサービスにおいてモデルが欲しい時は大体、対応したテーブルを用意するのですが、時にはデータベースに関係なくモデルを作りたい時があります。具体的には別のサービスで吐き出されたファイルの中身を扱う時などです。そういった時に手製のクラスファイルを作成するのも一つの手ですが、何かしたいことが増える度に簡単なことでも一々コードを書く必要があります。何かしら継承なりuseしたいですがEloquentを継承するのは危険です。誤った呼び出し一つで存在しない場所を参照するSQLを投げるがPHP的には正しいコードが出来上がります。
 FluentはLaravelの\Illuminate\Support\Fluentに位置しているEloquentの様なプロパティ制御とjson、array扱いの要素(ArrayAccess, Arrayable, Jsonable, JsonSerializableのinterfaceを満たしている)を持った素朴なクラスです。Laravel内部で扱われているのが基本でドキュメントなしのクラスです(Laravel4とかの頃のモデルクラスっぽい?)。Fluentのコンストラクタは次の様になっており、適宜new Fluent(パラメータ配列)をすることでデータベースに関係ないEloquentライクなモデル実体を扱えます。

    /**
     * Create a new fluent instance.
     *
     * @param  array|object  $attributes
     * @return void
     */
    public function __construct($attributes = [])
    {
        foreach ($attributes as $key => $value) {
            $this->attributes[$key] = $value;
        }
    }

 継承して、そのクラスをnewしただけでインスタンスにさせたいこと、インスタンスから知りたいことの設定が完了します。クラスだけ作って何も中身がないのに自在に動く様はEloquentを彷彿とさせます。
 簡単にnewする対象を探索する処理を入れるとなお便利です。例えば次の様なstaticメソッドを生やすことでなお扱いやすくなります。

    /**
     * ファイル名で探す。
     * @param  string $filename
     * @return mixed
     */
    public static function find(string $filename)
    {
        $disk = Storage::disk('hoge_files');
        if(!$disk->exist($filename)){
            return null;
        }
        $meta_data = $disk->getMetadata($filename);
        $body_data = self::parse($disk->get($filename));
        
        return new self(array_merge($meta_data, $body_data);
    }

 バリデータを作ってコンストラクタ中で呼び出す様な仕組みを作るとプロパティに何があるのかきっちり決まり更に更に安全安心に使えます。

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