cockscomblog?

cockscomb on hatena blog

AWS CDK は React

AWS Cloud Development Kit(以下、CDK)というものがあるが、これの提供する抽象化について考えを巡らしていたところ、唐突にこれは React だと気付いた。

CDK と React の類似性

CDK の CloudFormation Resource は、React の DOM Element に対応する。

CDK の Construct は、React の Component に対応する。

CDK でデプロイするという行為は、React における reconciliation に対応する。すなわち、CDK が内部で CloudFormation を利用して差分をとって AWS サービス変更を適用するということは、React が仮想 DOM を利用して差分をとって実際の DOM を変更することに対応している。

このような React との近似性から、CDK の提供する抽象を捉えなおすことができる。CDK の Construct は、construct-tree を構成できるが、これは React の component-tree と対応づけて考えられる。Construct をどのように切り出すかの指針としても、React Component と同じように、ドメインを整理して、再利用性やカプセル化を意図して切り出せばよいと直感的に理解できるようになる。

そもそも CDK は、なぜか JSX をサポートしようとしていた(がその後 JSX サポートに関するコードは削除された)。このことからも、CDK が React にインスパイアされて作られたものである可能性が伺える。

CDK の抽象

ここで一応 CDK の提供する抽象について説明する。AWS CDK Concepts を見ると、CDK の抽象化はおおまかに以下のようになる。

  1. App
  2. Stack
  3. Construct

ここで App は、CDK で実行可能な単位で、複数の Stack を含めることができる。StackCloudFormation が提供するデプロイの単位で、Construct を含められる。Construct には種類があり、CDKによって提供されているものは二種類ある。

  • CloudFormation Resource
  • AWS Construct Library

CloudFormation ResourceAWS のサービスについて、CloudFormation の Resource が対応づけられた Construct である。AWS Construct Library は、CloudFormation Resource を内部に複数持ったもので、典型的なユースケースのためにうまく設計されたものである。

そして CDK のユーザーである我々もまた、必要に応じて自分たちの Construct を作ることができるのだ。


以上のようなことを、社内で話していて考えた。いつもAWS CDKについて教えてくれる同じチームの id:akiymid:taketo957 にはとても感謝している。

Amazon Web Services パターン別構築・運用ガイド 改訂第2版 (Informatics&IDEA)

Amazon Web Services パターン別構築・運用ガイド 改訂第2版 (Informatics&IDEA)

Flutterを試した

flutter.io

先日なんとなく物見遊山的にFlutterを試してみた。特に事前の知識もなく数時間で試した程度で、全体に不案内ではあるから、それなりの感想であることを先に断っておく。

(当方はiOS/Androidのネイティブアプリの開発や、Reactを使ったWebフロントエンド開発の多少の経験を有しています)

開発環境

f:id:cockscomb:20180521105915p:plain

IntelliJ IDEAのFlutter開発環境

セットアップ

Get Started: Installにしたがって環境を構築した。Homebrewなどでインストールできるようにしようという動きもあるが、現時点では手でSDKを配置する必要があるなど、少し手間がかかる。経験がないと少し難しいかもしれないが、時間が解決するだろう。

エディタ

IDEとしてIntelliJ IDEADartプラグインFlutterプラグインをインストールした。プラグインのできがよく、筆者は普段からJetBrainsのツールを愛用しているので、それほど調べずにDart 2.0を書くことができた。RunボタンでFlutterアプリを容易に実行できるのは当然として、リファクタリング関連の機能も完全に動作するし、コードを保存した際にdartfmtを呼び出す設定もできた。

Dart 2.0

Dart 2.0は、きちんと学んだわけではないが、書きやすく感じた。言語機能が妙にリッチで、例えばcascade notation (..)や、factory constructorなど、色々な機能がある。Genericsもあれば、pubというパッケージ管理の仕組みもあって、とにかく一通り揃っている。async/awaitの構文とFutureStreamによる非同期処理の手厚いサポートは便利に思う。プログラミング言語としての用途をクライアントサイドのソフトウェア開発に絞ったことで進歩的な機能を取り入れ易かったのだろうと想像する。

Hot Reload

React Nativeでもそうだが、コードを書いたらすぐにアプリに反映されるのは便利である。そろそろ「Hot Reloadは人権」のような言説が出てくる頃合いだと思う。依存するパッケージを追加してもきちんと動くし、画面遷移したあとも遷移先の画面にとどまってHot Reloadが動作するのには驚いた。

Flutter

