22時に寝ようと思って2時に寝る。

備忘録や日記を書いてます。きょうは早く寝よう。

Android - FileProvider で外部アプリとファイルを共有する

FileProvider とは

Android7.0(API24, Android N)から、ファイルシステムに大きな変更が加わり、権限の仕様がより厳しいものへと変更されました。

API24 以降向けのアプリにおいて、プライベートディレクトリにアクセス制限が加わり、外部から存在、サイズ、メタデータなどの漏洩を防ぐことができます。

この権限の変更により以下のような副作用があります。

  • プライベートファイルの所有者は MODE_WORLD_READABLE および MODE_WORLD_WRITABLE を使用したパーミッションの緩和ができず、実行しようとすると SecurityException が発生する
  • 開発しているアプリのパッケージドメイン以外の file:// URIを渡すと、受け取り手がアクセスできないパスとなるため、 外部のアプリとのプライベートなファイルの共有には FileProvider の使用が推奨される

このように Android7.0 以降向けのアプリでは、Androidフレームワークによって自身のアプリ以外への file:// URIの公開ができず、 content:// URIへ変換し一時的なパーミッションを付与した上で URI をやりとりする必要があります。

ファイルに対してパーミッションを付与したり、 file:// から content://URIへ変換する最も簡単な方法は FileProvider クラスを使用することです。

FileProvider を用いてアプリ間のファイル共有を実現する

繰り返しとなりますが、自身のアプリから別のアプリにファイルを安全に共有するには、 content:// URIの形式でファイルをハンドルできるようにアプリを構成する必要があります。

Android フレームワークの FileProvider コンポーネントは、XML で指定した仕様に基づいてファイルのコンテンツ URI を生成します。具体的な手順を以下で説明していきます。

FileProvider の使用を AndroidManifest で宣言する

まず、 AndroidManifest.xml にエントリーを追加します。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.mobileapp">
    <application
        ...>
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:grantUriPermissions="true"
            android:exported="false">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_provider" />
        </provider>
        ...
    </application>
</manifest>

指定している各属性について、説明します。

android:authorities 属性

アプリのパッケージドメインプレフィックスとした命名URIの権限を設定します。ユニークである必要があるため、 ${applicationId}.provider などの名前が良いと思います。

android:exported 属性

FileProvider は公開する必要がないため false とします。

android:grantUriPermissions 属性

外部からのファイルへのアクセスを一時的に許可できるようにします。今回は、外のアプリとプライベートファイルを共有したいため、 true とします。

共有するディレクトリを宣言する

共有するファイルを配置するディレクトリを指定します。 res/xml 以下に file_provider.xml ファイルを作成し、以下の内容で記述します。

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="photos" path="photos/"/>
</paths>

この例では、 <files-path> タグでアプリの内部ストレージである files/ ディレクトリ以下のサブディレクトリを共有するようにしてます。このサブディレクトリのパスは、 Context.filesDir で取得できます。この他にも、以下のようなタグが指定可能です。

  • <cache-path>
    • 内部ストレージのキャッシュを共有でき、パスは Context.cacheDir で取得できる
  • <external-path>
    • 外部ストレージのルートにあるファイルを共有でき、ルートパスは Environment.getExternalStorageDirectory() で取得できる
  • <external-files-path>
    • 外部ストレージのルートにあるディレクトリを共有でき、パスは Context.getExternalFilesDir() で取得できる
  • <external-cache-path>
    • 外部ストレージにあるキャッシュを共有でき、パスは Context.externalCacheDir で取得できる
  • <external-media-path>
    • 外部メディアにあるディレクトリを共有でき、パスは Context.externalMediaDirs で取得できる

また、タグに含まれる属性については説明します。

name="name"

URIパスのセグメント。この値は、生成されるURIのパスに含まれるものです。

path="path"

共有するサブディレクトリ。値はサブディレクトリ名であり、個々のファイル名ではないことに注意します。ファイル名で単一のファイルを共有したり、ワイルドカードを使用して指定することもできません。

