スマートデバイスアプリ開発のあれやこれや

Re:VIEW StarterのA4対応

 脱Wordを掲げてAsciidocを使う日々が終わりそうです。

qiita.com

 Asciidocも悪くないのですが,以下の点が気になっていたのでこれを期にRe:VIEWに乗り換えようかと思っています。

  • 英語(例: Amazon Web Services)を入れると変にスペースが出来る
  • PDF出力すると文字装飾が上手く働かない時がある

 ただ,会社での用途はA4サイズのレポート作成なので,Re:VIEW Starterが対応しているB5 or A5サイズだと都合が悪いのです。というわけで,Re:VIEW Starterが生成するファイルを変更してA4対応やってみました。

config.yml

texdocumentclass: ["jsbook",
    #"uplatex,papersize,twoside,b5j,10pt,openright" # B5 10pt 右起こし
    #"uplatex,papersize,twoside,b5j,10pt,openany"   # B5 10pt 両起こし
    #"uplatex,papersize,twoside,a5j,9pt,openright"  # A5  9pt 右起こし
    #"uplatex,papersize,twoside,a5j,9pt,openany"    # A5  9pt 両起こし
    #"uplatex,papersize,oneside,a5j,10pt,openany"   # A5 10pt 両起こし(タブレット向け)
    #"uplatex,papersize,twoside,b5j,10pt,openright"
    "uplatex,papersize,twoside,a4j,10pt,openright" # A4対応
]
#

sty/mytextsize.sty

%% 本文の幅を設定
\setlength{\textwidth}{50zw}  % 全角44 --> 50文字 出力結果みて調整する
\setlength{\fullwidth}{\textwidth}  % ヘッダの幅を本文と同じにする

これでそれっぽくなります。

Firebaseに入門してみた

 あけましておめでとうございます。今年は公私共に実りのある1年にするべく,決意を新たに頑張りたいと思います。Qiitaやはてなブログでのアウトプット,GitHubでのソース公開も積極的に行っていきたいですね。(今の会社からそろそろ巣立とうかと考えながら……)

 年始の時間を利用して,前から触ってみたかったGoogleのmBaaSであるFirebaseを試してみました。ホスティング機能だけしか触れていませんが,Googleアカウントさえ持っていればCLIから簡単にアプリをデプロイ出来て便利ですね。 今回はVue.jsで作ったアプリ(Vue CLIが生成するデフォアプリ)をFirebaseにデプロイしてみたので,忘備録がてら手順を書いてみたいと思います。

前提環境

  • node.js: 8.9.4
  • npm: 6.5.0
  • Vue CLI: 3.2.2

