WWDC Quick Look 💓 By SwiftGGTeam
Create seamless experiences with Virtualization

Create seamless experiences with Virtualization

元の動画を見る

ハイライト

macOS Sonoma の Virtualization framework は、サイズ変更可能なディスプレイ、VM 状態の保存/復元、Network Block Device(NBD)ストレージ、NVMe コントローラーサポート、Rosetta 2 キャッシュ最適化を追加し、仮想 Mac と Linux VM をより使いやすく、柔軟で、高性能にしました。

主要内容

以前、Virtualization framework で VM を動かすと、ディスプレイ解像度は固定でした。ウィンドウを大きくしても VM 画面は追従せず、黒帯が出るか、手動で解像度を変える必要がありました。仮想 Mac 内での日常作業体験はあまり良くありませんでした。

01:19)macOS Sonoma は automaticallyReconfiguresDisplay プロパティを追加しました。有効にすると、VM の表示解像度がウィンドウサイズにリアルタイムで追従し、画面利用率が向上します。

もう一つの課題は VM のライフサイクル管理でした。以前は VM を閉じると電源断と同じで、未保存の作業状態はすべて失われました。再起動はコールドブートで、アプリ、ドキュメント、ブラウザータブをすべて開き直す必要がありました。

01:31)Sonoma は保存と復元を導入しました。実行中の VM をディスクファイルに完全シリアライズし、いつでも保存時点の状態に復元できます。作業進捗のバックアップやタスク切り替えに有用です。

ストレージ面では、以前はディスクイメージをローカルに置くしかありませんでした。今は Network Block Device(NBD)プロトコルでリモートストレージをマウントでき、VM ディスクをリモートサーバー上に置けます。データセンターシナリオで特に価値があります。

12:04)Linux VM 内の Rosetta 2 性能も向上しました。翻訳キャッシュデーモンが追加され、繰り返し使う x86_64 コードの再翻訳が不要になり、コンパイルやパッケージインストールなど exec 集約タスクが明らかに速くなります。

詳細

サイズ変更可能なディスプレイ

01:58VZVirtualMachineView にブール属性 automaticallyReconfiguresDisplay が追加されました。true にすると、ウィンドウサイズ変更が VM の解像度調整を自動通知します。

let virtualMachineView = VZVirtualMachineView()
virtualMachineView.virtualMachine = virtualMachine

virtualMachineView.automaticallyReconfiguresDisplay = true

キーポイント:

  • VZVirtualMachineView は Virtualization framework が提供するネイティブビューコンポーネントです
  • automaticallyReconfiguresDisplay のデフォルトは false で、従来の固定解像度動作を維持します
  • true にすると VM 内部が表示設定変更イベントを受け、動的に解像度を調整します
  • 仮想 Mac と Linux VM の両方がこの機能をサポートします

VM 状態の保存と復元

04:20)保存前に VM を一時停止し、実行が安定状態であることを確認します:

// virtualMachine is a running VZVirtualMachine.
try await virtualMachine.pause()

let saveFileURL = URL(filePath: "SaveFile.vzvmsave", directoryHint: .notDirectory)
try await virtualMachine.saveMachineStateTo(url: saveFileURL)

キーポイント:

  • pause() で VM をサスペンドし、CPU 実行を停止します
  • saveMachineStateTo(url:) で完全なランタイム状態を指定ファイルに書き込みます
  • 外部リソース(ディスクイメージなど)は別途コピー/バックアップが必要です
  • 保存ファイルはハードウェア暗号化され、他の Mac やユーザーアカウントからは読めません

04:58)復元時は同一設定から新しい VM インスタンスを作成し、保存ファイルを読み込みます:

let configuration = VZVirtualMachineConfiguration()
// Customize configuration.

let virtualMachine = VZVirtualMachine(configuration: configuration)

let saveFileURL = URL(filePath: "SaveFile.vzvmsave", directoryHint: .notDirectory)
try await virtualMachine.restoreMachineStateFrom(url: saveFileURL)

try await virtualMachine.resume()

キーポイント:

  • 復元前に start() を直接呼ぶとコールドブートになります
  • restoreMachineStateFrom(url:) で保存状態データを読み込みます
  • resume() で実行を再開し、VM は保存時の正確な状態に戻ります
  • 保存ファイルにはバージョン番号があり、形式非互換時はフレームワークが特定エラーコードを返します

Network Block Device(NBD)ストレージ