生成されるURIを見てみる

以下のように、複数のパスを指定することもできます。下記の定義の場合、生成されるURIと実態のあるコンテンツのパスを見てみます。(Providerの指定は冒頭でAndroidManifestファイルで定義したものを想定)

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="my_images" path="images/"/>
    <files-path name="my_docs" path="docs/"/>
</paths>

共有のコンテンツのURIは、

  • content://com.example.mobileapp.provider/my_images/example.jpg
  • content://com.example.mobileapp.provider/my_docs/example.pdf

コンテンツの実態のパスは、

  • com.example.mobileapp/files/images/example.jpg
  • com.example.mobileapp/files/docs/example.pdf

となります。

ファイルからコンテンツURIを生成する

コンテンツURIを使用してファイルを他のアプリと共有する場合は、FileProvider を使用して URI を生成する必要があります。具体的には以下のステップを踏みます。

  1. 新しいファイルを生成する
  2. そのファイルを FileProvider.getUriForFile() に渡す
  3. 返された URIインテントを使って別のアプリに送信する

具体的なコードは以下のようになります。

val captureFile = this.createOutputFile()
val contentUri = FileProvider.getUriForFile(activity, BuildConfig.APPLICATION_ID + ".provider", captureFile)

getUriForFile(Context context, String authority, File file) によって、共有コンテンツURIを生成してくれます。

例えば、画像ファイルを共有したい場合は createOutPutFile() の中身は以下のようになります。

fun createOutputFile(): File {
    val timeStamp = DateFormat.format("yyyyMMdd_HHmmss", Date()).toString()
    val tempFile = File( this.activity.filesDir, "/my_images/$timeStamp.jpg")
    if (!tempFile.exists()) {
        try {
            tempFile.parentFile.mkdirs()
            tempFile.createNewFile()
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }
    return tempFile
}

ここで注意したいのは、File はインスタンス化した後、実態としてストレージに空の状態で一時保存することです。

そのためにこの関数内では /my_images ディレクトリの存在を確認し、なければ親ディレクトリとして生成し、その配下にタイムスタンプをファイル名として tempFile.createNewFile() しています。

外部アプリへコンテンツURIを渡す

今回は、前項で生成した画像形式の一時ファイルをカメラアプリへ共有してみます。具体的なコードは以下です。

val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
this.cameraContentUri = createOutputUri()
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, this.cameraContentUri)
cameraIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
this.activity.startActivityForResult(cameraIntent, REQUEST_CODE)

重要なのは、外部アプリに対して共有コンテンツへの一時的なアクセス許可を与えてあげることです。今回は書き込み権限を与えるために Intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION) を指定しています。

以上が、FileProvider を用いたアプリ間のファイル共有の手順です。

参考文献

fish - rbenv で最新の Ruby をインストールする

f:id:azuuun:20181116203145p:plain

fish 環境に ruby の開発環境を構築する方法をまとめます。

github.com

実行環境

> sw_vers
ProductName:    Mac OS X
ProductVersion: 10.14.1
BuildVersion:   18B75
> brew -v
Homebrew 1.8.2

homebrew で rbenv を導入

> brew install rbenv

fish で rbenv を使う設定

vi ~/.config/fish/config.fish に以下を追記

## rbenv init setting
status --is-interactive; and source (rbenv init -|psub)

設定を反映させる

> . ~/.config/fish/config.fish

rbenv で最新の ruby を導入する

今回は 2.4.5(2018年11月16日現在の最新)をインストールします。

> rbenv install --list
Available versions:
  1.8.5-p52
  1.8.5-p113
  1.8.5-p114
  1.8.5-p115
  1.8.5-p231
...

> rbenv install 2.4.5
ruby-build: use openssl from homebrew
Downloading ruby-2.4.5.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.5.tar.bz2
Installing ruby-2.4.5...
Installed ruby-2.4.5 to /Users/hoge/.rbenv/versions/2.4.5