1. Firebase Consoleからプロジェクトを作る

 ブラウザからFirebase Console(https://console.firebase.google.com/u/0/?hl=ja)にアクセスしましょう。トップページから「プロジェクトを追加する」を選択し,任意の名前でプロジェクトを作成しましょう。ここで入力したプロジェクト名+乱数がアクセス先のURLになります。

2. Firebase Toolsをインストールする

 Firebaseの操作をCLIから行うためのツールFirebase Toolsをnpm経由でインストールしましょう。

npm install -g firebase-tools

3. 公開対象のアプリを作る

 ここは単純にVue CLIを任意の設定で実行していただければOKです。今回は雛形アプリをそのまま使うのでbuildコマンドで最終成果物まで生成しておきます。要点としては,最終成果物はdistディレクトリに出力される点だけ覚えておきましょう。

4. Firebaseにログインする

 ここからFirebase Toolsを使っていきます。

firebase login

 まずはログイン処理です。Vue CLIで作成したプロジェクトのルートで上記のコマンドを実行します。すると,ブラウザが起動してFirebase ToolsとGoogleアカウントの紐づけ処理および権限委譲のダイアログが表示されるので,基本的にOKで前に進めていきましょう。成功すると,コンソールに以下のメッセージが表示されるはずです。

Waiting for authentication...

+  Success! Logged in as xxxxxxxxx@gmail.com

5. Firebaseプロジェクトを初期化する

 続いてVueプロジェクトをFirebaseプロジェクトとして初期化します。

firebase init

 Firebaseのどの機能を使うのか聞かれるのでHostingを選択します。

firebase init

     ######## #### ########  ######## ########     ###     ######  ########
     ##        ##  ##     ## ##       ##     ##  ##   ##  ##       ##
     ######    ##  ########  ######   ########  #########  ######  ######
     ##        ##  ##    ##  ##       ##     ## ##     ##       ## ##
     ##       #### ##     ## ######## ########  ##     ##  ######  ########

You're about to initialize a Firebase project in this directory:

  C:\development\firebase\sample_app

Before we get started, keep in mind:

  * You are currently outside your home directory

? Are you ready to proceed? Yes
? Which Firebase CLI features do you want to setup for this folder? Press Space to select features, then Enter to confi
rm your choices. Hosting: Configure and deploy Firebase Hosting sites

=== Project Setup

First, let's associate this project directory with a Firebase project.
You can create multiple project aliases by running firebase use --add,
but for now we'll just set up a default project.

? Select a default Firebase project for this directory: [don't setup a default project]

=== Hosting Setup

Your public directory is the folder (relative to your project directory) that
will contain Hosting assets to be uploaded with firebase deploy. If you
have a build process for your assets, use your build's output directory.

? What do you want to use as your public directory? dist
? Configure as a single-page app (rewrite all urls to /index.html)? Yes
? File dist/index.html already exists. Overwrite? No
i  Skipping write of dist/index.html

i  Writing configuration info to firebase.json...
i  Writing project information to .firebaserc...

+  Firebase initialization complete!

 注意すべき箇所があるとすれば以下ぐらいです。

? What do you want to use as your public directory? dist
? Configure as a single-page app (rewrite all urls to /index.html)? Yes
? File dist/index.html already exists. Overwrite? No
  • デプロイ対象は「dist」ディレクト
  • SPA用にWebサーバのrewrite設定を追加する
  • index.htmlを上書きしない

6. デプロイする

 超簡単。

firebase deploy --project [projectId]

 projectIdはFirebase Consoleから確認できます。

=== Deploying to 'xxxxxxxxx'...

i  deploying hosting
i  hosting[xxxxxxx]: beginning deploy...
i  hosting[xxxxxxx]: found 8 files in dist
+  hosting[xxxxxxx]: file upload complete
i  hosting[xxxxxxx]: finalizing version...
+  hosting[xxxxxxx]: version finalized
i  hosting[xxxxxxx]: releasing new version...
+  hosting[xxxxxxx]: release complete

+  Deploy complete!

Project Console: https://console.firebase.google.com/project/xxxxxxx/overview
Hosting URL: https://xxxxxxx.firebaseapp.com

 5分ほどで環境構築からデプロイまで終わってしまいました。Firebase……恐ろしい子ッ!!

Mint60を作ってみた

 ゆかりさんが販売されている自作キーボードのMint60を買いました。元々,職場ではMistelのBAROCCOを使っていたのですが「自宅でも分離型のキーボードが使いたい!」という思いから,電子工作初心者にも関わらず組み立てにチャレンジした次第です!

www.archisite.co.jp

 今回は電子工作初心者目線で,Mint60を組み立てた感想を書いてみます。結論を最初に述べると「電子工作初めてでも完成までたどり着けるよ!!」と初心者の方に伝えたいです。せっかくはんだごてを購入したので,キーボード以外のものも作ってみたいなと思うようになりました。

私の電子工作経験

  • 最後に半田付けしたのは中学生の頃
  • 電子工作の道具は今回初めて買った

使った機材

  • はんだごて
    • 温度調整機能付きのものを購入しました

白光 ダイヤル式温度制御はんだこて FX600

白光 ダイヤル式温度制御はんだこて FX600

  • こて先
    • 2Cサイズが重宝します

  • こて台
    • スチールウールではんだを掃除出来るのでコテ先の温度低下を防止できます

白光(HAKKO) こて台 633-01

白光(HAKKO) こて台 633-01

  • ハンダ
    • 片手でハンダを引き摺り出しながら使えるので便利でした

goot 電子工作用はんだ SD-63

goot 電子工作用はんだ SD-63

  • リードベンダー
    • ダイオードを大量に折り曲げる必要があったので購入しました
    • ジャスト間隔で針金を曲げられるのでダイオードの浮きを防止出来ます
    • 途中まで使い方を間違えていました。裏側の溝を使いましょう

電子工作初心者ゆえの困惑

  • はんだをどれだけの量盛っていいのか分からない……
  • 基盤を焦がさないか心配になる

はんだづけのポイント

  • はんだごての温度は370℃程度であれば焦げたりしない
  • コテ先(C2)の平らな部分ではんだを溶かす
    • そこから重力で滑らせるイメージを持つ(適量が自然と流れ落ちる)
    • ぷっくらするまではんだを垂らさなくてOK
  • こまめにコテ先のはんだ付着を落とす
    • ↑で紹介したコテ台はコテ先を拭いても温度が下がらないので便利です

完成後に気付いた不具合

  • 右側の下段(N~?ぐらいまで)が反応しない
    • ケースと合体すると高確率で反応しない。ケース外すと復活。
  • 「Y」が反応しない

対策

  • 右側下段が反応しない問題
    • 他の方も書いておられますが,LEDテープとキースイッチの足の干渉でした
    • はみ出ているキースイッチの足をニッパーで切り落としたら直りました
  • 「Y」が反応しない
    • ダイオードの設置が一箇所漏れてる……
    • キースイッチも全部はんだづけ終わっていたので絶望的な気分になりました
    • ダメ元で説明ページとは逆方向から基盤にダイオードをはんだづけしたら……成功!

使用感

  • 静音赤軸を初めて使ってみたが,その名の通り静かで素晴らしい
  • スタビライザが内蔵されているキーはちょっとだけ音が気になる
  • キー配置が普段使っているものと違うのでなれるまで時間かかりそう

AsciiDocでテーブルの中に画像やコードを表示したい!

 AsciiDocが便利なので近頃ちょくちょく活用しています。もうWordやExcelには戻りたくないほど感動的な体験で,「今後作る設計書は全てAsciiDocで作ってやろう……!」と堅く心に誓ってしまうほどです。どの部分に惹かれるかは人それぞれですが,私にとっては以下の特徴が魅力的に感じました。

  • 表紙や目次を持ったフォーマルな文書作成をサポートする機能が多い
  • 下手にWordで頑張るより小奇麗なファイルが生成される
  • ドキュメント作成時のデザイン崩壊事故が起きにくい
    (デザイン定義が別ファイルになるので基本触らない)
  • ソースコードのSyntaxHighlightが効く

 そんなわけで便利なAsciiDocなのですが,ちょっと困ったことがあったので今日はその紹介を……。

テーブルの中に画像を表示したい!

 要するに↓みたいなことをやりたかったのです。

f:id:cross-xross:20180616080352p:plain

 でも普通にAsciiDocを書くと

|===
|1-1|2-1

|image::sample.jpg[width="100", align="center"]
|2-2

|1-3
|2-3
|===

f:id:cross-xross:20180616080744p:plain

 こんな感じで残念な表示をされてしまいます。

対策は……?

 意外と簡単に対策できました。

|===
|1-1|2-1

a|image::sample.jpg[width="100", align="center"]
|2-2

|1-3
|2-3
|===

 内部でAsciiDocの文法を解釈させたいセルの直前に「a」を追加します。

f:id:cross-xross:20180616080352p:plain

 出た!

 画像だけでなくSyntaxHighlightも効くので↓みたいなことも可能です。

f:id:cross-xross:20180616081535p:plain

別解

 テーブルのヘッダ定義部分をイジっても同じことが出来ます。

[cols="1a,1"]
|===
|1-1|2-1

|image::sample.jpg[width="100", align="center"]
|2-2

|1-3
|2-3
|===

 特定列だけ常にAsciiDocを解釈して欲しいなら,こちらの方がラクですね!

ReactNative事始め

 必要に迫られてReactNativeを最近触っています。慣れるとサクサク画面が作れるので,ちょっと可能性を感じています……! SwiftやKotlinといったNative言語での開発も愉しいですが,こういった高速開発がしやすいツールも使えると活躍の幅が広がるのではないかと思っています。プロトタイピングの時なんかに使ってもいいんじゃないでしょうか。※本開発でも使える品質だと思いますが。

ReactNativeとは?

 ReactNativeは,facebookが開発しているオープンソース(MIT)のスマートデバイスアプリ開発ツールです。SPA開発ツールであるReact.jsの知識をベースにして,iOSAndroidのNativeアプリケーションをワンソースで開発可能です。facebookアプリやInstagramアプリ,AirBnBアプリといった有名アプリの開発でも採用されており,十分実用に耐えうる品質を備えたツールだと思います。そんなReactNativeの特徴は以下です。

  • Reactの知識をベースに開発できる
  • NativeのUIコンポーネントが利用できる
  • ホットリロードで高速開発できる

(1) Reactの知識をベースに開発できる

 Reactの特徴として「Learn once write anyware」という言葉がよく使われます。Javaも昔似たようなことを言われてましたね。一度流儀を理解すれば,それを他の開発(スマホアプリやVRアプリ)でもいい感じに活用できる……というのがコンセプトで,ReactNativeもその流儀に則ったツールと言えます。

  • ReactNative: Reactの流儀でNativeアプリが作れる
  • ReactVR: Reactの流儀でWebVRアプリが作れる
  • ReactNative for Web: Reactの流儀で抽象化された開発方式でWebアプリが作れる

 Reactを触ったことがあるならば,少ない学習コストで開発をスタート出来ることは間違いないです。JavaScriptの知識ではなく,Reactの知識が前提になる点は注意です。

(2) NativeのUIコンポーネントが利用できる

 ReactNativeでは,Apache CordovaのようなHybridアプリ開発とは違い,画面描画をNativeの技術で行います。具体的に言うと<Button>タグを使った場合,iOSではUIButtonクラスを使って画面描画されますし,AndroidではButtonクラスが使われます。アプリ側が勝手に作った非標準のUIコンポーネントではなく,利用者が慣れ親しんだ標準UIコンポーネントで画面を作れる――パフォーマンスやユーザビリティの面でも大きなメリットがある方式です。

(3) ホットリロードで高速開発できる

 Nativeアプリを開発する際に困るのがビルド時間が長くなることです。ちょっとした修正でもリビルドで数分待たされるとヤル気が下がるのではないでしょうか。ReactNativeは,ホットリロードという仕組みを採用しており,JavaScriptファイルの差し替えだけでアプリが更新されるので,サクサク高速にアプリ開発を進められます。

f:id:cross-xross:20180606215811p:plain

ReactNativeの始め方

 cliコマンドから雛形プロジェクトを生成出来るので活用しましょう。

npm install -g react-native-cli

 他のcliツールとしてcreate-react-native-appも在るのですが,Nativeコードを含むReactNative用のOSSライブラリの導入が面倒だったり細やかな変更が難しい点からreact-native-cliの方を推奨したいです。※create-react-native-appだと変更頻度が低いファイルを隠蔽した形で雛形が生成されるため,初心者が混乱しにくいというメリットも存在します。

react-native init MyProject
cd MyProject
react-native run-ios

 上記のコマンドで雛形アプリが起動します。

react-native run-android

 Androidの場合は先にAndroidエミュレータを起動しておく必要がある点に注意です。

EcmaScript5でのクラス実現パターン

はじめに……そして,結論

 調べた結果,以下のように書くのが一番ベターっぽい気がしてきました。

var MyClass = function() {
  //Privateな属性
  const privateValue = "private";
  const privateMethod = function() {
    console.log("private");
  }
  //Publicな属性
  const F = function() {};
  F.prototype.publicMethod = function() {
    privateMethod();
    console.log("hogehoge");
  }
  return new F();
}

Optional型活用のすゝめ

はじめに

niwaka.hateblo.jp

 Streamの話を↑でしましたが,コードレビューで指摘する内容として「Optional型を上手く使いましょう」という話もよくしています。Optional型もJava8から登場した比較的新しい文法になりますが,nullを扱う場合に便利になるので積極的に活用していきたいところです。

Optional型=nullかもしれない値

 Optional型はJava8から追加された新しいクラスです。どういうケースで使うといえば,nullを返却する可能性があるメソッドの戻り値型として採用すると良いでしょう。まず,従来の文法で説明してみます。

private MyEntity convertToMyEntity(String name) {
    if (name.equals("Apple")) {
        return new MyEntity("name");
    } else {
        return null;
    }
}

 引数で与えられる文字列が"Apple"の時以外はnullを返します。このメソッドを使う側は,処理結果としてnullが返ってくるかどうかをどうやって判定するのでしょうか? 呼び出し先のソースコードがあるならば,そちらを見れば良いでしょうが対象クラス・メソッドがjarファイルになっているケースもあります。なにより毎回ソースコードを当たらないとnullが返るかどうか分からないというのは面倒です。そういう時に使ってほしいのがOptional型なのです。

private Optional<MyEntity> convertToMyEntity(String name) {
    if (name.equals("Apple")) {
        return Optional.of(new MyEntity("name"));
    } else {
        return Optional.empty();
    }
}

 こんな感じで戻り値型をOptional型でラッピングして返却します。”これ,なんの旨みがあるの?”と思いますよね。Optional型のミソはラッピングされた値を取り出すところにあります。Optional型から元のMyEntity型を取得するコードは以下のようになります。

Optional<MyEntity> entity = convertToMyEntity("Apple");
entity.ifPresent(e -> {
    //e=MyEntity
});

 値を取り出す際にnullチェックを強制出来るという点が最大の特徴です。このルールをチームメンバーで共有しておけば,少なくとも自前で作成したコード部分については

  • Optional型=nullが返ってくる可能性がある
  • 非Optional型=nullは返ってこない

 といった方針でコーディングが出来るのではないでしょうか。※getメソッドでチェックすることなく強制的に中身を取り出すことも出来ますが,例外が飛ぶので禁止しましょう。コードレビューでの注視ポイントだと思います。

 個人的には最初は↑の箇条書きの方針で採用していけば良いと考えていますが,ある程度Optional型に慣れてきたらもう一検討して欲しいです。最初に述べた通り,Optional型は相手にnullチェックを強要出来ます。逆に言うとnullでも構わないようなケースは別にOptional型である必要はないでしょう。nullを扱うためにいちいちアンラップするのも面倒ですから。検査例外と非検査例外……みたいですね。

戻り値以外でOptional型を使うのはNG

 「Optional型,便利じゃん!」ってなってきましたか? 便利なOptional型ですが使う場所は限定しましょう。Optional型に慣れてきた頃にやりがちなミスですが,フィールドの型としてOptional型を使ったりメソッド引数としてOptional型を使うのは止めるべきです。

private Optional<String> option;
    
private void doSomething(Optional<String> args) {
    //なんかの処理
}

 理由は2点です。

  • 再代入できる様式だと考慮すべきパターンが増える
  • 引数でOptional型を与えるメリットが誰にもない

 前者「再代入できる様式だと考慮すべきパターンが増える」はフィールド型として使う場合の話です。再代入可能なOptional型を定義するとそれを参照する側は

  • Optional型オブジェクトは存在するが,中身が空(null)である
  • Optional型オブジェクトは存在するが,中身が入っている
  • Optional型オブジェクトが存在しない(=nullで代入された)

 という3つのパターンを考慮しないといけません。これでは逆にデメリットが増えてしまいます。採用するのであればgetterメソッドの型だけをOptionalにする方が無難でしょう。

 後者「引数でOptional型を与えるメリットが誰にもない」は説明が難しいのですが,メソッドを作る側の立場になって考えてみましょう。引数型がOptional型以外でも結局のところnullチェックって実装するのではないでしょうか? 非Optional型で来たからといって信用できないかなという気がしています。なので,個人的には引数にはOptional型を使わない方が良い?と思っています。基本,Optional型は受け取った場所(メソッド)で中身を精査して扱うというのが王道なのでしょう。

 Oracleの中の人も「Optional型は戻り値だけで使ってねん」と言ってた気がします。

togetter.com