月別アーカイブ 7月 2019

asaba 著者:asaba

【mapbox】mapboxを使っていてハマったこと

mapboxはアプリケーション向けに開発された地図ライブラリです。地図ライブラリといえばgoogleMapやOpenStreetMapがありま

すがmapboxは高速かつ比較的自由度が高くコードで自分の好きなようにカスタマイズすることができるという点が評価され様々なアプリ

に使われています。

便利なライブラリですが、各osにつき若干期待された動作と違う動きをするみたいです。

例えばandroidで大丈夫だったはずのmapboxがiosで開いた場合ページを画面いっぱいに出してページスクロールをすると、ページごとス

ワイプしてしまいます。目的の場所を探している最中も常にページが監視され続けるのでこのままだと非常に使いにくいです。

このままでは煩わしいので一から疑わしいコードを索敵することに・・・すると意外とすぐに原因を見つけ出すことができました。

どうやら、mapboxを装飾する時に定義したcssに問題があったみたいで、cordovaのようなハイブリッドアプリとmapboxを組み合わせる

場合はcssでpotision:”absolute”と定義しなければ正しく機能してくれないみたいです。

なんだよそんなことかと思いつつもcssの基本を忘れかけていたので手放しには喜べませんでした。

 

</pre>
※iosでマップ固定するプロパティ

potision:"absolute,"
<pre>

 

次の課題はページの一部に表示されたマップをスワイプ検知を回避して固定するところまでです。ここをabsoluteするとページ自体が

マップより下にいかなくなるのでより捻って対策を模索する必要がありそうですね・・・。

 

 

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

clamav と disable-unrar で warning

disable-unrar とすることで、古い ccplus でもコンパイル自体は通りますが、今度は実行じに Warning といった警告メッセージが表示される様になりました。

LibClamAV Warning: Cannot resolve: Undefined symbol "libclamunrar_iface_LTX_unrar_peek_file_header" (version mismatch?) - unrar support unavailable

オプション指定で disable-unrar をしたのですが、どうやらモジュールを作成する、しない、の disable 化の様です。

ワーニングメッセージというのことで、現状では 0.101.2 で稼働している為、問題はないのですが、いずれは消したい。なにか新しい c++ コンパイラを入れる以外に良い方法は無いだろうか。

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

【PHP】のスターリンソートがけっこうそれっぽい

 スターリンソートとはジョークソートアルゴリズムの一つです。

I came up with asingle pass O(n) sort algorithm I call StalinSort.
You iterate down the list of elements checking if they’re in order.
Any element which is out of order is eliminated.
At the end you have asorted list.
gustavo-depaula/stalin-sort: Add a stalin sort algorithm in any language you like ❣️ if you like give us a ⭐️

 スターリンソートは、要素を先頭から順番に見ていき、ソートされていない要素を発見する度に粛清することによって昇順ソートを実現します。全要素を一つずつ見るだけなので計算量はO(n)であり、高速です。

3, 6, 2, 1, 7, 10, 1, 10
↓
3, 6,       7, 10,    10
↓
3, 6, 7, 10, 10

 アルゴリズム完了時に昇順で要素が並んでいるので昇順ソートと言い張れます。入力時から要素が減っていようと昇順ソートです。(ソートの要件満たしていないし実際にはフィルターに分類されます)
 多くの言語は配列を詰めていくのでスターリンソート完了時には粛清された要素なんて最初からいなかったと思わされます。

 ですがPHPはそうなりません。

 PHPの配列は順番づけられたマップに過ぎず、キーと値はがっちり結びついており、配列が詰められることはありません。そのため次の様なことにもなります。

 紐づいた値に基づいて複数の名前が消されました。消された要素は戻ってきません。

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

【Android】複数のパーミッションをリクエストする方法

毎回書き方を忘れてしまうので、備忘録としてまとめます。
Android のアプリで、複数のパーミッションをリクエストする方法です。

今回参考にさせていただいた記事はこちらから。

Androidのパーミッションリクエスト(複数)- Qiita
https://qiita.com/tcb78/items/fd2e16eb7f1eacd0ba26

 

早速ですがコードは下記のとおりです。
onCreate() 内に下記を記述します。

private final int REQUEST_CODE = 1000;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Android 6, API 23以上でパーミッションの確認
    if(Build.VERSION.SDK_INT >= 23) {
        String[] permissions = {
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION
        };
        checkPermission(permissions, REQUEST_CODE);
    }
    // メインの処理を記述
}