肝心のFlutterであるが、Reactにインスパイアされた宣言的なUIフレームワークは扱いやすく、好ましく感じた。Reactのcomponentにあたる概念がWidgetで、StatelessWidgetStatefulWidgetをうまく組み合わせて使う。事前に用意されたMaterial DesignもしくはiOSに似せた(Cupertino)スタイルのwidgetを組み合わせると、それだけでもある程度のアプリができてしまう。

FutureBuilderのように、非同期に得られるデータを使ったUIを抽象化してくれるwidgetが特に便利である。非同期処理というのは「状態」に他ならないが、「状態」を宣言的にUIへ反映させられるからこその、宣言的なフレームワークである。直接的にこれと似ているのは、Apollo ClientのQuery componentだろうか。

ReactのようにJSXを使えたらとも思うが、Dartが引数ラベルをサポートしていることや、IDEがコンストラクタの呼び出しの後ろにnew Scaffold(); // Scaffoldというような行コメント風の表示で括弧の終わりを示してくれたりと、工夫を感じる。

簡単なアプリを作っていて、WebView widgetの不在に気がついた。考えてみれば、FlutterはOpenGLでまったく独自にUIを描画しているのだから、WebViewを実装するのは容易なことではない。この点でプラットフォームのUIをそのまま利用しているReact Nativeと大きな違いが生まれている。このトレードオフが今後どのように影響してくるのか、難しいところだろう。

全体的に

少し書いてみたところでは、Flutterはおもしろい。しかしまだバージョンが0.3と若く、未成熟さも感じる。来年に予定されるバージョン1.0のリリースまでには、さらに使いやすくなるだろう。またこのような未成熟さを、コントリビューションのチャンスと捉えることもできる。

Flutterが有効に機能する場面はまだ限定されていると思う。しかしこのような宣言的なフレームワークは業界の最新の流行であるから、学んでみて損はない。

github.com

Marzipanを予想する

予想というか、根拠のない与太話です。


Marzipanと呼ばれるAppleのプロジェクトは、どのようなものになるのだろう。噂では、iOSmacOSのアプリが一度に作れるようになるらしい。このふたつのOSのアプリを開発する上での主要な差異は、iOSのUIKitとmacOSのAppKitの、UIフレームワークである。その他のフレームワークのほとんどはすでに共通している。この状況を踏まえれば、MarzipanはUIフレームワークであると考えられる。

そのMarzipanがどのようなUIフレームワークになるのか、グラデーションをつけて考えてみる。

UIKitの移植

もっとも単純なのは、UIKitをmacOSへ移植してしまうパターンである。macOSのAppKitは古びてきているから、より近代的なUIKitを持ってきてしまう発想である。

もちろんtvOSのUIKitのように、同じUIKitでも異なるUIを提供することにはなるだろう。それはポインティングデバイスの特性であったり、要求されるUIの複雑さに依るところである。

一方で、ひところプライベートフレームワークとして存在していたUXKitとは異なる実装方法が取られるのではないか。UXKitはAppKitの上にオーバーレイするようなアーキテクチャであったが、そのような方法では不特定多数の開発者に安定的なAPIを提供するのが難しい。

UIKitの移植は、多くの開発者にとっては、iOSアプリを少ないコストでmacOSに移植できるメリットを得られる可能性がある。ただし一定のカスタマイズが必要になる可能性もある。

まったく新しいUIフレームワーク

このタイミングでまったく新しいUIフレームワークの導入が行われる可能性も存在している。それがどのようなものになるのか想像するのは楽しい。

まったく新たなフレームワークが作られるなら、最大の関心事は、それがSwiftネイティブなフレームワークであるかどうかであろう。Objective-Cと決別することで、よりSwiftの言語機能を活かすことができる。静的型付けを活かしたSwiftフレンドリーなフレームワークは、多くの開発者に喜ばれるはずだ。その反面で、これまでObjective-Cの動的な特性を活用してきた部分は失われる。例えばresponder-chainは、まさにそのような機能であり、単純なイベントハンドリングはもちろん、メニューバーやコンテキストメニュー、キーボードショートカットからTouch Barにいたるまで、多くの用途で利用されている。そのようなものが存在しないとすれば、もはや既存のものとはまったく異なるパラダイムのUIフレームワークであるだろう。

昨今ではReactに端を発した、宣言的にビューを構築するUIフレームワークが流行している。宣言的な記述でVirtual DOMを構築し、reconciliationと呼ばれるプロセスによって実際のビューを差分更新する。最近ではGoogleもReactにインスパイアされたFlutterというUIフレームワークを開発している。