使用したい version を設定する

> rbenv versions
* system (set by /Users/hoge/.rbenv/version)
  2.4.5
> rbenv global 2.4.5
> rbenv versions
system
* 2.4.5 (set by /Users/hoge/.rbenv/version)
> ruby -v
ruby 2.4.5p335 (2018-10-18 revision 65137) [x86_64-darwin18]

以上です。

Gulp - v4 の series と parallel を使って直列・並列処理を制御する

f:id:azuuun:20181021234214p:plain

Gulp v4 で導入された series と parallel を使ってみました。

動作環境

$ node -v
v8.12.0
$ npm -v
6.4.1
$ ./node_modules/.bin/gulp -v
CLI version 2.0.1
Local version 4.0.0

series の使い方

series は直列(同期的とも言える)に処理を順次実行します。今回は、js ファイルのコンパイル等を行う scripts タスクと sass ファイルのコンパイルを行うstyles タスクを順次実行して動作を確かめます。

const gulp = require('gulp');

gulp.task('scripts', () => {
    return gulp.src('./src/scripts/*.js')
        .pipe(...)
        .pipe(gulp.dest('./dist/assets/js'));
});

gulp.task('styles', () => {
    return gulp.src('./src/styles/*.css')
        .pipe(...)
        .pipe(gulp.dest('./dist/assets/css'));
});

gulp.task('series',
    gulp.series(
        'scripts',
        'styles'   
    )
);

これを実行します。

$ ./node_modules/.bin/gulp series
[22:21:11] Using gulpfile ~/programming/.../gulpfile.js
[22:21:11] Starting 'series'...
[22:21:11] Starting 'scripts'...
[22:21:11] Finished 'scripts' after 357 ms
[22:21:11] Starting 'styles'...
[22:21:15] Finished 'styles' after 3.25 s
[22:21:15] Finished 'series' after 3.61 s

scripts タスクの完了を待ってから styles タスクが開始されていますね。

parallel の使い方

parallel は並列(非同期的とも言える)に処理を実行します。先程の scripts タスクは結果を styles タスクで利用しているわけではないので、実は並列で実行してしまってもよい処理でした。なので、この2つを parallel に置き換えます。

const gulp = require('gulp');

gulp.task('scripts', () => {
    return gulp.src('./src/scripts/*.js')
        .pipe(...)
        .pipe(gulp.dest('./dist/assets/js'));
});

gulp.task('styles', () => {
    return gulp.src('./src/styles/*.css')
        .pipe(...)
        .pipe(gulp.dest('./dist/assets/css'));
});

gulp.task('series',
    gulp.series(
        'scripts',
        'styles'   
    )
);

これを実行します。

$ ./node_modules/.bin/gulp parallel
[22:26:54] Using gulpfile ~/programming/.../gulpfile.js
[22:26:54] Starting 'parallel'...
[22:26:54] Starting 'scripts'...
[22:26:54] Starting 'styles'...
[22:26:57] Finished 'scripts' after 2.7 s
[22:26:57] Finished 'styles' after 2.86 s
[22:26:57] Finished 'parallel' after 2.86 s

parallel タスクの実行と同時に scripts タスクと styles タスクが並列で Starting していますね。 並列なので、全体の処理速度も先程の series の処理時間 3.61 s と比較して parralel は 0.75 s 速いです。

series と parallels を併用してみる

最近、自分が実際に実装した中で series と parallels を併用したパターンを例に取ってみます。

例えば、ビルド作業の前処理と後処理が必要な場合、これらは必ずビルドの最初と最後に実行したいので直列的に扱いたいです。一方でビルド作業自体で実行される各ビルドタスクはそれぞれ独立した処理を行うため並列的に実行しても問題ないという場合があります。

図示したものが以下です。

f:id:azuuun:20181021231358p:plain