なお、今回は位置情報とストレージへのアクセスをリクエストしています。
REQUEST_CODE の定義を忘れないように気を付けてください。私はよく忘れます。

次に、checkPermission() を下記のように定義します。

public void checkPermission(final String[] permissions,final int request_code){
    ActivityCompat.requestPermissions(this, permissions, request_code);
}

上記の処理を実行すると、許可されていないパーミッションのみリクエストされます。

最後に、onRequestPermissionsResult()requestPermissions() のコールバックを受け取ったときの処理を定義します。

@Override
public void onRequestPermissionsResult(int requestCode,
                                       @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {

    if (requestCode == REQUEST_PERMISSION) {
        for (int i = 0; i < permissions.length; i++) {
            if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
         // パーミッションが許可された
               Log.d("Permission", "Added Permission: " + permissions[i]);
            } else {
                // パーミッションが拒否された
                Log.d("Permission", "Rejected Permission: " + permissions[i]);
            }
        }
    }
}

もし必要であれば、パーミッション別にリクエストが許可/拒否されたときの処理を記述することもできます。
状況に応じて追加してください。

追加するコードは以上です。
あとは、設定からパーミッションの許可を無効にするか、アプリをアンインストールしてから再インストールして実行すると、パーミッションリクエストのダイアログが表示されることが確認できると思います。

 

以上、Android アプリで複数のパーミッションをリクエストする方法でした。
困ったときは、是非コピー&ペーストしてご活用ください。

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

VSCodeでパンくずリストを有効にする方法

有料のPHP用IDE”PHP Storm”には、カーソルの現在地がプログラムのどの位置に居るのか(どのクラスのどのメソッドの中にカーソルがあるか、など)を”パンくずリスト”の形で表示してくれる機能があります。

長いコードを見ているとしばしば今自分がどの位置にいるかわからなくなることがあるので、この機能はあるととてもありがたいです。

さて、この機能、有料のIDEにしかない便利機能かと思いきや、実はオープンソースのエディタ(という名のほぼIDE)のVSCodeでも使用することができます。

VSCodeでパンくずリストを表示するには、VSCodeの設定画面から有効にする必要があります。

まず、右下の歯車アイコンから”設定”をクリックします。

すると下のような設定画面がでてくるので、検索欄に breadcrumbs.enabled と入力します。

すると設定がフィルタされるので、その中から赤枠の

Breadcrumbs: Enabled

の項目のチェックボックスをオンにします。

これで設定は完了です。

あとはフォルダごと開いた状態でプログラムを確認すると…

VSCodeでもパンくずリストが表示できます…!

このパンくずリストがあるだけで、コーディング中に”遭難”する率がかなり減るので、VSCodeを使っている方は是非一度試してみてください。

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

Apacheでは1つのpemファイルに中間証明書をまとめてあっても別で中間証明書を指定する必要がある件

最近新しいサーバーをセットアップし、その上でApacheをセットアップし、新しいサイトを構築しました。

そのサイトへはPCやスマホのWebブラウザからは問題なく閲覧できていたのですが、何故かアプリのWebviewからアクセスできないという問題が発生していることが判明。

具体的には、Webview側でサイトへアクセスしようとするとステータスが”Cancelled”になる、というもの。

いろいろ調べたところ、どうやら平文では問題なく閲覧できてはいるものの、SSL(https)経由になると何故か正常に見ることができないことがわかりました。

そこで、SSL通信のチェックサービスを使って、SSLの状態を調べてみました。

SSLチェック【証明書・プロトコル・暗号スイート確認】 – cman

結果、証明書の認証チェーンに問題があることがわかりました。

ApacheではSSLの証明書の指定を行う際、下記のように書きます。

SSLCertificateFile /etc/letsencrypt/live/example.jp/fullchain.pem
SSLCertificateChainFile /etc/letsencrypt/live/example.jp/chain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.jp/privkey.pem

今回構築したサーバーではSSL証明書にLet’s Encryptを使用しており、Apacheに入れる設定としては上記のようになります。

fullchain.pemについては1ファイルに証明書本体と中間証明書も含まれているのですが、Apacheではそのようには認識してくれず、中間証明書は別で指定する必要があります。

その中間証明書の指定が2行目の SSLCertificateChainFile の記述になります。

今回の場合、2行目のSSLCertificateChainFile が抜けていたことで証明書のチェーンが壊れてしまっていたのが原因だったのですが、PCやスマホのブラウザで見るとOSがチェーンを補完して問題なく見れてしまうため、アプリでつなげようとしてようやくエラーに気付いた形でした。