Reactの新しいFiberアーキテクチャでは、非同期的にVirtual DOMを構築できる。これによって、一見すると同期的なコードでビューを構築しつつ、実際にはその部分の描画だけを遅らせるようなことが可能になる。これは単にUIのフレームレートを改善するだけに留まらない。時間のかかる処理に依存してビューを更新することが容易になるのはもちろん、アニメーションの表現もしやすくなる。

なんの傍証も存在しない妄言に過ぎないが、例えばReactのようなパラダイムを持ち込んだものがMarzipanであるなら、とてもおもしろい。その一方で、まったく異なるパラダイムフレームワークを導入した場合は、既存のアプリをそう簡単には移植できないため、移行に時間がかかることが懸念される。

グラデーション

UIKitの移植か、完全に新しいUIフレームワークか、二者択一というわけではなく、実際にはグラデーションが存在するだろう。例えばUIKitによく似たAPIで、少し抽象度の高いフレームワークが双方に導入されることも考えられる。あるいはまったく新しいUIフレームワークではあるが、既存のアプリに部分的に取り入れられるようになっている場合もあるだろう。

いずれにせよ、すでに存在しているiOSアプリから少しずつ移行できるようになっていなければ、多くの開発者はなかなかMarzipanを採用できない。AppleにとってMarzipanの開発の目的が、macOSのアプリを充実させることにあるなら、移行のしやすさは重要である。


Marzipanと呼ばれる秘密のベールに包まれたプロジェクトについて、Appleのファンボーイ的に予想を行なった。実際にどのようなものが出てくるかは、6月のWWDCまでわからない。しかし新しいUIフレームワークを予想するという行為そのものは、単におもしろいだけでなく、UIフレームワークの理想像について考察を深めるきっかけになることだろう。

ぜひ読者諸氏も、Marzipanを予想してみてほしい。

Docker for Macでコンテナの中からホストに繋ぐたった一つの冴えたやり方

Networking features in Docker for Mac | Docker Documentation

コンテナ中で docker.for.mac.localhost というDNS名を使うと、ホストのmacOSに繋がります。

メリークリスマス。

追記(2018/01/06 21:00)

Docker 17.12.0から新たに同じ用途の docker.for.mac.host.internal が追加され、今後はこちらが推奨されます。

これはlocalhost のサブドメインを禁止するRFCが提案されていることによります。

謹賀新年。

追記(2018/03/27 11:00)

https://docs.docker.com/docker-for-mac/release-notes/#stable-releases-of-2018

Docker 18.03.0からさらに host.docker.internal が追加され、今後はこちらが推奨されます。

ハッピーバースデー。

三点リーダーの位置をOpenTypeフォントでいい感じにする……

僕は三点リーダー「…」が好きで、ついつい使ってしまいます……。この三点リーダーですが、日本語では(仮想ボディの)中央に並び、欧文ではベースライン上に並べるのが一般的です。一方で昨今のWeb媒体などでは、日本語の文章であっても三点リーダーがベースライン上に並んでいる場合も多くみられます。どちらかといえばベースライン上に並んでいるのに慣れてしまった諸氏も少なくないのではないでしょうか……。

基本的に、コンピュータ上で三点リーダーがどの位置に表示されるかは、フォントによって決まっています。三点リーダーのUnicodeにおける名前は “HORIZONTAL ELLIPSIS” といって、U+2026 のコードポイントに割り当てられています。このコードポイントに対応するグリフがどのようにデザインされているかが問題になります*1。実際に複数のフォントを見比べてみるとわかりますが、“HORIZONTAL ELLIPSIS” のグリフは、和文書体なら中央、欧文書体ならベースライン上に置かれていることが大半だと思います。

文字ビューア

macOSの文字ビューアで表示した “HORIZONTAL ELLIPSIS”

Helvetica NeueSF Pro Text Regularヒラギノ角ゴ W3游ゴシック体 ミディアム

様々な書体の三点リーダーのグリフ

特にWebコンテンツでは、三点リーダーの部分だけフォントを変更したり、あるいは “MIDLINE HORIZONTAL ELLIPSIS” を使うことによって、三点リーダーを中央に表示するようにと対応されることもありました。

OpenTypeフォントloclフィーチャー

ところでOpenTypeフォントでは、特定の文字(列)を表すグリフが複数になることがあります。例えば日本語の横書きや縦書きで句読点の位置を変えたり、あるいは合字を表現するのに用いられます。フォントによってはこの仕組みを使うことで三点リーダーのグリフも置き換えることができます。