処理の流れを通明すると、

  1. build タスクが開始
  2. 前処理として clean タスクを実行する
  3. cleanタスクが完了するのと同時に、scriptsstyleshtml タスクなどが並列で実行する
  4. それら並列で実行されたタスクがすべて終了したあと、後処理である zip タスクを実行する
  5. build タスクが終了

並列の処理はなるべく parallel でまとめて実行してあげることによって、タスク全体の処理速度の向上が期待できます。

具体的なコードは以下です。

上記コードを実行すると、

$ ./node_modules/.bin/gulp build
[23:30:04] Using gulpfile ~/programming/.../gulpfile.js
[23:30:04] Starting 'build'...
[23:30:04] Starting 'clean'...
[23:30:04] Finished 'clean' after 54 ms
[23:30:04] Starting 'scripts'...
[23:30:04] Starting 'styles'...
[23:30:04] Starting 'html'...
[23:30:04] Starting 'fonts'...
[23:30:04] Starting 'images'...
[23:30:04] Starting 'vendors'...
[23:30:04] Starting 'manifest'...
[23:30:06] Finished 'manifest' after 2.62 s
[23:30:06] Finished 'html' after 2.69 s
[23:30:07] Finished 'vendors' after 2.84 s
[23:30:07] Finished 'scripts' after 2.92 s
[23:30:07] gulp-imagemin: Minified 5 images (saved 2.91 kB - 23.9%)
[23:30:07] Finished 'fonts' after 3.36 s
[23:30:07] Finished 'images' after 3.36 s
[23:30:07] Finished 'styles' after 3.55 s
[23:30:07] Starting 'zip'...
[23:30:07] Finished 'zip' after 99 ms
[23:30:07] Finished 'build' after 3.71 s

clean タスクが Finished するのと同時に各種ビルドタスクが一斉に Starting しており、すべてのビルドタスクが終了したタイミング(今回であれば stylesが一番最後に Finished している)で 後処理である zip タスクが走っています。

以上です。

参考

gulpjs.org

デザイン組織のつくりかたを読んだ

きょうは デザイン組織のつくりかた という本を読みました。

デザイン組織のつくりかた デザイン思考を駆動させるインハウスチームの構築&運用ガイド

デザイン組織のつくりかた デザイン思考を駆動させるインハウスチームの構築&運用ガイド

  • 作者: ピーター・メルホルツ,クリスティン・スキナー,長谷川敦士,安藤貴子
  • 出版社/メーカー: ビー・エヌ・エヌ新社
  • 発売日: 2017/12/22
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログ (2件) を見る

この本を読むきっかけは、とある記事の一文でした。

どうしてデザインが大切なのか、ここ最近デザインが盛り上がっている歴史的背景を一通り話して、「あーやっぱりデザインって大事だね!」って思ってもらうまでにまずひと苦労。 (中略)だんだんめんどくさくなってきたんですよね… もうめんどくさいから、そういう説明するのはやめることにしました。この本に委ねます。

「デザイン組織のつくりかた」がめっちゃ良かったので、100冊ぐらい配ってみようかと思う | TECHNICAL CREATOR

昨今の「デザイン大事だよね」という流れの歴史的経緯を学んでいきたいというモチベーションで購入し、しばらく積読となっていました。

一通り読んでみて、いくつか学びになったところを備忘録として残しておきたいと思います。デザイン組織の構築の部分より前の、デザイン組織が必要になってきた経緯が中心です。自分なりの言い回しでメモしているため、原著との解釈が異なる部分があります。

コンシューマライゼーションの波

何十年ものあいだソフトウェアは MicrosoftOracleAdobe といった会社が作る製品だったのが、インターネットの急速な普及によって、大きく変化してきた。業種に関わらず、業務の中心にソフトウェアが存在し、インフラとなり、程度の差はあってもすべての会社はソフトウェア会社になりつつある。

ソフトウェアは性質上抽象的なものであり、ほとんどの人にとってその抽象性を理解することは容易くない。そのため、ソフトウェアの分野では「ヒューマン・コンピュータ・インタラクション」「インタラクションデザイン」「インターフェースデザイン」「ユーザビリティ」といったデザインに対して、相対的に多くの投資が行われている。

