cockscomblog?

cockscomb on hatena blog

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で書きました。

子供が生まれました

本日午前11時に、僕と妻の子供が生まれました。予定日を10日ほど過ぎた、3,700グラムの男の子です。日付が変わった頃から陣痛がきて、それからあれよあれよという間に産まれていました。今はただ妻と息子の無事をありがたく思います。

結婚してからおよそ1年半になりますが、新しい家族の存在は新鮮で、とても嬉しく、そして自分に息子がいるという事実がまだ不思議です。自覚に欠けているようにも感じますが、子供が僕と妻を少しずつ親にしてくれるのだろうと思っています。

家事にも育児にも仕事にも、ますますがんばって参りたいと思います。

今後ともよろしくおねがいいたします。

年末年始に飲み過ぎないために

諸君は酒が好きだろうか。筆者の場合は少しくらい、好きである。酒を飲んでもいいことなどない。僅かに楽しいような気分になるばかりで、だんだんと頭がボーッとしてきて身体もダルくなり、ひどいときには周囲の人間にまで迷惑をかける。しかし、よく冷えたビールの一口目の、あのなんとも言い難い美味さよ。あのたった一口分の美味さが脳神経に刻みつけられ、繰り返しくりかえし酒を飲んでしまう。なんと愚かなことだろう。

さて本稿では、種々の問題をはらむ飲酒について、特に二つの問題を取り上げ実践的なアドバイスを諸君らに授けたい。筆者のアドバイスは主に Swift によって記述される。

ビール1パイント問題

アイリッシュパブなどに行ってビールを頼むと、「中ジョッキ」のような曖昧な単位でなく、「パイント」という単位で量を指定しなければならない。諸君らも安易に1パイントで頼んでしまって思ったより多くて苦労する、といった経験をしたことがあるかもしれない。

パイントはヤード・ポンド法における体積の単位であり、イギリスでは1パイントがおよそ0.568リットルに相当する。アメリカでは0.473リットルであるが、ビールにおいてはイギリス式のパイントが用いられる。

Swift と Foundation.framework でこれを示すと、以下のようになる。

let onePint = Measurement(value: 1, unit: UnitVolume.imperialPints) // 1.0 pt
onePint.converted(to: .liters) // 0.568261 L

Measurement は Foundation に iOS 10 の世代から追加された、Double 型の値と Unit 型の単位を持った、単位付きの値を表す struct である。体積の単位を表す UnitVolume は抽象クラスである Dimension のサブクラスで、また DimensionUnit のサブクラスである。Unit は単に単位を表し、Dimension はそれに加えて単位変換を行うために baseUnit()UnitConverter が関連づけられている。

これらの仕組みにより、converted(to:) メソッドで単位変換を行うことができる。英国法定標準のパイントである UnitVolume.imperialPints から SI 併用単位の UnitVolume.liters へ変換できる。(ところで litre じゃなく liter なのはアメリカっぽいと思います。)

let halfPint = Measurement(value: 0.5, unit: UnitVolume.imperialPints) // 0.5 pt
halfPint.converted(to: .liters) // 0.2841305 L

(halfPint * 3).converted(to: .liters) // 0.8523915 L

Swift の Foundation インターフェースでは演算子が定義されているので、ハーフパイントのビールを3杯くらい飲めばおおよそいい感じになる、ということがわかる。

結論:ハーフパイントくらいでいい

さらに Measurement では、MeasurementFormatter を使って読みやすい文字列を得られる。

let onePint = Measurement(value: 1, unit: UnitVolume.imperialPints) // 1.0 pt

let formatter = MeasurementFormatter()
formatter.locale = Locale(identifier: "ja-JP")
formatter.unitStyle = .long

formatter.string(from: onePint) // "0.568リットル"

日本酒1合問題

日本酒のラインナップが充実した居酒屋でお気に入りの銘柄を1合注文したとき、後に続くおちょこ追加、おちょこ人数分によって、僅かに舐めるばかりの量しか残らない。諸君らも、このような事例で涙したことは一度や二度では済まないだろう。

1合がいかほどの量か、ビールのように調べてみたいが、生憎 Foundation の UnitVolume には「合」という単位は存在していない。しかし幸いなことに、自分で単位を追加することができる。

extension UnitVolume {
    static var: UnitVolume {
        return UnitVolume(symbol: "合", converter: UnitConverterLinear(coefficient: 0.18039))
    }
}

このように UnitConverterLinear を利用して新しい UnitVolume を作ることができる。UnitConverterLinearUnitConverter 抽象クラスのサブクラスであり、coefficient と constant によって単純な線形の変換を行うことができる。UnitVolumebaseUnit().liters であるから、尺貫法における1合が約0.18039リットルであることにより、このように書けるのである。

let oneGo = Measurement(value: 1, unit: UnitVolume.合) // 1.0 合
oneGo.converted(to: .liters) // 0.18039 L

これによって Measurement において合という単位が利用できるようになり、人数に応じて適切な量について考えられるようになった。

UnitConverter は他にも実装することができ、例えば逆数への変換などが存在し得るだろう。

結論:みんなで飲むなら多めにたのむ

総括

本論により、Foundation の Measurement 関連 API の利用方法を示した。その中で我々は、以下の結論を得た。

  • ハーフパイントくらいでいい
  • みんなで飲むなら多めにたのむ
  • 飲み過ぎないように気をつける

それでは皆さんよいお年を。


本稿の内容は関西モバイルアプリ研究会 #21において行われた筆者の研究発表から、その内容を再録したものである。

これは飲酒を勧めるものではなく、京都市清酒の普及の促進に関する条例とも関係しない。筆者の居住地である日本国では、未成年者飲酒禁止法により満20歳未満の者の飲酒は禁止されている。また酒気帯び及び酒酔い運転は犯罪である。飲酒は健康な成年に限って、自己の自由意志によってのみ行われるべきであり、何人も飲み過ぎてはいけない。