フォントの中のグリフ(あるいはその位置)を選択するには「フィーチャー」というものを使います。言語によって異なる字形を表現するのはlocl(Localized Form)というフィーチャーです。

CSSでの設定

CSSではfont-feature-settingsというプロパティを設定することで、OpenTypeフォントのフィーチャーを利用できます。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>locl test</title>
    <style>
      body {
        font-family: "Noto Sans CJK JP";
      }
      .locl {
        font-feature-settings: "locl";
      }
    </style>
  </head>
  <body>
    <p class="locl" lang="en">This is English…</p>
    <p class="locl" lang="ja">これは日本語です…</p>
  </body>
</html>

This is English…

これは日本語です…

font-feature-settings"locl"を指定する

このようなHTMLをNoto Sans CJK JPフォントのインストールされたコンピュータの、SafariFirefoxChromeInternet Explorerで表示すると、英語ではベースライン上、日本語では中央に三点リーダーが表示されることを確認できます。(Edgeでも確認しましたが、なぜかうまくいきませんでした……。)

Safari

ブラウザでの表示

特にloclフィーチャーの基準となる言語の選択について、実際にはブラウザ毎に少しずつ挙動が違います。例えばSafariは、三点リーダーの直前の文字をもとに言語を決定しているようです。FirefoxChromeではlang属性も言語の選択に影響します。

またChromeFirefoxではデフォルトでloclフィーチャーが有効ですが、Safariでは明示的に有効にする必要がありました。

ちなみにtext-overflow: ellipsis;を用いて省略記号を表示させた場合は、Firefoxでのみ適切な位置に三点リーダーが描画されました。

このようなブラウザ毎の挙動の違いは今後も改善されていくでしょうから、その都度で様子を見ていく必要がありそうです。いずれにせよlang属性を指定するのはよい習慣です。

loclフィーチャーでの三点リーダーの置き換えに対応したフォント

残念ながら現実には、この機能に対応したフォントは多くありません。少し調べて対応が確認できたのはNoto Sans CJK JPNoto Serif CJK JP貂明朝の3つでした。一般的なヒラギノ書体や游書体などは現在のところ対応していません。

Webフォントを利用していれば、多くの環境で使うことができます。Webフォントを使っていなければ、比較的新しいAndroid OSくらいでしか使えないでしょう。

将来に期待です……。


この記事ははてなエンジニアAdvent Calendar 2017の15日目の記事です。前日はid:Pasta-Kとりあえずシュッとパフォーマンスチューニングの目星を付けるでした。

*1:ただしUnicodeには “MIDLINE HORIZONTAL ELLIPSIS” という U+22EF に割り当てられた文字もあって、こちらは必ず中央に並べられます

「iOS 11 Programming」を書きました

iOS 11 Programming

iOS 11 Programming

  • 著者:堤 修一,吉田 悠一,池田 翔,坂田 晃一,加藤 尋樹,川邉 雄介,岸川克己,所 友太,永野 哲久,加藤 寛人,
  • 発行日:2017年11月16日
  • 対応フォーマット:製本版,PDF
  • PEAKSで購入する

今日から普通にお買い求めいただけます。

担当した章について宣伝します

僕は「第6章 Drag and Drop」と「第7章 FilesとDocument Based Application」のところを書きました。ここで担当した章について宣伝します。

iOS 11が一般にリリースされてからもう少し経っていますが、実際にiPadを使っていると、Drag and Dropがとても便利な操作であることがわかります。例えばタスク管理に使っているThingsというアプリでは、メールアプリなどからのドロップを受け付けてくれます。メールがきて後で何か対応しないといけない時に、とりあえずTo-Doを作成するのがとても簡単です。ドラッグやドロップはとても直感的で、効率的な操作ですが、アプリが対応しているかどうか一目で見分けることができません。逆説的に、どのアプリでも必ず対応しているようになることで、その価値が高まると言えます。

Document Based Applicationというのは、KeynoteやPages、Numbersのような、ドキュメントを中心としたアプリです。iOS 11ではこのようなアプリを作るのが本当に簡単になりました。ドキュメントブラウザのコンポーネントが提供されていて、iCloud DriveやDropboxとの連携もほとんど意識する必要がなく、ただドキュメントの表示や編集に注力すればよいようになっています。これまでiOSのはアプリを中心とした世界観を構築していましたが、Document Based Applicationではそれと直交する、ドキュメントを中心としたワークフローを提供できます。対応しているアプリはまだ多くありませんが、そこにニーズが存在していることは間違いないでしょう。