単純に作られているソフトウェアの数が増えているだけでなく、高いレベルの性能を要求される。「高いレベル」という曖昧な表現だが、ただ要求にこたえられる「すべての機能の全部盛り」ではもはや不十分である。ソフトウェアの分野はそれくらいに成熟したフェーズにあり、他社と横並びに機能するサービスを提供すれば戦略的にまずまずだった時代は終わり、体験価値の点でも競争していく段階に来た。業務や作業に使うソフトウェアの数が増えていくにつれ、ユーザーの知識も高度化し、効率的に機能するソフトウェアは評価されても、そうでないものはそもそも見向きもされなった。

そういう傾向は長い間、消費者向け(toC)の製品に限られたものだった。というのは、何を買う・使うかは個人がそれぞれに選ぶ立場にあったからだ。一方でエンタープライズ系のソフトウェアはデザインがずっとひどいものだった。というのにもいくつか理由がある。

  • 購入者が必ずしもユーザーではなかった
  • ユーザーに選択肢がなかった
  • デザインのひどさはトレーニングによって克服できると信じられていた
  • 仕事は面白くて楽しいものであってはならないからソフトウェアにもその堅苦しさを反映すべきという空気

しかし、今のエンタプライズ系ソフトウェア市場は進化しており、企業は”ひどいデザイン”のソフトウェアを使うことで生産性の足を引っ張ると悟った。エンタープライズ系ソフトウェア会社は、デザインがお粗末だと顧客を失いかねないことに気づいた。高度な知識を持つようになったユーザーは”ひどいデザイン”を我慢することを嫌うようになった。

そして、子供の頃からデジタルテクノロジーに浸かってきたミレニアル世代が社会人になってきてから、ITのコンシューマライゼーションが加速している。

Everything-as-a-Service

これまでソフトウェアは、プロダクト、つまり製品だと考えられてきた。完成すると、箱に入れてパッケージ化され販売されるか機械に直接インストールされる。しかし、常時ネットワークに接続されるようになってからの世界では、ソフトウェアが完成することはなく、より最適化され、より強化され、デプロイされ続ける

そうした変化から、今では顧客がソフトウェアそのものを手に入れることはなくなり、そのライセンスへのアクセス権を購入するサブスクリプションモデルによって収益を生み出すのが当たり前になってきた。修正され続けるソフトウェアの性質が、売り手と買い手の関係性を変えた。両者の関係が継続的なものになってから、すべての会社はソフトウェア会社であるのと同時にサービス会社になりつつある。

まだ、サービス会社になることができていないソフトウェア会社は、顧客をどう捉えて、どうやり取りするかを根本的に再考する必要さえある。今は、製品を使うために顧客はアカウントを発行し、その行動は細かく追跡されている。企業には、顧客のことをよく知り、ソフトウェアを修正し、サービスを提供し続ける責任がある。

ユーザーエンパワーメントという諸刃の剣

ただ「サービスを提供する」会社を目指せばいいわけでもない。これまでになく現状は複雑化している。1990年代半ばまでは、企業に連絡するツールは電話や FAX、または郵送を使って直接働きかけた。その後、Web や E-mail が登場し、やがてオンラインチャットやソーシャルメディア、モバイルアプリが加わり、デジタル上での顧客とのタッチポイントが爆発的に増えた。

インターネットにつながったソフトウェアはコミュニケーションだけにとどまらない。インターネットが普及する以前は、銀行であれば、ソフトウェアは主に訓練された専門の銀行員によって使用される社内ツールだった。顧客が直接アクセスできるのは ATM やテレフォンバンキングくらいで、それらでできることは基本的なものに限られていた。デスクトップから Web へのアクセスが可能になると、銀行はかつて社内システムとして公開していた機能を顧客に提供するようになった。