SSLを使うサイトを立ち上げた際は、ブラウザでのチェックだけでなく、ご紹介したSSLチェックツールなどでもテストしておいた方が確実かもしれません。

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

clamav と libunrar

少し前からコンパイルが出来なくなってしまったので、調査していましたが、最終的に .rar 圧縮なんて滅多に見ないじゃん?(exe でも中身は rar の可能性はあるが。)

-Wno-logical-op-parentheses
-Wno-dangling-else

この2つのオプションが関連しているところは libclamunrar です。
ということで disable にすることにしました。

./configure --prefix=/usr/local/clamav --enable-milter --enable-clamdtop --disable-unrar

いままで 0.100.3 を使用していましたが、次からは 0.101.2 にアップ。

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

テーブルと1対1になるモデル以外のモデルを増やす時

 webプログラミングのMVCデザインパターンにおいてモデルとは大体DB(データベース)のテーブルそのものです。しかもモデルとテーブルは1対1のことがほとんどです。これはフレームワークがそう扱った方がやりやすい様に自動生成コマンドやクラス、メソッドを仕込んだり、例を用意しているからというフレームワークの用意した道筋が一因です。これは悪いことでなく実際、簡単なロジックを扱うプログラムならばモデル1つはテーブル1つとした方がシンプルにまとまり直感的なコードで要件を満たすことになり、いいことづくめです。無暗にリポジトリやらエンティティやらの概念を持ち込んで一つのテーブルにアクセスするのに二つ三つもクラスやメソッドを経由させられるより遥かに賢明です。
 しかしデータベースのテーブルと1対1だとどうにも収まりが悪い時があります。

 例えば、1つのユーザアカウントで様々なサービスの恩恵を受けられるプログラムの時です。こういった時、ユーザは何かを購入する、何かにメールを送る、何かを出品する、ブログを書く、などさまざまな操作をします。これらの操作がある上で、usersテーブルは一つだからモデルはUser一つだけ、とするとUserモデルは大爆発します。こういった時には各処理におけるUserモデルである購入者モデル、メール送信者モデル、出品者モデル、ブロガーモデル、を用意して全てusersテーブルに対応させる様にすることで対応できます。
役割駆動設計で巨大クラスを爆殺する – Qiita
 例えば、しょっちゅうまとめて参照されるテーブルがある時です。こういった時は複数のテーブルをselect, joinするクエリを必ず発行するモデルを作ることで対応できます(DB上でview作ってそれを読みこむのもありかも)。エンティティ(参照オブジェクト)の考え方はこういった時、役に立ちます。
【PHP】Adapterパターンであるカラムの値によって大きく振る舞いを変えるテーブルの扱いを多少マシにする – 株式会社シーポイントラボ | 浜松のシステム開発会社
 例えば、そもそもDBを参照しないがデータを参照する時です。ある外部サービスから吐き出されたファイルを読みこんで扱う時にはDBに関係ないモデルを用意してファイルの情報を持たせる様にするべきでしょう。
【Laravel】データベースと無関係のEloquentっぽいモデルを作るためのFluentクラス – 株式会社シーポイントラボ | 浜松のシステム開発会社
 例の様に単にデータを扱うモデルを考えるだけでも、こういった複雑な時にはテーブルと1対1になるモデル以外のモデルを作った方がやりやすいです。
 原義に基づくならばMVCのモデルとは”業務領域のデータと振る舞い”です。データベース設計が優れていてそれで設計が完結できる時は、モデル=DB関連の操作をまとめたモノとするのが正しいし適した形ですが、DB上で扱うとどうにも複雑になる時は”振る舞い”も別途モデル化するのが良いでしょう。
 余談ですが、振る舞いのモデル化はサービス化です。振る舞いの含意は広い為、多くの動作がサービスと言えなくもないです。サービスと定義できるからと何でもかんでもサービス化すると、オブジェクト指向を実現するためのMVCなのにオブジェクト指向から離れて手続きプログラミングと化します。なるべくサービスにせず、より適した場所を見つけたいものです。

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

【Cordova】写真からExif情報を取得するプラグイン「cordova-exif」

今回は、写真から Exif 情報を取得するためのプラグイン「cordova-exif」について。
以前は JavaScript を使って取得していたのですが、色々修正することになったので併せてこちらも修正しました。

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

GitHub – guilhermefarias/cordova-exif: This plugin, is the simplest way to get exif data of images at Cordova platform (Phonegap)
https://github.com/guilhermefarias/cordova-exif

 

実装方法ですが、まず下記のコードを実行します。