iOS 11 Programmingでは、Drag and Dropへの対応やDocument Based Applicationを作成する際に必要となるであろう知識を、大半のAPIについての解説しつつ、網羅的に詰め込みました。ちょっとググっただけでは得られないような内容になっているはずです。個人的な開発からお仕事まで、ぜひご活用ください。

全体的に宣伝します

「Swift 4の新機能とアップデート」や「Xcode 9 の新機能」のようなDeveloper Toolの章や、僕の担当部分や「レイアウト関連の新機能及び変更点」のようなUIKitに関連した章は、ほとんどのiOSアプリエンジニアにとって必ず役に立つでしょう。少し目を通してから開発を始めることで、より効率的に、特にiPhone Xへの対応作業などでは、大きな効果を得られると思います。

「ARKit」や「Core ML」、そして「Metal」の章は、いまiOS以外の分野でも特に重要な技術領域について、iOSにおける実装を一度に学べるまたとない機会と言えるでしょう。ARはついにひろく実用的な技術になりつつあり、機械学習はもはやなくてはならないものですが、さらに現在ではモバイル端末上での活用が進んでいます。そしてMetalのような高パフォーマンスなGPUAPIは様々なプラットフォームで台頭しています。

「Core NFC」と「PDF Kit」はiOS 11で新たに加わったフレームワークですが、どちらも新たな可能性をもたらします。「SiriKit」や「HomeKit入門とiOS 11のアップデート」、「Audio関連アップデート」は、これまでにもあったフレームワークではありますが、iOS 11で着実に進化しつつあります。特にSiriKitは、来年発売されるというHomePodとの連携が期待されるところです。HomePodはGoogle Assistantなどと違って、クラウド上のアプリではなく、iOS端末上のアプリと連携するのがユニークなところですね。

ということで、全体的にiOSアプリの開発をしていたら買うしかないかな、というような内容になっています。どうぞお買い求めください!

iOS 11 Programming

技術書クラウドファンディングプロジェクト「iOS 11 Programming」

iOS 11 Programming

iOS 11 Programming

  • 著者:堤 修一,吉田 悠一,池田 翔,坂田 晃一,加藤 尋樹,川邉 雄介,岸川克己,所 友太,永野 哲久,加藤 寛人,
  • 発行日:2017年11月16日
  • 対応フォーマット:製本版,PDF
  • PEAKSで購入する

以前に妻のいとこに会ったとき、当時大学生だったそのいとこは、大学のレポートをスマートフォンで書いている、と教えてくれた。現代ではそういうものだという話は聞いたことがあったが、実際の事例であることがそのときわかった。ふつうはパソコンを使うでしょう、と考える人もいるかもしれないが、大学生がパソコンを使えるようになったのだって、ほんの最近のことなのかもしれない。

先日iOS 11が発表された。iPadドラッグ&ドロップができたりするらしい。どれどれと思って、いろいろと新しいAPIを見てみると、これは確かによくできている。iPadは新しいiOS 11で、「パーソナルコンピュータ」になるのかもしれない。

ここでいうパーソナルコンピュータというのは、人間ひとりひとりを拡張する道具、というような意味である。Windowsデスクトップだけを指すのではないし、ましてMacだけがそうであるはずもない。新しいiOS 11は、ドラッグ&ドロップによる直感的なデータの受け渡しや、あるいはファイルを中心とした新しいアプリ間の連携によって、生産的な活動に耐えうるコンピュータになっていくのだろう。

先日僕にも子供が生まれた。僕の子もまた、成長するにつれてパソコンを必要とするだろう。そのとき僕が買い与えるのは、Macなのか、iPadなのか、それとも未だ見ぬ未来の何かなのか、まだ知るすべはない。ただ、その日のために備えておきたいと思う。

さて、縁あって「iOS 11 Programming」という本の、まさにドラッグ&ドロップやファイルを中心とした新しい機能について、章を書かせてもらえることになった。新たなパーソナルコンピュータたるiOS 11について、他では読めないようなものを書きたいと思う。とはいっても、この本はいま流行りのクラウドファンディングであって、これが成立しない限りは世に出ることもない。これを読んでいるみなさんひとりひとりに、未来のパーソナルコンピュータを支えるため、クラウドファンディングに協力する責任がここに発生した。ぜひご協力頂けると幸いです。

ところでこの記事も全て新しいiPad ProとSmart Keyboardで書きました。