こうした複雑なシステムを顧客は喜んで利用した。自分で直接管理できることを高く評価した。一方の銀行も人件費の削減に役立つため、それを促進した。

だが、社内の訓練された専門の銀行員(ユーザー)は一日に何時間もそうしたツールを利用するのに対して、一般のユーザーの場合は一週間、あるいは数ヶ月の数分のために利用する可能性が高い。専門家以外の比較的使用頻度の低いユーザーに分かりやすいものを作るには、根本からじっくりと考え直す必要が出てくる。

そして、競合するソフトウェアと機能が横並びである以上、ユーザーエクスペリエンス(UX)も顧客がサービスを選ぶ際の理由になる

複雑さと単純さという正反対の性質を抱えないといけない矛盾は、携帯電話の登場でますます深刻化した。アクセスポイントを一つ増やすと、その分だけ複雑さは増す。だが、モバイルデバイスには画面の小ささや処理能力の低さなどの制約がある。その範囲内でデザインするにはさらなる合理化と単純化が必要になる

デザインのポテンシャル

ソフトウェアによってビジネスはより一層複雑さを増した。それに対処するために、企業はデザインに投資する。一方で、デザインを企業に導入する責任を負うほとんどの人はデザインが持つ力について初歩的な理解しかない。デザインを主に美的価値を高め、スタイルや外見をよくするものだと認識している。

ジョブズの有名な言葉に以下のものがある。

ほとんどの人はデザインを見た目のことだと思っているが、それは間違いだ。デザインをうわべだけのことだと勘違いしている。デザイナーには箱を渡して、「見た目をよくしてくれ!」と言えばいいのだと。私たちは、デザインとはそういうものではないと考える。どのように見えるか、どのように感じるかではない。デザインはどのように機能するかなのだ。

プロダクトデザインのコンサル会社 Ammunition の設立者のロバート氏は、「デザインはプロセスだ。イベントではない。」と語り、最近までデザインは一つの流れの中での一つのステップだとみなされてきたという。

f:id:azuuun:20181008203733p:plain

彼は、図.1 のようにデザインは単独で存在しうるものではなく、図.2 のように製品開発のライフサイクル全体に取り入れてこそ、最大の効果が発揮されるプロセスであると主張している。

f:id:azuuun:20181008203942p:plain

すべてのデザインはサービスデザイン

「サービスデザイン」という新しい領域は、企業によるデザインの活用方法をリフレーミングする。これまでのデザインは作ることに焦点を当てるよう求められてきた。サービスデザインも本質は変わらないものの、視点はもっと高く、広いものであり、作られた成果物自体を重視するより、ステークホルダーとそれらと関わるすべての活動の関係性を理解しようとする

作られた成果物は独立した存在ではなく、より大きなサービス・エコシステムのなかの一つのツールに過ぎないと考える。

さいごに

この記事は、本書籍の導入部のみの備忘録です。この後、書籍では「組織に広く貢献するデザインの力」へと解説が続きます。私が所属する会社もエンタープライズ系のソフトウェア会社の一つで、実際にデザイングループが存在し、日々製品/サービスの顧客体験を考え、提供し続けています。そういった背景があり、本書を読むことで組織の中でのデザイングループの位置付けや重要性を改めて学ぶことができたように思いますし、ITエンジニアの立場からも積極的にデザインに関わっていきたいと感じています。

以上です。

fish - Macのシェル環境を新しくした

f:id:azuuun:20180919233241p:plain

これまでシェルにそこまでこだわりがなかったのですが、身の回りの方々を見ていると、かっこいい・便利な感じにカスタマイズしている人が多く、「おっ、良さそうだな」と思ったので シェル環境を一新しました。

どのシェルを選ぶか

fish にします。

導入手順

Homebrew を使って導入します。

$ brew install fish
$ fish -v
fish, version 2.7.1

ログインシェル(デフォルトで立ち上がるシェル)を bash から fish に変更します。