cordova plugin add https://github.com/domax/cordova-exif.git --save

なお、このプラグインを使うには cordova-plugin-cameracordova-plugin-file が必要です。
インストールされてない場合は、自動でこれらのプラグインもインストールされます。

ただし、プラグインのバージョンによっては競合が起こる事もあり、私の環境ではカメラプラグインのバージョンが新しすぎたようでエラーになりました。
そのため、最新のカメラプラグインやファイルプラグインを既にインストール済みの場合は、問題がなければ一度削除してから cordova-exif をインストールすることをおすすめします。

インストールが完了したら、あとは下記のコードで Exif 情報を取得できます。

CordovaExif.readData(imageURI, function(exifObject) {
  console.log(exifObject);
});

取得できるデータ一覧は上の GitHub のページに記載されているので、分からなくなった場合はご確認ください。

なお、カメラプラグインと合わせて使う場合は下記のように書きます。

function onSuccess(imageURI) {
  CordovaExif.readData(imageURI, function(exifObject) {
    console.log(exifObject);
  });
}
function onFail(message) {
  alert('Failed because: ' + message);
}
var options = {
  sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
  quality: 50,
  encodingType: Camera.EncodingType.JPEG,
  destinationType: Camera.DestinationType.FILE_URI
}
navigator.camera.getPicture(onSuccess, onFail, options);

なお、上記のプログラムでは、フォトアルバムから写真を選択するようにしています。

気を付けたい点としては、カメラプラグインのオプションで correctOrientationtrue に設定し、画像を正しい向きに直す処理を追加すると、取得できる Exif 情報が減りました。
私は写真から緯度経度を取得したかったので、上記の理由から correctOrientation を追加するのをやめました…。
なお、写真の向きは取得できたので、そちらで正しい向きに直す処理を追加することはできます。

 

以上、写真から Exif 情報を取得するためのプラグイン「cordova-exif」についてのご紹介でした。
インストール時に若干手間取りましたが、便利なプラグインですので是非ご活用ください。

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

【react-material-Ui】ListとDialogを組み合わせて動的に削除するコンポーネント

window.confirmは簡単な実装でOK/キャンセルの処理を作ることが出来ます。しかしその汎用性に反し対応していないosが多く

ちゃんと発動するか不明な点が多いことと、ESLintで引っかかることもありストア向けのアプリには不向きです。

最初見つけた時はこれめっちゃ便利じゃん他のアプリにも入れたろと考えましたが

reactではandroidやiosでwebviewを介してみるので爆弾扱いされているみたいですね。

てな訳で素直にdialogを使いましょうということにしました。

material-uiではスタイリッシュなコンポーネントがずらりと揃っていますが今開発しているアプリでも

使われているmaterial-uiのdialogコンポーネントを使うことにしました。(こっちのほうがずっとかっこいいです)

 

</pre>
choice(i){
this.setState({index: i});
this.setState({deleteMessage : "削除しますか?"})
this.setState({deleteOpen: true});
}
delete() {
const i = this.state.index;
this.state.count.splice(i,1);
this.setState({count: this.state.count});
this.DialogClose();
}
deleteDialogClose() {
this.setState({deleteOpen: false});
}

render() {
const i = this.state.count;
const reText = i;
const deleteActions = [
<FlatButton
label="削除する"
primary={true}
onTouchTap={this.delete}
/>,
<FlatButton
label="キャンセル"
primary={true}
onTouchTap={this.deleteDialogClose}
/>,
];
return (
<Dialog
actions={deleteActions}
modal={true}
open={this.state.deleteOpen} >
{this.state.deleteMessage}
</Dialog>
)
}
<pre>

 

render内でダイアログのオプションを設定してreturn内でそのオプションを取り込んで実際にトリガーが発火

した時にダイアログの処理内容を引数に合わせて変えていくイメージで作りました。

最初はどこで発火するんだ?と迷子状態ですが、this.setState({Open: true});でon状態になるとダイアログが

起動することが分かったので一安心。

 

とりあえずthis.setState({Open: true});で発火することを覚えておけば適当な関数にこれを設置して

さきほど切り分けた処理を実際に試すことができるみたいですね、覚えておきます。

ちなみにメッセージはthis.setState({Message : “hoge!!”})で変えられますのでそちらもお見知りおきを・・・。

 

使ってみた感想:良かったです。従来のjsのダイアログより優しい・安心のmaterial-uiブランドなので視覚的に優しいと

優しい尽くしでした。とくに凝ったデザインにしないならば第一におすすめします。

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