09:28)Virtualization framework は NBD プロトコルのクライアントを実装しています。ストレージは任意の場所の NBD サーバー上に置けます:

let url = URL(string: "nbd://localhost:10809/myDisk")!
let attachment = try VZNetworkBlockDeviceStorageDeviceAttachment(url: url)

let blockDevice = VZVirtioBlockDeviceConfiguration(attachment: attachment)

キーポイント:

  • VZNetworkBlockDeviceStorageDeviceAttachment は新しいアタッチメントタイプです
  • URL 形式は nbd://host:port/diskName です
  • VZVirtioBlockDeviceConfiguration または VZUSBMassStorageDeviceConfiguration と組み合わせ可能です
  • VM から完全に透過的で、ストレージがリモートであることは VM から感知できません

10:02)ネットワーク接続が切断される可能性があるため、delegate で状態変化を監視できます:

let url = URL(string: "nbd://localhost:10809/myDisk")!
let attachment = try VZNetworkBlockDeviceStorageDeviceAttachment(url: url)

let delegate = NetworkBlockDeviceAttachmentDelegate()
attachment.delegate = delegate

let blockDevice = VZVirtioBlockDeviceConfiguration(attachment: attachment)

キーポイント:

  • delegate は VZNetworkBlockDeviceStorageDeviceAttachmentDelegate プロトコルに準拠します
  • 接続切断時は VM を一時停止するか再接続を試みます
  • 特殊イメージ形式や物理ドライブなど、カスタム I/O ロジックは NBD サーバー側で実装できます

NVMe コントローラーサポート

11:21)一部 Linux カーネルには virtio ドライバーがありませんが、通常 NVMe ドライバーはあります。Sonoma は NVMe コントローラーのエミュレーションを追加しました:

let nvmeDevice = VZNVMExpressControllerDeviceConfiguration(attachment: attachment)

キーポイント:

  • VZNVMExpressControllerDeviceConfiguration は新しいデバイスタイプです
  • Linux VM のみ。仮想 Mac は引き続き virtio block を推奨します
  • NBD アタッチメントもサポートします

Rosetta 2 キャッシュ最適化

13:46)Linux VM 内の Rosetta 2 に翻訳キャッシュデーモンが追加されました。通信チャネルを設定し、VM 内でデーモンを起動する必要があります:

// Rosetta 2 ランタイムとキャッシュデーモンの通信チャネルを設定
let rosettaConfiguration = VZRosettaDirectoryShare()
// VM 内でデーモン起動後、動的リンク要求はデーモンへ転送
// Rosetta 2 ランタイムはデーモンから事前翻訳済みバイナリを直接取得

キーポイント:

  • 翻訳結果はディスクにキャッシュされ、複数 App で共有されます
  • 同一ライブラリ/実行ファイルの再翻訳を回避します
  • コンパイル、パッケージインストールなど exec 集約タスクで最も効果が大きいです

重要ポイント

  1. スナップショット機能付き VM マネージャーを作る

    • saveMachineStateTorestoreMachineStateFrom で App 終了時に VM 状態を自動保存し、次回起動を瞬時に
    • 実装:applicationWillTerminate で保存 API を呼び、App ライフサイクルイベントを監視
  2. リモート開発環境を構築

    • NBD で VM ディスクを社内サーバーやクラウドホストに置き、ローカル Mac は計算のみ実行
    • 実装:NBD サーバーを構築し、VZNetworkBlockDeviceStorageDeviceAttachment でリモートディスクをマウント
  3. x86 Linux 互換テストツールを作る

    • Rosetta 2 キャッシュ最適化で Apple Silicon Mac 上で x86_64 Linux ビルド/テストを高速実行
    • 実装:Linux VM を作成、Rosetta 2 を有効化、共有フォルダでプロジェクトコードをマウント
  4. 解像度適応型の仮想デスクトップクライアント

    • automaticallyReconfiguresDisplay を有効化し、リモート仮想デスクトップが常にローカルウィンドウを埋める
    • 実装:VZVirtualMachineView 作成時に属性を設定し、コンテナビューのサイズ変化を監視

関連セッション

  • Create macOS or Linux virtual machines — WWDC22 の Virtualization framework 入門。本 Session の前に基礎を学ぶのに適しています
  • What’s new in Swift — 本 Session の API は Swift async/await を多用。最新 Swift 機能の理解が API 利用に役立ちます
  • Meet SwiftData — VM 管理 App で設定とスナップショットメタデータを永続化するなら SwiftData が理想です

コメント

GitHub Issues · utterances