ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
Swiftの新機能
Swiftは、SwiftUI、RealityKit、Create MLなど、すべてのAppleプラットフォームの主要なフレームワークの多くにおいて選ばれている言語です。このセッションでは、Swift 5.0について再確認し、Xcode 11で新しく導入されるSwift 5.1について紹介します。パフォーマンスと安全性における最新の改善点についてご確認ください。また、Swiftの新機能と、それらが新しいフレームワークの開発にどのように役立ったかについてもご確認いただけます。
リソース
関連ビデオ
WWDC19
-
ダウンロード
(音楽)
(拍手) おはようございます “What's New in Swift”へ ようこそ 今日はSwiftの 2つのリリースをご紹介します 3月にリリースされたばかりの Swift 5と 現在 Xcode 11で使用できる プレビュー版のSwift 5.1です この2つを組み合わせることで Appleと皆さんが構築できる― 言語とテクノロジーとしての Swiftの可能性がさらに広がります
それは SwiftとAPIの 強力な組み合わせで実現します
現在 Swiftランタイムが AppleのOSに組み込まれ Swiftで書かれたフレームワークの バイナリが展開できます Swiftだけでできたフレームワークが 登場するのです さらに Swift Package Managerが Xcodeに統合され Swiftパッケージが 開発のワークフローに組み込まれます Swift自体が表現力豊かな APIを作る動機をもたらし APIの進化を 示せるようになるのです 言語にとってエキサイティングな 展開が続いています まず バイナリフレームワークから 説明します それを実現させた中心的な要素を 説明したいと思います その要素とは ABIとモジュールの安定性です
ABIとは Application Binary Interfaceの略で コンパイルされたコードが 実行時にやり取りする仕様のことです 関数の呼び出しのようなものですが どのような仕組みでしょうか 引数の値は どのように渡されるのでしょうか 使えるメタデータ メモリ展開といった情報が必要です Swiftで書かれたプログラムを例に 考えてみましょう 実行できるものであれば 何でもかまいません Swiftで書かれたフレームワークを 使っているものです こうしたコンパイル済みコードは プロセス内で同時に実行されるため プログラムはフレームワークの APIでやり取りをします やり取りの実現には 互換性のあるABIが必要です 別々にコンパイルしたコードを 同時に実行しなければいけません これまでは 異なるコンパイラでビルドした場合 ABIの互換性は保証されませんでした これは問題でした Swiftの基盤を進化させてきた私たちが 将来の成長のために改善すべきは この問題だと確信しました Swift 5では この改善策を具体化し ABIの安定性を確保しました つまり Swift 5以降のコンパイラで ビルドする限り 同じコンパイラで ビルドする必要はないのです
次に重要なのはモジュールの安定性 つまりコンパイル時間の概念です 例えば Swiftのフレームワークの 全てのAPIは モジュールと呼ばれる 共有の名前空間の一部です そのフレームワークを Swiftコンパイラでビルドすれば フレームワーク内のすべてのAPIの マニフェストが作成されます その後 フレームワークの クライアントに使われます そのマニフェストは Swiftモジュールと呼ばれます では例に戻って コンパイルしてみましょう ソースファイルが フレームワークを参照すると 次に コンパイラは モジュールを読み込み APIを取得します モジュールファイルは細かく コンパイラに左右され ABIの安定性と同じ問題を 抱えていました 異なるコンパイラを 使えなかったのです Swift 5.1では 新しい補完的な マニフェストを導入しました それは Swiftモジュール インターフェースと呼ばれ インターフェースを安定させるために フレームワークによって使われます それは一見 Swiftのソースコードのように見えます Swiftのソース安定性の概念に基づいて 作られたものです この2つの要素が Swiftフレームワークの デプロイと共有を可能にします
(拍手) ABIの安定性については 非常に興味深い点が多数あります 詳細な情報を得るには swift.orgが役に立ちます これが Swift Open Source Projectの ホームページです ABIの安定性について いいブログ記事が載っています
バイナリフレームワークを 使ってみたい方は 今週後半に“Binary Frameworks in Swift”という講演があります フレームワークを共有する際の 注意点に関する話題もあります APIで もうひとつ重要なのは Swiftパッケージです Swift Package Managerが Xcodeに統合されたことで App構築の中心的な ワークフローの一部になりました 今週 Xcodeでのパッケージの作成と 導入についての講演があります このように Swiftパッケージと バイナリフレームワークは APIを共有するための 豊富なオプションを提供しています
では パフォーマンスの説明に 移りましょう Swiftはモダンで安全でありながら 非常に高性能なプログラミング言語です ABIの安定性により パフォーマンスに 重要な利点をもたらします 利点の1つはOSのApp用に 共有のSwiftランタイムがあることです MacOS iOS tvOS watchOS iPadOS用に3月にリリースされました こうしてOSに組み込まれた 共有ランタイムは サードパーティーを含め 全てのAppで使用されます
では実際に どのように機能するのでしょうか
AppがSwift 5以降で ビルドされている場合は OSに組み込まれている 共有ランタイムを使用します しかし 以前のバージョンのOSで ビルドしている場合は 共有のランタイムがありません その場合 XcodeはAppにランタイムの コピーをバンドルするので 古いOS上で動き続けられます しかし 常にOSの中にあるコピーを 使用したほうがよいので 新しいシステムで実行する場合には App内のコピーは動かなくなります ランタイムを持つOSの デバイスにダウンロードするときに iOSのApp Storeは最適化として ランタイムのコピーを送信します つまりユーザがダウンロードの コストを負担する必要はありません
これはコード・サイズの重要な利点です しかし OSでランタイムを使用する 最大の利点は OSの一部として 最適化できることです それはApp自体にも恩恵を与えます もうひとつの利点は起動時間です 1年前 Swift 4.2について話しました
単に起動するだけの Objective-CのAppがあるとします 同様に 起動するだけのSwiftのAppと 起動時間を比べます Swiftでは ランタイムの処理のために コストが約5%上がります AppをSwift 5で再コンパイルして 共有ランタイムで実行すると その余分なコストはなくなります (拍手) 待機時間は ユーザが Appを起動させた瞬間と 実際にAppが起動する時間の差であり とても重要です
もうひとつの最適化した点は コンパイラからのコードの調整です SwiftのAppのサイズを 格段に小さくしました これは SwiftのAppの 特有のパターンを見たり コード生成の際に 辞書の書式が どう表現されたかなどの調整で いかなる場合でもコンパイラの出力が 最適化されていることを確認します 様々な最適化の結果 Swift 5.1コンパイラを使用すると コードサイズが最大で10%削減されます そして コードサイズを最適化すれば 約15%の減少になります かなり大きな差になります
ブリッジのパフォーマンスも 向上し続けています SwiftとObjective-Cの間の ブリッジについて説明しましょう この2つの言語の間には 相互運用性があります
SwiftとObjective-Cをブリッジする 共通のタイプがあり それがAPIの全体で使用されています StringとNSString DictionaryとNSDictionaryなどです これらの流通タイプの相互運用性は SwiftとObjective-C間では通例です Objective-CのAPIはSwiftの 流通タイプで再マッピングされます これはコンパイラの作業を 組み合わせたものですが APIの境界を越えて値を渡す ランタイムの側面もあります OSの一部になったSwiftを さらに調整した部分でもあります 例えば NSDictionaryとDictionary間の ブリッジは1.6倍速くなりました もし SwiftのStringを Objective-Cに渡し NSStringとしてブリッジすると 操作が最大で15倍高速になります (拍手) これはAPIエコシステム全体で使用する 型であるため 大きな差が出ます
私たちはStringの表現を洗練させ続け Swift 5では String型を大きく変更しました それは String型のUnicodeを UTF-16から UTF-8に変えることでした
これは 完全に パフォーマンスを目的としています この変更についての詳細は swift.orgを参照してください 技術的な変更点と変更理由についての ブログが掲載されています 重要な点を強調しておきます Swiftは“C”のようなパフォーマンスを 実現するために作りました しかし重要な点はSwiftと既存の “C”のAPIの相互運用性が高いことです SwiftがUTF-16を使っていたときは “C”のAPIにStringを渡す場合 割り当てとコピー そして コード変換が必要でした 互換性のあるフォーマットに するためです かなり大変な作業です UTF-8に変更すれば Stringをそのまま渡すことができます 割り当てもコピーも 余分な作業もありません
String型自体の最適化も 強化できました 最適化されたStringでは 15文字以下の場合の割り当ては不要で 文字のペイロードは Stringの値そのものに入ります これも嬉しい展開です さらにSwift 5では ASCIIだけでなく 全てのUnicodeを含められます つまり ローマ字以外を含む言語にも 適用されるようになりました
これをNSStringとStringの間の 相互運用性を維持しながら行いました パフォーマンスの向上は 非常にすばらしいことです SwiftNIOはその一例です SwiftNIOは Swiftをサーバー側で使う クロスプラットフォームで ネットワークプロトコルとサービスを 構築するためのフレームワークです スピード向上のために 調整されています UTF-8に切り替えることで SwiftNIO上にビルドされたweb serverの スループットが20%向上します これは テキスト処理の 単なるベンチマークにすぎません 高度な操作が可能な String型にするという目的に 沿っています しかし それだけでなく ユーザーフレンドリーでもあります
Swift 5とSwift 5.1の言語に関する 変更点についてアナが話す前に オープンソース プロジェクトの主要な ツールや改良点について説明します
Swiftがオープンソースなのは プロジェクトの進み方のことだけでなく ソフトウェアの広範で多様な エコシステムの一部だということです 例えば Swiftコミュニティ内の Docker Hub上でホストされている― 公式のDockerイメージを 作成するという例もあります MacにDockerが インストールされていれば Dockerイメージを ダウンロードできます コンパイラと Package Managerを含む― Docker Linuxコンテナを 作動できるのです 今やコンテナはサービスを構築する 本質的な部分とみなされていますね
重要な オープンソースの技術といえば SourceKitもそうです これは Xcodeの機能の背後にある セマンティックコードエンジンで コード補完や定義へのジャンプ リファクタリングなどです 今後もこれらの改良を続け コード補完の結果を向上させていきます
こういった取り組みの他にも 信頼性と安定性を高めたいと思います
今年の取り組みに SourceKit用の新たなストレステストの ツールの構築があります それはIDEが発行する全てのクエリを SourceKitに送り込み SourceKitの問題を解決するものです クラッシュやアサーションなど 再現性のあるテストケースを作成します 使う側の視点に立ち― 私たちはSwiftで作る最良のツールを 提供したいと考えています 自分たちのワークフローでも使うので 皆さんと同じぐらい期待しています この取り組みは 現在のプロジェクトにおける エンジニアリングの中核部分です
そこで 将来を見据えたSourceKitへの 投資について話します それは language server protocolを 採用することです このスライドの例をご覧ください Xcodeを使って この図を多様な エディタやツールに一般化できます オープンソースであるSourceKitは 再利用が可能なように設計されています
動きはしますが とても古いモデルです 世の中には 多種多様な ツールやエディタ IDがあり 異なる言語サービスに 接続する必要があります SourceKitに接続するために 実装が可能でも 場当たり的な方法です それぞれのエディタに独自のサポートを 結び付ける必要があり 接続する全てのサービスに対する 理解が必要になり 拡張性がありません ただ コンピューター科学の様々な 問題と同様に 間接層で解決できます その例として業界標準のソリューション LSPが登場したのです もしエディタが標準的なクエリである LSPを話す場合 サービスはそれに対応し 簡単に統合することができます 現在進行中のこの取り組みを ぜひチェックしてください 今からお見せする動画は SourceKit LSPを使って コード補完をサポートする様子と 様々なエディタに対する サポートを表しています 手順は GitHubページにあります (拍手) 私たちにとって 非常に刺激的な投資です Swiftは 私たちが 一般向けに構築した言語だからです 大きな可能性を秘めているので 多様なソフトウェアシステムを 成功に導くでしょう
ここで 同僚のアナ・ザックスと 代わります Swiftの言語の変更について ご説明します (拍手) ありがとう テッド プロジェクトとコンパイラの 改良の説明に続き Swift 5と5.1の言語と標準ライブラリの 改善点をご説明します それにより 言語とライブラリの 主要部分が洗練されました 今年 主要なSwiftのフレームワークを 出荷するAppleと連携して より良いSwift APIの作成を サポートする機能を追加しました ご存じの通り Swift言語の 展開予定は公開されています スライドの“SE”がついた番号は Swift EvolutionのWebサイトに 掲載された文書に対応しています 機能の詳細は こちらをご覧ください ここでは簡単にご紹介します
ブロックを埋めていく例を 見てみましょう
単一のクロージャの シンタックスの簡素さは 多くの人が好みます リターン値は単一での記述が必要です 関数 メソッド サブスクリプトなどに 不要な負担がかかるでしょう 今ではシンプルなシンタックスが どこでも使用可能になりました (拍手) また アレハンドロ·アロンソは 問題解決に貢献してくれました 驚くことに 彼は高校を卒業したばかりです この構造は“未”と“済み”両方の プロパティのデフォルト値を定義します 以前はイニシャライザを呼び出して 引数をパスしないか 全ての引数をパスするかの二択でした 引数の一部だけを パスすることはできなかったのです Swift 5では この問題が修正され 全てが思い通りに作動します (拍手) コンパイラは イニシャライザを生成します
そのほかの改善点は 高性能コンピューティングです Swift 5では標準ライブラリに SIMDのサポートを追加しました これは グラフィック用のコードを 書くために使われます 例えば 画像処理やARなどです 今年出荷される新しい RealityKitライブラリに使われています 新しいSIMDの型は 固定サイズの SIMDのベクトルを表します ご期待の通り 標準ライブラリの整数と 浮動小数点を要素として使えるのです ではこれらの型で何ができるか 説明しましょう
SIMDのベクトルは配列リテラルから 初期化できます ここではサイズ4の配列が2つあります 新しいドット演算子を使うと ベクトルに対して 性質や比較など 個別の演算を実行できます ここでは xがyより大きいかどうかを チェックします 最後の2点でのみ yよりxが大きい結果が示されています
結果はSIMDMaskという 別の型に保存されます SIMDMask型のドット演算子を使うと 結果のマスクをさらに操作可能です 例えばここでは 前の計算結果を無効にしています
Swift 5は テキスト操作の表現力を 高めてくれます Swift 5ではStringの補間が 再設計されました 新しいデザインでは 最大で1.7倍速くなり さらに自身のヘルパーを提供することで 補間をカスタマイズできます そして補間されたStringで 自身の型を初期化できます
Swiftは当初から文字列補間を サポートしてきました ストリング・リテラル内の引用符を バックスラッシュに続けて書くと コンパイラがコードを実行して Stringを実行し 値を挿入します 以上は 最初から使えた機能ですが 制限がありました 例えば NSLocalizedStringの中では 文字列補間は機能しません 補間は変換の前に行われます この例で言うと 全ての整数値が挿入された Stringの変換は含まれません そのため ここでは“You have 10 apples”は変換されません まずはformatStringを 構築する必要があります
そして 次はローカライズです その後でローカライズされたStringに 値を挿入します 以上がUIKitとAppKitでStringの ローカライズを行う正しい方法です 新しい文字列補間の設計は さらに進歩しており フレームワークであるSwiftUIの テキストのような 表現豊かなAPIを設計します テキストはSwiftUIで ラベルに使用されるので ローカライズしたいですね では 内容を見てみましょう ここでは補間されたStringを テキストのイニシャライザに渡します イニシャライザはインプットとして String型を受けません LocalizedStringKeyと呼ばれ SwiftUIで定義される型を取ります そのため Swiftコンパイラは この補間を処理するために 文字列補間プロトコルの表現に コストと適合を使用します 使用する適合が判明すると コンパイラはString補間を 自動生成コードで変換します 次のステップに進みます まずSwiftはLocalizedStringKey用の ビルダーのために インスタンスを作成します このインスタンスは formatKeyと引数配列を 分けて取っておきます
次に補間のセグメントを処理して Stringを作成しましょう まず 文字列のリテラルをformatKeyに 追加します 次に 処理する量について formatKey内のフォーマット指定子と 引数配列内の値を別々に復元します
最後に別のリテラルを追加します
これで LocalizedStringKeyの イニシャライザが呼び出されます この時点でStringを正しくローカライズ するための十分な情報があります
SwiftUIがこの言語機能を使用して テキストをローカライズするので ユーザはメッセージを読めます (拍手) これは文字列補間でできることの ほんの一例にすぎません この機能について興味がある方は ExpressibleByStringInterpolationの 資料をお読みください
それでは Focusについて話します API設計の一部が 何を除外するかを決定します Swift 5.1では戻り値の型について 特に改良を加えました
重要な点は APIのユーザが 推論できるような― リターンの型を使うことです しかし リターンの内容を 抽象化したい場合もあります 関数は 実行時に 複数の型を返すこともあれば 常に同じ型を返す場合もあります しかし その型はユーザが 推論するべきでない何かを明らかにし APIの実装に関する詳細を 漏らす可能性があります Swiftがこれらのケースに対して 提供するオプションを見てみましょう
この例では 単純な形のAPIを使います “Shape”というプロトコルです 円 楕円 正方形など 基本的な形状を定義する型があります さらに 図形を操作し結合して 変換する構造があります この“FaceShape”を 例にしましょう APIはフェイス形の種類に応じて 異なる型をリターンしますが それらは全て 形状プロトコルに準拠しています 従って 戻り値の型として プロトコル型を使うのは適切です
では 四角形と変形した四角形を 結合させて 8角の星を作成する例では どうでしょうか 明確なリターンの型を示すと 実装の詳細がクライアントに漏れ 不必要な詳細の公開により APIの 今後の動作が推測しにくくなります
しかし プロトコルタイプの形状を 使うのも良策とは言えません 理由を見てみましょう どの呼び出しに対しても 同じ型が返される保証はありません これが本質的な限界になるのです 同じAPIを別々に呼び出し 8角星の2つの値が返された場合は どうでしょう 型が異なる可能性があるため 同じ値かどうか 比較ができません リターンの型は関連する型や それ自体を含む要件は持てないのです 型のIDを失うと コンパイラの 最適化が妨げられるかもしれません
Swift 5.1には Opaque Result Typeという 概念が導入されました 同じ型を返すというのは APIの優れた点ではありますが ユーザに型を隠したい場合もあります Opaque Result Typeは “some Shape”とします 特定の形状の型がAPIから リターンされたことを伝えます
型の同一性が保証され API内部で 厳格なチェックが実行されます 異なる型のリターンが 複数ある場合には コンパイラが察知して 問題を解決するように促します
これはSwift 5.1から使えます 詳細は文書で確認できます この機能には 新しいSwiftランタイムが必要なので 新しいSwiftが入ったOSでしか 動作しません 前バージョンへのデプロイでも この機能は使えますが 可用性チェックで 利用できるかどうか 確認する必要があります
次は コードの再利用と Property Wrappersについて 説明します プロパティへのアクセスには カスタムのパターンがよく使われます lazyなどのパターンが Swift内でサポートされていますが あなた自身もカスタムのラッパーを 作っているかもしれません ローカルのスレッドにアクセスする ストレージがあるかもしれませんし ユーザーデフォルトを保存するための プロパティを持っているかもしれません 私たちはカスタムゲッターと セッターを書きますが そのコードが 繰り返されることもあります 例えばここに ユーザの既定値を 指定する2つのプロパティがあります しかし コードの大部分は単に コピーしてペーストされただけです
Property Wrappersを使って アクセスパターンを指定する 型が宣言されます
これをユーザデフォルトと呼びます 次に この型が特殊であることを コンパイラに伝えます 主な目的は プロパティをラップし アクセスパターンを指定することです この型によりカスタム属性を使い UserDefaultsを操作する プロパティを宣言できます 詳しく見てみましょう Property Wrappersがあることで 2人のユーザのデフォルトの プロパティを書き換えられます 繰り返しがなくなり とても簡潔です 必要なのは カスタム属性を追加することだけです
これらのプロパティは Bool型として宣言されているので 単純なブール値のように 使用できます (拍手) Property Wrappersによって アクセスパターンは定義できます そして 宣言にカスタム属性を 足すだけで その定義をプロパティに 当てはめられます
問題を解決するためには 問題に合ったツールが望ましいです 同様にDSLはプログラマーにとって 重要な役割を果たします データベースを照会して グラフを作成するために使うのです ウェブページのレイアウトを シンプルに簡潔にする― その宣言的スタイルが人気です しかし DSLはどれも異なります コンテキストスイッチとして使うたびに それぞれの言語にシンタックスと セマンティックを伴います それらをサポートする 独自のツールがあります HTMLのエディタの中に HTMLタグがない場合は 非常に簡単です シンタックスとセマンティックは 特定の目的に合わせて調整されいて それらをサポートするツールも ドメイン固有のものです
これらのDSLをプロジェクトに 統合する必要がある場合 選択肢はそれほどありません カスタムビルドフェーズを 追加するのは例外的です 見覚えがあると思いますが HTMLを表す文字列のリテラルです 統合され ツールのサポートを失いました コンパイラのコード補完は これをStringと見なします 型のチェックはなく Swiftコンパイラのテキストです 終了タグを忘れるなどのミスは 実行時まで気付かれません DSLは必要なのですが 言語とツールに うまく統合されることが大切です
Swift 5.1では 埋め込まれたDSLを 定義する機能を取り入れています (拍手) HTMLのオブジェクトを定義する コードを見てみましょう 私の同僚が この新しいSwiftの機能を使い ほんの数時間で HTML DSLの サポートをプロトタイプ化しました このコードは Swiftのように見えますが ご覧のように中身は HTML要素を定義しています クロージャやメソッドコールのような よく知られたSwiftの概念があります 私たちはSwiftプログラムの変数を 使用しています ツールは不均衡なテキストがないことを 確実にして シンタックスの要点とリファクタリング アクションを提供します 私たちの構想は 要素のリストを宣言するだけでなく このDSLのように Swiftの制御 ステートメントを使用できることです
どうも (拍手) では 実装の内容を見てみましょう DSLの実装者がそれぞれの HTML要素を構築する関数を追加しました これらの関数はクロージャです 興味深いのは これらのクロージャが 特別なものだということです どれも@HTMLBuilderという カスタム属性を持ち @HTMLBuilder型を使い クロージャを 処理する旨をコンパイラに伝えます
DSLコードを含むクロージャが どう変換されるのか見てましょう このDSLクロージャは 値のバッチを作っています ただし それらの値は使用されず returnステートメントもありません
これを機能させるために コンパイラは まず 未使用の値を収集し コードを変換します
次に ビルダー機能を呼び出して それらを結合します DSLの開発者が書いたHTMLビルダー型が 提供するこの機能は DSLに最適なオブジェクトを構築します ここではHTMLを構築しているので HTMLオブジェクトが構築されます
宣言型シンタックスを強化する この素晴らしい機能を 新しいSwiftUIフレームワークで ぜひ役立ててください (拍手) これは SwiftUIで独自のカスタムの Swift DSLを使った例です この機能はベータ1版で利用可能です 今後この機能によって どのようなDSLが 構築されるのか楽しみです この機能の詳細については Swiftのフォーラムで議論されています これらの機能が今後どうなるか また 他のSwiftの機能にご興味があれば ぜひ参加してください
本日 お話しした改良点の多くは 今年出荷される新しいSwiftの フレームワークに集約されています これによって 皆さんがAPIを― 表現力豊かな 明確な 使いやすいものにすることを期待します 私たちの同僚がSwift APIの デザインについて講演する予定です Appleフレームワークを構築する際に 学んだ教訓を 皆さんと共有します 以上で終わります ありがとうございました (拍手)
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。