今回は久しぶりに新ハードウェアがどっさりと発表されました。それも2時間30分超えのキーノートの大半の時間を使って。新OSもつつがなく発表されたとはいえ、iOS 11はとにかくmacOSはHigh Sierraとは、あまり新しそうに見えません。
とは言っても現行MacはCPUがKaby Lakeにアップデートされただけのように見えますし、iMac ProもHomePodも発売開始は今年末であり、その意味で真の新製品はiPad Pro 10.5ということになるでしょう。筆者も1台入手しました(写真1 ) 。
写真1 真の新製品iPad Pro 10.5
なぜAppleはこれらの新製品発表の場としてSpecial EventではなくWWDCを選んだのでしょう?――ほかの誰よりも開発者達がそれを欲していた、というのが筆者の読みです。とくにiPad Pro 10.5は、よりMac寄りに近づくことが確定的になったiOS11 for iPadのレファレンス・マシンとしての役割を担っています。ドラッグ&ドロップ可能なマルチタスク画面にDockまで。iPadはコンテンツを消費するデバイスからコンテンツを制作するデバイスへという流れをより鮮明化させてきました。これでXcode for iPadがあれば、Macフリーなエコシステムができあがるようにすら見えるほど。
本番は「プラットフォーム一般教書演説」
むしろWWDCとしての本番は、Platforms State of the Union でした。ベタな直訳で「プラットフォーム一般教書演説」 。機械学習APIであるMLKitと拡張現実APIであるARKitは他社の後追いのようにも感じられますが、本連載で何度も繰り返しているように、Appleは最も保守的なプラットフォーム企業。そのAppleが標準APIを用意するというのは、それが今後の業界の標準となることを示唆せずには入られません。
Swift Playgrounds meets robots
本連載の主題はAPIではなくSwiftという言語。そこに焦点をあてるとSwift PlaygroundsでドローンやLEGO MINDSTORM EV3をプログラムできるようになるという発表(写真2 )は、IT業界よりも教育業界にとって朗報でしょう。筆者の次女が通っている中高一貫校の高等部ではiPadが必須の教材となっているのですが、彼女たちもきっとその恩恵を受けることでしょう。
写真2 LEGO MINDSTORM EV3をiPadでプログラミング
Swiftで書き直されたXcode Source Editor
とはいえ本連載をお読みの読者のほとんどは、XcodeでSwiftしているはずです。そのXcodeは9でどう変わったか。一番の注目は、Swiftで全面的に書き直されたソースエディタでしょう。妙な言い方になりますが、ソースコードを「理解」するようになっています。言葉で言うより、スクリーンショットをご覧いただいたほうが早いでしょう(図1、図2 ) 。
図1 コンテキストメニュー表示(その1)
図2 コンテキストメニュー表示(その2)
iOSアプリでもあるSwift Playgroundsと同様、ソースの構造を適切に解釈したうえで、その構造に即したコンテキストメニューが表示されます。
圧巻なのは、プロトコルとの組み合わせ。本連載でもSwift はProtocol Oriented Languageであると繰り返し申し上げてきましたが、言語自身はとにかくこれまでのエディタのサポートは貧弱なもので、不適合なら“ Type T does notconform to protocol 'P'” というエラーメッセージを表示する程度でしかありませんでした。
それが、図3 のとおりに変わります。
図3 エラーメッセージの変化
プロトコルを追加した時点で適合性がチェックされるところまでは今までどおりですが、足りないプロパティをすべて洗い出したうえでスタブを追加してくれるのです。あとはそれを埋めるだけ。ああ、PONS を開発中にこの機能があったらどんなに楽だったか!
エディタの機能が増えると心配なのが「それでますますもたつくのではないか」 。うれしいことに、機能が豊富になったにもかかわらず、編集からビルドまでほぼすべての面で高速化しています。とくに長いコードが入ったPlay groundは、Xcode 8までは明らかにもたついていたのが、ほぼ何をしても瞬殺という感じで非常に快適。正直、High Sierraを待たずに先に正式版リリースしてほしいぐらい。
Swift 4「簡単なことはより簡単に」
開発用のMacもXcodeも明らかに改善されたのを確認できた今回のWWDCですが、肝心のSwift 4はどうでしょう? 「 一般教書演説」でも少し紹介されていましたが、やはりここはWhat's New in Swift でもう少し詳しく見ていきましょう。
言語仕様自体は、Swift 3からそれほど変わっていません。Swift 3のリリースのときと同様Swift 4のリリースでは同時にSwift 3.2がサポートされます。ここまでは同様ですが、前回はXcodeにコンパイラーを2種類搭載してそれを実現していたのに対し、今回は同じコンパイラーでそれを実現していることからも2→3ほどの変化ではないことがうかがわれます。とはいうものの、3.xのxの増分では済まない違いも確かに存在します。
private
宣言がより自然になったので、fileprivate
はほぼ不要に。プレゼンテーションでは「これでアクセスコントロールに関してはおしまい」という言い方でこの変更についての説明を締めくくっていた
プロトコル宣言で新たなプロトコルを宣言しなくても、プロトコルを合成できるように。P&Q
と書けば、「 プロトコルPとプロトコルQ双方に適合するタイプ」と解釈される。あとのコードサンプルにも実例が出てくる
Sequence
の要素を指定するのに、Iterator.Element
と書かずにElement
だけでよくなった
たとえばSwift 3では、
extension Sequence
where Iterator.Element: Equatable
{
func containsOnly(
_ value: Iterator.Element
) -> Bool {
return !contains { $0 != value }
}
}
と書かなければならなかったのが、Swift 4では、
extension Sequence
where Element: Equatable
{
func containsOnly(
_ value: Element
) -> Bool {
return !contains { $0 != value }
}
}
で済むように。Protocol Oriented Programmingがますますはかどります。内部的には、
protocol Sequence {
associatedtype Iterator: IteratorProtocol
// ...
}
protocol IteratorProtocol {
associatedtype Element
// ...
}
となっていた定義を、
protocol Sequence {
associatedtype Element
associatedtype Iterator: IteratorProtocol
where Iterator.Element == Element
// ...
}
protocol IteratorProtocol {
associatedtype Element
// ...
}
としたとのことです。見ればなるほどですね。
String
がCharacter
のCollection
に
しかし一番歓迎な変更は、String
がCharacter
をElement
とするCollection
になったことでしょう。今まで、
let animals = "🦏 🐫 🐍 💎"
for c in animals.characters {
print(c)
}
として.characters
プロパティにアクセスしないと取り出せなかったのが、Swift 4以降は、
let animals = "🦏 🐫 🐍 💎"
for c in animals {
print(c)
}
と書けるということです。もちろん今までどおり、バイト単位でバラす.utf8
や、Unicode単位でバラす.unicodeScalars
は健在です。
ここで「Unicode単位」と言いましたが、Swift 4におけるCharacterは合成文字もきちんと1文字として扱います。なので、
let flags = "🇯🇵 🇺🇸"
flags.count // 2
flags.unicodeScalars.count // 4
flags.utf8.count // 16
となります。なお、今までどおり.characters
も用意されているので、Swift 3以前のコードもそのまま動くはずです。
あと、Pythonと同様の"""
で複数行String
リテラルもサポートされます。次に紹介するCodable
と組み合わせると、文字列にとどまらず入り組んだデータの初期化もはかどること請け合いです。
Codable
プロトコル
筆者が最も感銘を受けたのが、Codable
プロトコルの追加です。本連載の第25回で、JSONタイプを作成しましたが、今後こういったタイプはほぼ不要になるのです。実例を見てみましょう。
struct Point2D
<F:FloatingPoint>
{
let x:F
let y:F
}
という簡単なタイプがあったとします。これをJSONで扱いたいとしたらどうするか? こうするだけでよいのです。
struct Point2D
<F:FloatingPoint & Codable> : Codable
{
let x:F
let y:F
}
そう。ストアドプロパティがすべてCodable
でありさえすれば、そう宣言するだけであとは何もしなくてよいのです。では実際に使ってみましょう。まずはPoint2D
からJSONデータへ。
let p = Point2D(x:42.0, y:0.195)
let j = try JSONEncoder().encode(p) // Data型
String(data: j, encoding: .utf8)
// {"x":42,"y":0.19500000000000001}
次はその逆。
let pp = try JSONDecoder()
.decode(Point2D<Double>.self, from:j)
ここでおもしろいのは、.decode
の第一引数が型になっていることです。try
しているので、JSONがこの型に適合していなければthrow
することは言うまでもありません。
鋭い読者であればすでに察しているとは思いますが、当然[Codable]
も[String:Codable]
もCodable
なので、文字列や数値はすぐにこの恩恵を受けられますし、Swift 4以降は標準搭載のJSONEncoder
のみならずMessagePackEncoder
やYAMLEncoder
がリリースされることも期待されます。
ほかにもRange
がstart...end
と書かなくても、start...
だけでstart
から最後の要素までの意味になったりと、Swift PlaygroundsとあわせてますますカジュアルにSwiftを使えるようになるのは確実そうです。
APFS Update
LeopardにSnow Leopard、LionにMountain Lion。そしてSierraにHigh Sierra。AppleがOS XもといmacOSのバージョンをそう命名するときには、外見はあまり変わらずとも内部がガバッと変わるものと相場が決まっていますが、今回の内部は格別に大きい。ついにAPFSがmacOSにも正式導入されるのです。ただし、macOS SierraやiOS 10.3のAPFSそのままではありません。What's new in Apple File System を見てみることにしましょう。
一番変わったのは、Unicode Normalizationの有無。High SierraのAPFSはNormalizationを行います。本連載第26回のときの検証コードをHigh Sierra BetaのAPFSで使ってみたところ、こうなりました。
Perl版:POSIX API
食べないでくださーい
食べないでくださーい
食べないよー
かばん.txt:\ x{304b}\ x{3070}\ x{3093}.txt
Swift版:Foundation
食べないでくださーい
食べないでくださーい
食べないよー
かばん.txt: ["\ u{304B}", "\ u{306F}", "\
u{3099}", "\ u{3093}", ".", "t", "x", "t"]
やや奇妙なことに、Perlを含めPOSIX API経由ではNFCが、Foundation経由ではNFDがそれぞれファイル名として使われていますが、\ u{304b}\ u{3070}\ u{3093}.txt
と"\ u{304B}\ u{306F}\ u{3099}\ u{3093}".txt
が同じファイル名だと認識されています。
次回予告
というわけでSwiftを取り巻く環境の今後の方向性も見えたところで今月の記事は結びです。次回はSwift 4を見据えつつ、Swift 3でももちろん有効なSwiftyな記事をお届けする予定です。
第1特集
MySQL アプリ開発者の必修5科目
不意なトラブルに困らないためのRDB基礎知識
第2特集
「知りたい」「 使いたい」「 発信したい」をかなえる
OSSソースコードリーディングのススメ
特別企画
企業のシステムを支えるOSとエコシステムの全貌
[特別企画]Red Hat Enterprise Linux 9最新ガイド
短期連載
今さら聞けないSSH
[前編]リモートログインとコマンドの実行
短期連載
MySQLで学ぶ文字コード
[最終回]文字コードのハマりどころTips集
短期連載
新生「Ansible」徹底解説
[4]Playbookの実行環境(基礎編)