$ sudo vi /etc/shells
# 末尾に以下を追加
/usr/local/bin/fish

保存した後、以下を実行します。

# ログインシェルを fish に変更
$ fish
> chsh -s /usr/local/bin/fish

これで、次シェルを立ち上げたときも fish になります

パッケージマネージャー fisher を導入する

github.com

> curl -Lo ~/.config/fish/functions/fisher.fish --create-dirs https://git.io/fisher
> fisher -v
fisher version 3.1.1 ~/.config/fish/functions/fisher.fish

個人的にとりあえず以下の2つを入れてみて便利でした

環境変数とPATHの設定

fish の環境変数の設定ではexport AWS_ACCESS_KEY_ID=HOGE1234 というような見慣れた記法が使えません。

ターミナルに直接以下のようにsetを叩くか、~/.config/fish/config.fishに以下を追記します。-x環境変数としてsetするオプションで、これがないとシェル変数として定義されます。

> set -gx AWS_ACCESS_KEY_ID HOGE1234

PATH は以下のように設定します。コロンで区切るのではなく、配列で管理されています。

> set -gx PATH $HOME/.rbenv/bin /usr/local/var/pyenv $PATH

テーマを変更する

github.com

結構、いろいろあります。今回は、oceanを入れてみます。 fisher add oh-my-fish/theme-{color-theme-name}で導入できます。

> fisher add oh-my-fish/theme-ocean
Installing 1 plugin/s
OK Fetch ocean github.com/oh-my-fish/theme-ocean
Done in 1s 558ms

フォントによっては、アイコンが Apple Emoji になったりしますが、以下のような powerline 対応のフォントを導入すると良さそうです。

fonts/Meslo LG L Regular for Powerline.ttf at master · powerline/fonts · GitHub

iTerm2 を設定する

以下から設定を選ぶか、お好みのものをインポートします。

iTerm2 > Preferences > Colors > Color Presets...

f:id:azuuun:20181116192659p:plain

自分が Ocean と合わせて使っているカラーセットは以下です。よければ、ダウンロードして使ってください。

自分のiTerm2の設定(oh-my-fish/oceanと併用)

さいごに

乗り換えてみて、とても便利ですし、いい意味で”驚きが少ない”(予想に反する挙動がない)です。また何かカスタマイズしたときに、追記したいと思います。

以上です。

参考

UIが消えて何もしなくてよくなっていく

最近読んだ2つの記事がつながって、「なるほど」と腑に落ちた。

サービス開発において「ユーザーがしたいことをできるようにさせてあげる」という議論は活発だが、いっぽうで「しなくていいことをしないようにさせてあげる」分野はまだまだ発展途上だと思う。 (中略) システムで吸収してあげれば、人間がしなくていいことはまだまだある。

しなくていいUX|小山田翔子 / GMOペパボ|note

つまり・・・

UIとかUXとか、サイコーな状態になると、使ってる側はまったくその存在を気にしなくなるのだ。

UIがサイコーになるとUIは消える|米光一成|note

サイコーな状態のUXは、「しなくていいことをしないようにさせてあげる」分野が発展していくと、徐々に増えていく。ユーザーが「しないようにさせてあげられる」システムを作れるようになりたい。

引用した記事

note.mu

note.mu

デザイン - 信頼感を持たせる色・透明感のあるデザイン

今回は、「信頼感を持たせる配色」「透明感がある配色」に着目して、カラーコードと色見本を見ていきます。

信頼感が生まれる配色

f:id:azuuun:20180917222830p:plain

一般的に、信頼・冷静といった印象を与える色は青系、安心感を与えるのは緑系の色だと言われています。

色の数を少なくナチュラルな印象

f:id:azuuun:20180917222954p:plain

冷静な印象を与える

f:id:azuuun:20180917223032p:plain

意欲的な赤色を添える

f:id:azuuun:20180917223058p:plain

緑をメインに安定感を与える

f:id:azuuun:20180917223124p:plain

参考