ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
Swiftの新機能
Swiftの新機能をご紹介します。より早く読み込み、編集し、デバッグするコードを作成できるというデベロッパ体験の向上と共に、ランタイムパフォーマンスの最新の成果をお見せします。複数のtrailing closureといった新しい言語機能の活用方法もお伝えします。SDKで利用可能な新しいライブラリやSwift Packagesとして増え続ける数々の利用可能なAPIについてもご説明します。
リソース
- Swift Argument Parser on GitHub
- Swift Evolution
- Swift Numerics on GitHub
- Swift Standard Library Preview
- The Swift Programming Language
関連ビデオ
WWDC20
-
ダウンロード
こんにちは WWDCへようこそ “Swiftの新機能” 私はテッドです Swiftの新機能をご紹介します 現在 Swiftのエコシステムは 多方面で大いに盛り上がっています Swift 5がABIの安定化を 導入したことで― バイナリフレームワークが利用可能に これにより Appleの開発者体験にとって重要である SwiftUIなどのパワフルなAPIが登場しました この1年間 Swiftには さまざまな形で 多くの投資が行われてきました これから Swiftは AppleのAPIや― OSのコアやデベロッパのエコシステムに さらに大きな影響をもたらします
Swift Package Managerを使い Xcodeで 快適にアプリケーション開発が行えるという― Swiftの強みを生かした オープンソースのAPIも増えてきています Swiftはクロスプラットフォーム言語として 対応できるドメインを増やし続けています 過去最多のプラットフォームに対応可能です 最新版のXcodeとSwiftでは パフォーマンス 言語の洗練度 開発者体験が向上しました
まずはSwiftのランタイム・パフォーマンスが いかに向上したかを見てみましょう
1つ目のポイントは コードサイズです コードサイズはアプリケーションのロジックに 該当するマシンコードのサイズです この部分は 直近のリリースにおいて 最適化の焦点でした
向上度を測るため iOSに付属する アプリケーションをSwiftで書き換え― Swift版とObjective-C版のアプリケーションの コードサイズを比較しました
当初 Swift版のコードサイズは Objective-C版の約2.3倍でした
Swift 4.1では 最適化設定により コードサイズを大幅に削減し―
それ以降も リリースの度に この差を縮めました そして Swift 5.3では 1.5倍以下まで削減したのです この多少の差はやむを得ません 安全性を確保するためです 安全機能を実装するには ある程度のコードサイズが必要です しかし アプリケーションの形式によって バイナリサイズは異なります 先ほどの例はUIKitアプリケーションでした では SwiftUIアプリケーションなら?
Swift 5.3は SwiftUIアプリケーションの コードサイズを大幅に改善しました これはMovieSwiftUIという オープンソースアプリケーションです このアプリケーションでは コードサイズが 40%以上も減少しています バイナリサイズは ダウンロード時間などに直結しますが アプリケーションの実行中においては クリーン・メモリの一部です このメモリは必要な時に リロードできるので 削除できます そのため 実行時にアプリケーションが操作する ダーティ・メモリほど重要ではありません では ダーティ・メモリの使用量は どれほど改善したのでしょうか Swiftの値型の使用には リファレンス型の 基準言語に比べ抜本的な利点があります Objective-Cのシンプルな UUIDと文字列と数値を例にします このモデルをメモリに格納し どのように保持されているか見てみましょう Objective-Cでは対象変数はポインタです したがって配列はモデルオブジェクトを指します
すると モデルオブジェクトは プロパティを指します それぞれのオブジェクトが 余分にメモリを使用しています 重要なのは Objective-Cに備わる ASCII文字列用の文字列表現です 追加オブジェクトの割り当てを節約するため ポインタ内に格納できるのです
では Swiftで同じモデルを見てみましょう 値型を使用するため ポインタを介して アクセスする必要がありません そのため UUIDは オブジェクト内に保持できます また SwiftのString型は より多くの文字列を保持できます 非ASCII文字を含む 最大15コードユニットが可能です その結果 全オブジェクトを配列内に 直接割り当てることができます よって いくつかの文字列を除き 連続したメモリブロックに保持されます このように 値型を使用することで メモリに大きなメリットがあるのです 400個のモデルオブジェクトを配列し 使用されるメモリを調べると― Objective-Cの35KBに対しSwiftは20KBで 非常にコンパクトです なお これはSwift 5.1以降の測定値です
以前のSwiftプログラムは― 実行時のオーバヘッドのため 多くのヒープメモリを使用していました 従来は 起動時に多数の キャッシュとメモリを作成 キャッシュが格納していたのは プロトコルの適合性などの情報や Objective-Cとの連携に使うデータでした
どんな言語にもオーバヘッドはありますが Swiftの場合は大きすぎました 私たちは この最適化に力を注ぎました
そして Swift 5.3では オーバヘッドの大幅な削減に成功しました Swift 5.3で使用するヒープメモリは 昨年のバージョンの3分の1です これを最大限に生かすには アプリケーションの 動作環境をiOS 14に設定する必要があります ですが これらの改善点は旧OSで使用される アプリケーションにも利点があります
ほとんどのアプリケーションでは 改善点はあまり目立ちませんが― メモリを最適化することで SwiftはAppleシステム全体にさらに浸透します 省メモリが重要なDaemonや低水準の フレームワークでも使用可能になるのです
そのために もう1つ重要な変更を行いました Swiftの標準ライブラリを Foundationの下に移動したのです よって Objective-C以下の フレームワークにも実装できます 以前ならばC言語を使う必要がありました
次に 開発者体験の向上を見ていきましょう コンパイラからの診断 エラーや警告が 今回のバージョンでは大幅に改善しました コンパイラの新たな診断機能は 問題を起こしているソースコードの位置を より正確に突き止めます 新たなヒューリスティックで 問題の原因を診断し 解決方法をガイダンスします
ここに 不可解な診断の事例があります 1年前のSwift 5.1コンパイラが SwiftUIコードに出した診断です
最新版では診断が大幅に改善されています 表示されるエラーは 何が問題なのか正確に伝えます コンパイラは診断の際に 問題に関する詳しい情報も内部に記録し 補足の情報も表示します これらの情報があれば多くの場合 デベロッパは問題を理解し解決できるでしょう この例では 修正を適用すると テキストフィールドの不完全な部分に 欠けている情報を入れるよう案内されます
コンパイラの新しい診断アーキテクチャに 興味がある場合は Swift.orgにアクセスして ブログ記事をご覧ください
Swift5.3では コード補完も劇的に改善しました コンパイラとSourceKitによる コード補完の推論と Xcodeエディタでの経験に基づいています それでは 補完結果が いかに大きく向上したか見てみましょう まず 補完候補の推論が大幅に改善されました この例では 不完全な辞書リテラル内での 三項演算子の値を推論しています 以前は不可能だったでしょう さらに コード補完には KeyPathを関数として使用するなど 動的な機能に要求されている値を 候補として出します
補完結果の品質だけでなく パフォーマンスも劇的に向上しました Xcode 11.5と比較して 最大15倍の速度向上を実現しています
特に SwiftUIコードの編集に役立ちます この棒グラフは SwiftUIコードの 補完パフォーマンスを秒単位で示しています Xcode 11.5では コード補完の 完了まで 約0.5秒かかっていました 今では0.1秒未満です
SourceKitエンジンも備えた Xcodeのコードインデントが改善されました SwiftUIコードの主要な構成要素である メソッドチェーンでの呼び出しや プロパティアクセスの処理 呼び出し引数 ダブルの要素― 複数行にまたがるコレクション要素や 制御フローなどが改善されました
MovieSwiftUIプロジェクトから得た SwiftUIコードの改善例です 以前は 連結されたアクセスの一部に インデントが発生することがありました
でも 今ではきれいに整列しています こうした改善点により 編集エクスペリエンスは 大幅に向上するでしょう 次に Swiftコードのデバッグの 改善についてお話しします
デバッグ情報が利用可能な場合 一般的な ランタイム障害トラップの理由を表示します 分かりにくく“無効な命令”と 表示するだけではありません
また Swiftのデバッグサポートは より強固になりました SwiftとObjective-Cの コンパイル時の相互運用を見てみましょう SwiftはClangモジュールを使い Objective-CからAPIをインポートします LLDBは 現在のデバッグコンテキストで 表示されている すべてのSwiftとClangモジュールを インポートする必要があります モジュールファイルには 型に関する情報が豊富です LLDBはプログラム全体と すべての動的ライブラリを見られるからです ですが Clangモジュールのインポートは 失敗することがあります 一般的に原因となるのは 異なる動的ライブラリからの検索パスが 競合していることです これが発生した場合 今のLLDBは DWARFのデバッグ情報から CやObjective-Cの型をインポートできます これにより Xcodeの変数ビューや 式エバリュエーターなどの信頼性が 大幅に向上しました
Swiftは優れた汎用言語です Appleのプラットフォーム上だけでなく 他のタスクにも最適です そのため クロスプラットフォームサポートに 力を入れ―
より多くのプラットフォームへの 公式サポートを拡大しています 今年はUbuntuのサポートを更新し CentOSやAmazon Linux 2の Linuxの公式サポートも受けました また 初となる Windowsのサポートを予定しています 詳細はSwift.orgをフォローして 確認してください これらの移植により Swiftが使用される場はさらに増えます その1つがAWS Lambdaです サーバーレス機能はデベロッパが アプリケーションをクラウドに拡張する手段です Swift AWS Lambda Runtimeを使えば Swiftで簡単にできるようになりました これはオープンソースで GitHubで入手できます Swiftコミュニティのエンジニアたちの 努力の結晶です AWS Lambdaへのビルドとデプロイや プログラミングの方法も記載されています このXcodeの例のように 必要なコード量は少なくシンプルです これらは Swiftエコシステムの更新の 一部にすぎません 次は カイルがSwift言語とライブラリの 変更点についてお話しします こんにちは Swift標準ライブラリチームのカイルです この1年で Swift言語とライブラリは 大きく進化しました まずは言語について話しましょう 先ほどテッドが説明した改善点に加え Swift 5.2と5.3では 12以上の新しい言語機能が追加されました すべてをご紹介する時間はないので SEの付いた番号にご注目ください
Swift言語はオープンな進化プロセスを 経ています これらの数字はSwift Evolutionの ウェブサイトの文書に対応しています Swiftの未来に興味がある方は ぜひこのウェブサイトをご覧ください それでは 本題です 追加機能のいくつかは APIデザイナーが 利用できる強力な新しいツールです 人気パッケージを保持する場合も チームで作業する場合も 個人でも すべての人が利用できます コードを書けばAPIが設計できます マルチプルトレーリングクロージャ構文から 始めましょう Swiftがずっとサポートしてきたのが この構文です これは メソッドの最後の引数を括弧から 取り出せる糖衣構文です トレーリングクロージャ構文が 大人気なのは当然です より簡潔でネスト化を減らせるため コードを格段に読み込みやすくなります ただし この構文は 最後のクロージャにしか使えず 適用範囲に制限があります
この場合は トレーリングクロージャの役割が 不明確なため コードが読みにくくなります さらに悪いことに ブロックによって意味が変わってしまいます メソッドコールが複数のクロージャの引数を 持つ場合 混乱を防ぐため― トレーリングクロージャ構文の使用を 禁止するようになりました
その結果 クロージャの引数を 追加する必要がある場合― 必要以上にコードを再設定しなければなりません
Swift 5.3では マルチプル トレーリングクロージャ構文が追加されました
構文の利点が複数のクロージャ引数を 使用した呼び出しに拡張され 引数を追加するために 再調整する必要はありません 複数のトレーリングクロージャ構文は DSLにも最適です SwiftUIの新しいゲージは 全体の容量に対する値のレベルを示します これは 私の庭の土の酸性度を 監視しているwatchOSのゲージです トマトはとても繊細なので 一目で正確な数値を知りたいです 幸い 現在の値ラベルと 最小値と最大値のラベルを追加可能です マルチプルトレーリングクロージャ構文を 利用することで Gaugeはカスタマイゼーションポイントを 段階的に公開できます SwiftのAPI設計に対する トレーリングクロージャ構文の 影響を見てみましょう 作業中のメッセージアプリケーションで このコードに遭遇したとします サマリーは最後のメッセージの スニペットの表示に使用されています サマリーの値は? takeメソッドの呼び出しは何をしていますか? クロージャがどの文字を取るか決めますが どのように適用されているでしょう? 考えてみてください
述語に合う文字を取り 合わない文字を落としているのでしょうか?
述語に合う文字を取り その後の字は すべて落としているのでしょうか? コールサイトが明確になるのは 引数ラベルを付けた表記を使用する場合のみです
もっといい手があります 引数ラベルを削除する可能性を前提に メソッドを命名するのが最善です “take”より“prefix”という名前が いいかもしれません 結果がコレクションの先頭に 固定されていることを示します 実際 このメソッドがSwift 3.1で 標準ライブラリに追加された際は “prefix(while”という名前でした これはマルチプルトレーリングクロージャ構文や より複雑なAPIにも当てはまります メソッドの名前は その役割を明確にすることが大切です そのラベルはメソッドの第一引数でなくても 削除されるからです 次に 関数としての KeyPath式について説明します KeyPathはSwift 4.1で導入されました プロパティの値を取得・設定するための 呼び出されていない参照を表す型です
APIを設計する際 KeyPathは 関数のパラメータに代わる魅力的な手段です より簡潔でネスト化が少ないためです この例では Rubyから アルゴリズム“Chunked”を借用しました 隣接する要素のキーが等しい時にグループ化する コレクションのアダプタです 私は友人や家族の靴のサイズを リストにしています 靴はプレゼントに最適です ソートして 連絡先を靴のサイズごとに分ければ 簡単に全体を確認できます
要らない靴を貰ったら サイズが同じチャールズにあげよう 単純なプロパティアクセスではない ユースケースに遭遇することもあるでしょう 例えば ハーフサイズがないサンダルを 買うとします 両方のコールサイトに対応するには 宣言を重複して行う必要があります Swift 5.2ではKeyPath式を 関数として使えるようになりました
一致するシグネチャを持つ任意の 関数パラメータにKeyPath引数を渡せます そして KeyPathを受け入れるために 過去の重複した宣言を削除できます 次に@mainを紹介します エントリーポイント用のツールです どのプログラムも実行の開始が必要です 新しく“ArgumentParser”が “Hello”の出力ツールの宣言に使われています
ですが実行開始に必要な ボイラープレートの長さは プログラム自体と同等です
Swift 1.0以降は UIApplicationMain属性で 暗黙的なmain.swiftを生成できるようになり Swift 5.3ではこの機能が一般化されました
ライブラリ作成者は静的なmainメソッドを プロトコルやスーパークラスで 宣言するだけで大丈夫です
使うのはParsableCommandです ユーザーは@mainでこの型へのタグ付けができ 暗黙的なmain.swiftが生成されます エントリーポイントへの参照が 立ち上げと実行をより簡単にします コマンドラインツールや 既存のアプリケーション―
新しいアプリケーションなどが 扱いやすくなります パワフルで新しいAPI設計ツールに ご期待ください 次は言語機能の強化についてです ボイラープレートを削減できるようになり 表現力が向上しました まずはクロージャにおける 暗黙的なselfの可用性です 保持サイクルの想定が大事になるため Swiftではselfを 明示的に使用する必要があります ただselfが多く含まれると 少し冗長な印象を受けます
Swift 5.3の場合 キャプチャリストに含めれば 本文からselfを省略できます
キャプチャを明示的に示す必要はありますが そのために行う宣言は1度のみで済みます
しかし selfを一度も使用しない場合もあります selfが値型になるSwiftUIでは 参照サイクルが発生しにくくなります Swift 5.3を使用すれば 構造体や列挙型のselfを クロージャから省略できます
今回の強化で selfの暗黙的利用に関する― コンパイラのエラーの SN比が増加する見込みです 誤ってselfを処理する可能性も低くなります 次は複数のパターンのキャッチ句です do-catchはswitchほど表現力がなかったため switchをキャッチ句内で ネストしていました Swift 5.3では キャッチ句が拡張され switchの全機能が備わっています
複数の句のパターンマッチングを 直接do-catchに組み込めるので より読みやすくなります 次は列挙型の拡張機能を見ていきましょう Swift 4.1以降 HashableとEquatableは合成することができます
ですが 比較演算子があると 非常に便利な場合もあります Swift 5.3のコンパイラは 列挙型を修飾する同質の適合性を 合成させることができます 次は列挙型のcaseについてお話しします 2つの呼び出しサイトです fileCorruptedは静的変数かcaseか
keyNotFoundは静的関数かcaseか
静的変数や静的関数でありcaseでもあります 2つの宣言の呼び出しサイトは同じです
Swift 5.3では列挙型のcaseが強化され 静的変数と静的関数のプロトコル要件を 満たすための使用が可能です 昨年 組み込みDSLのサポートが追加され SwiftUIの構文が強化されました 更新されたのはビルダのクロージャや 基本的な制御フローのステートメントです
Swift 5.3では組み込みDSLが拡張され switchなどのステートメントがサポートされます これは 私のお気に入りの動物のギャラリーです switchステートメントを使用して 画像を切り替えることができます 次は ビルダの推論についてです 私が読んでいる本を追跡する アプリケーションを作成しました
ウィンドウはインターフェイス用と アプリケーション設定用があります 以前は 本文の最上位でDSL構文を使用する際 特定のビルダ属性でのタグ付けが必要でした ですが Swift 5.3ではビルダ属性は不要です プロトコル要件からの推論が プログラムされているのです
SwiftUIには多くの新機能があります 詳細については 新機能のセッションをご覧ください ここからは パワフルで新しいSwiftのAPIのお話です まずはSDKのAPIです Float16から見ていきます Float16は IEEE 754標準の形式で Swift 5.3の新機能です
名前が示すとおり メモリは2バイトのみで 単精度浮動小数点数とは異なります
サイズが半分なので メモリのページなどには倍の規模が適用され ハードウェアでの パフォーマンスが2倍になります
ただし データ型が小さいと 精度と範囲が制限されるので 倍精度や単精度で機能するように実装された コードのFloat16への変換には注意が必要です
詳細については “Numerical Computing in Swift”をご覧ください
次は新しいモジュール式のApple Archiveです OSのアップデート提供の テクノロジーに基づいています
高速でマルチスレッドの圧縮用に最適化され Finderの統合も可能で コマンドラインツールも用意されています 慣用的なSwiftのAPIも実装できます これを見れば Apple Archiveによる 処理の効率性が分かります
このFileStreamでは 今年導入するSwift Systemを活用します
Swift SystemではローレベルAPIの システムコールや通貨型への インターフェイスが行えます
Darwinからのインターフェイスは エラーが生じやすくなります
Swift Systemでは これらのAPIがラップされます エラー処理 デフォルト引数 名前空間などが用いられ より慣用的なSwiftのレイヤーの土台が 出来上がります 次はOSLogの機能強化についてです OSLogは統一のロギングAPIで 意図せぬ機密データのロギング防止と オーバヘッドの抑制に使用します
Swift 5.3では コンパイラが高度に最適化され OSLogが劇的に高速化し 表現力も高まりました 文字列補間や フォーマットオプションも使えます 今こそロギングソリューションを見直す 絶好の機会です これらのAPIや ロギングによるバグ追跡についての詳細は “Logging in Swift”セッションを 参照してください Swift Package Managerを活用し SDK以外で実装できるAPIも増えています まずは数値計算用のSwift Numericsです
サインや対数など 基本的な関数がすべて定義されています 一般的なコンテキストだけでなく 複素数や算術のサポートとしても機能します 複素数にはCとの レイアウトの互換性がありますが より高速で正確です
GitHubでもSwift Numericsが扱われています 近似式の比較 任意精度の整数 10進浮動小数点数などがご覧になれます
“Numerical Computing”セッションでも 詳細情報を入手することができます 次はSwift ArgumentParser コマンドライン引数解析用の 新しいパッケージです 先ほど ArgumentParserによる 出力を紹介しました
これに整数のオプションを追加します countのデフォルト 1です
countの頻度で出力するループも設定します
これでツールがより高度になります
処理する値の選別も正確に行われ
ユーザーは正しく利用できます
また ヘルプ画面も充実しています
これらすべてのプログラムは スライド上で参照できます
最後は Swift StandardLibraryPreview パッケージです Swift Evolutionの機能にアクセスできますが 公式にリリースされた機能ではありません 新機能を早く試すことは Swiftの強化につながります 実際 Swift Evolutionへの提案は簡単に行えます 前はコンパイラのスタック全体の 構築が必要でしたが 今はStandardLibraryに提案する機能を スタンドアロンとして提供できます
SE-0270の機能もパッケージに追加しました コレクションの部分的な操作や 一部のset型の参照ができます ぜひお試しください 今まさに Swiftライブラリの未来が 形成されています オープンソースのパッケージが増え続ける中で 新しいプラットフォームやドメインへの移行が 行われています パッケージのリリースは早めに行い GitHubを活用し 改善を加えられるようにしています
提案があれば プルリクエストを作成してみましょう
今こそ 皆が意見を出し合って 最高のものを作り上げる時です 今回リリースされた新しいSwiftを ぜひご活用ください 引き続きWWDCをお楽しみください
-
-
13:32 - Swift on AWS Lambda
import AWSLambdaRuntime Lambda.run { (_, event: String, callback) in callback(.success("Hello, \(event)")) }
-
21:08 - @main
// Type-based program entry points import ArgumentParser @main struct Hello: ParsableCommand { @Argument(help: "The name to greet.") var name: String func run() { print("Hello, \(name)!") } }
-
23:50 - Synthesized comparable conformance for enums
// Synthesized comparable conformance for enums enum MessageStatus: Hashable, Comparable { case draft case saved case failedToSend case sent case delivered case read var wasSent: Bool { self >= .sent } }
-
27:19 - Compress and archive a source directory using Apple Archive
// Apple Archive import AppleArchive try ArchiveByteStream.withFileStream( path: "/tmp/VacationPhotos.aar", mode: .writeOnly, options: [.create, .truncate], permissions: [.ownerReadWrite, .groupRead, .otherRead] ) { file in // Receives raw bytes and writes compressed bytes to `file` try ArchiveByteStream.withCompressionStream(using: .lzfse, writingTo: file) { compressor in // Receives archive entries, and writes bytes to `compressor` try ArchiveStream.withEncodeStream(writingTo: compressor) { encoder in // Writes all entries from `src` to `encoder` try encoder.writeDirectoryContents(archiveFrom: source, keySet: fieldKeySet) } } }
-
28:34 - OSLog support for String interpolations and formatting options
logger.log("\(offerID, align: .left(columns: 10), privacy: .public)") // Logs "E1Z3F " logger.log("\(seconds, format: .fixed(precision: 2)) seconds") // Logs "1.30 seconds"
-
30:05 - ArgumentParser Swift Package
// Swift ArgumentParser import ArgumentParser @main struct Hello: ParsableCommand { @Option(name: .shortAndLong, help: "The number of times to say hello.") var count: Int = 1 @Argument(help: "The name to greet.") var name: String func run() { for _ in 1...count { print("Hello, \(name)!") } } }
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。