{"$schema": "https://raw.githubusercontent.com/guitaripod/wwdc-sessions/master/schema/transcript.schema.json", "id": "wwdc2026-224", "language": "eng", "source": "https://developer.apple.com/videos/play/wwdc2026/224", "wordCount": 3051, "segments": [{"start": 6.0, "text": "Hello!"}, {"start": 7.0, "text": "I'm Ronnie Misra from the Virtualization team."}, {"start": 10.0, "text": "In this session, I'll explore how you can add advanced capabilities"}, {"start": 13.0, "text": "to your Virtualization app."}, {"start": 15.0, "text": "You can use the Virtualization framework"}, {"start": 17.0, "text": "to create apps that power full, desktop experiences"}, {"start": 20.0, "text": "or enable sophisticated developer workflows,"}, {"start": 23.0, "text": "like testing collaborative Mac apps, and networking between devices."}, {"start": 27.0, "text": "You can also build command line tools and automation"}, {"start": 30.0, "text": "to enable consistent testing in controlled environments."}, {"start": 34.0, "text": "Today, I'll take you through some new and existing APIs"}, {"start": 37.0, "text": "to make your Virtualization apps even more powerful."}, {"start": 40.0, "text": "I'll cover: automating the setup of Virtual Macs,"}, {"start": 43.0, "text": "and attaching USB devices to virtual machines"}, {"start": 46.0, "text": "with the Accessory Access framework."}, {"start": 49.0, "text": "I'll explore configuring advanced network topologies,"}, {"start": 52.0, "text": "and how to create high-performance,"}, {"start": 54.0, "text": "efficient disk images with the DiskImageKit framework."}, {"start": 58.0, "text": "Finally, I'll cover creating custom,"}, {"start": 60.0, "text": "high-performance virtual devices with Virtio."}, {"start": 63.0, "text": "First, I'll show you how Virtualization enables you"}, {"start": 66.0, "text": "to automate macOS guest provisioning."}, {"start": 69.0, "text": "After you install macOS into a virtual Mac,"}, {"start": 72.0, "text": "you can set it up exactly the same way as you would set up a physical Mac."}, {"start": 76.0, "text": "You use the same Setup Assistant you are already familiar with."}, {"start": 79.0, "text": "This gives you an easy way to create a user account"}, {"start": 81.0, "text": "and configure common settings."}, {"start": 84.0, "text": "For automation use cases, however,"}, {"start": 86.0, "text": "it would be convenient to be able to programmatically set up a virtual Mac."}, {"start": 90.0, "text": "The Virtualization framework now lets your app specify provisioning options"}, {"start": 94.0, "text": "when a virtual Mac is started."}, {"start": 96.0, "text": "You provide a full name, username, and password,"}, {"start": 99.0, "text": "and optionally enable auto-login or remote login via SSH."}, {"start": 104.0, "text": "When the guest boots for the first time,"}, {"start": 106.0, "text": "these parameters are automatically passed to Setup Assistant."}, {"start": 110.0, "text": "A user is created with the specified credentials,"}, {"start": 112.0, "text": "and auto-login and remote login are enabled if requested."}, {"start": 116.0, "text": "To use the macOS guest provisioning API,"}, {"start": 119.0, "text": "you first create a VZMacGuestProvisioningOptions object"}, {"start": 123.0, "text": "with your desired settings."}, {"start": 124.0, "text": "Here, I have created provisioningOptions that will create a user account,"}, {"start": 128.0, "text": "enable auto login, and also enable SSH."}, {"start": 132.0, "text": "You then construct a VZMacOSVirtualMachineStartOptions object"}, {"start": 136.0, "text": "and set its guest provisioning"}, {"start": 138.0, "text": "to the provisioningOptions you just constructed."}, {"start": 141.0, "text": "Finally, you start your virtual Mac using these startOptions."}, {"start": 145.0, "text": "When the guest boots,"}, {"start": 146.0, "text": "these provisioning options will be used to automate provisioning of the virtual Mac."}, {"start": 151.0, "text": "Now, I'll show you this in action."}, {"start": 153.0, "text": "I've modified the macOS virtual machine sample app"}, {"start": 156.0, "text": "to make use of the macOS guest provisioning API."}, {"start": 159.0, "text": "I have already installed macOS into a new virtual Mac,"}, {"start": 162.0, "text": "but I have not booted it yet."}, {"start": 164.0, "text": "I'll double-click the app to boot the virtual Mac for the first time."}, {"start": 173.0, "text": "The app prompts me for Provisioning Options."}, {"start": 176.0, "text": "Because I have previously run this app,"}, {"start": 178.0, "text": "it remembers my preferred provisioning options"}, {"start": 180.0, "text": "to create a user for Jane Appleseed"}, {"start": 182.0, "text": "and enable automatic login and remote login."}, {"start": 185.0, "text": "I'll now click OK to accept those settings."}, {"start": 191.0, "text": "My app has now started the virtual Mac with those provisioning options."}, {"start": 195.0, "text": "The Virtualization framework will pass those options into the guest,"}, {"start": 198.0, "text": "so I don't have to navigate through setup assistant manually."}, {"start": 201.0, "text": "Setup assistant automatically creates a new user."}, {"start": 205.0, "text": "Setup assistant has now created the new account."}, {"start": 208.0, "text": "Because my provisioning options indicated that automatic login should be enabled,"}, {"start": 212.0, "text": "the guest has logged into the account."}, {"start": 214.0, "text": "I'll now open a Finder window in my virtual Mac."}, {"start": 224.0, "text": "The sidebar shows the username jappleseed, which matches the username I provided."}, {"start": 229.0, "text": "Now, I'll open up System Settings"}, {"start": 231.0, "text": "and browse to the Remote Login sharing setting."}, {"start": 243.0, "text": "System Settings confirms that Remote Login has been enabled."}, {"start": 247.0, "text": "My virtual Mac is now ready to go!"}, {"start": 249.0, "text": "All I had to do was boot it."}, {"start": 251.0, "text": "Note that these settings are only honored if the guest has not already been set up."}, {"start": 256.0, "text": "If a user has already been created in the guest,"}, {"start": 258.0, "text": "provisioning options passed on subsequent boots will be ignored."}, {"start": 263.0, "text": "When using these APIs, be thoughtful about how you handle passwords,"}, {"start": 267.0, "text": "and consider the security implications for your app."}, {"start": 269.0, "text": "For example, instead of hardcoding a password in your code,"}, {"start": 273.0, "text": "you might want to read it from the Keychain,"}, {"start": 275.0, "text": "or a configuration file, or an environment variable."}, {"start": 279.0, "text": "Next, I'll talk about attaching USB accessories"}, {"start": 281.0, "text": "using Accessory Access."}, {"start": 285.0, "text": "Some virtual machine use cases require the ability"}, {"start": 287.0, "text": "to grant the guest access to a USB accessory connected to the host."}, {"start": 291.0, "text": "For example, someone may want to make use of a USB drive"}, {"start": 295.0, "text": "from inside of a virtual machine."}, {"start": 297.0, "text": "At the same time, people should remain in control of their devices."}, {"start": 301.0, "text": "Accessory Access is a new framework designed to support"}, {"start": 304.0, "text": "making USB devices available to macOS and Linux virtual machines."}, {"start": 308.0, "text": "A key principle of Accessory Access is that people should have explicit control"}, {"start": 312.0, "text": "of which devices are attached to which apps."}, {"start": 315.0, "text": "People have visibility into what apps are using their devices,"}, {"start": 318.0, "text": "and can attach and detach devices at any time."}, {"start": 321.0, "text": "Accessory Access supports device hot plugging."}, {"start": 324.0, "text": "When someone grants an app access to a device,"}, {"start": 326.0, "text": "it can be attached to the virtual machine at runtime"}, {"start": 329.0, "text": "without changing the VM's static configuration."}, {"start": 332.0, "text": "Before I dive into the details, here is Accessory Access in action."}, {"start": 336.0, "text": "I'm running the macOS virtual machine sample app I showed you before."}, {"start": 340.0, "text": "I'll now connect a USB drive to my Mac."}, {"start": 349.0, "text": "The icon for my drive has appeared on the desktop."}, {"start": 352.0, "text": "Also, because the virtual machine app is running"}, {"start": 354.0, "text": "and has indicated interest in storage devices,"}, {"start": 357.0, "text": "an accessory icon is now present in the menu bar."}, {"start": 360.0, "text": "I'll now select my disk in the accessory menu"}, {"start": 362.0, "text": "and attach it to my app."}, {"start": 367.0, "text": "Since I attached this drive to my virtual Mac,"}, {"start": 369.0, "text": "my host has unmounted the drive, and the guest has mounted it."}, {"start": 373.0, "text": "Now I'll safely eject the drive from inside the virtual Mac."}, {"start": 382.0, "text": "Then I'll use the accessory menu to release the drive back to my host."}, {"start": 391.0, "text": "Now that I have released the drive to my host,"}, {"start": 393.0, "text": "the host has remounted the drive."}, {"start": 395.0, "text": "This demonstrates how Accessory Access makes it easy to use your USB accessories"}, {"start": 399.0, "text": "from a virtual machine."}, {"start": 402.0, "text": "To use Accessory Access, your app registers a listener with matching criteria"}, {"start": 406.0, "text": "describing the types of devices it is interested in."}, {"start": 409.0, "text": "You can filter by device class and subclass,"}, {"start": 411.0, "text": "vendor ID and product ID,"}, {"start": 413.0, "text": "or other criteria."}, {"start": 416.0, "text": "When a matching device is connected to the Mac,"}, {"start": 418.0, "text": "the Accessory Access menu extra appears."}, {"start": 421.0, "text": "From here, someone can decide to attach the device to your app."}, {"start": 425.0, "text": "If the device is attached to your app,"}, {"start": 427.0, "text": "your app's listener object will be notified of the newly attached device."}, {"start": 432.0, "text": "To use Accessory Access,"}, {"start": 433.0, "text": "you start by creating an array of AAUSBAccessoryMatchingCriteria objects"}, {"start": 437.0, "text": "describing the types of devices you are interested in."}, {"start": 441.0, "text": "You can use an empty array to express interest in all USB devices."}, {"start": 445.0, "text": "Then use AAUSBAccessoryManager to register a listener."}, {"start": 449.0, "text": "This listener should implement the AAUSBAccessoryListener protocol."}, {"start": 454.0, "text": "registerListener will return any accessories"}, {"start": 456.0, "text": "that were previously attached to your application."}, {"start": 459.0, "text": "When someone attaches a device to your app,"}, {"start": 461.0, "text": "your listener's usbAccessoryDidConnect function will be called."}, {"start": 465.0, "text": "In this function, you can attach the device to your virtual machine."}, {"start": 469.0, "text": "VZVirtualMachine requires modifications to happen on its own queue."}, {"start": 473.0, "text": "On that queue, you can use the VZUSBPassthroughDeviceConfiguration class"}, {"start": 477.0, "text": "to create a VZUSBPassthroughDevice,"}, {"start": 480.0, "text": "and then attach this device to one of the virtualMachine's USB controllers."}, {"start": 486.0, "text": "In order for your app to use Accessory Access,"}, {"start": 488.0, "text": "add the Claim USB Accessory capability to your Xcode target's capabilities."}, {"start": 493.0, "text": "Remember that people can choose to attach"}, {"start": 495.0, "text": "or detach devices from your app at any time."}, {"start": 498.0, "text": "Your app should handle these events gracefully."}, {"start": 501.0, "text": "Consult the Accessory Access documentation for details on supported device types."}, {"start": 506.0, "text": "In macOS 26 and later, your app can use the vmnet framework"}, {"start": 510.0, "text": "to configure virtual network interfaces."}, {"start": 513.0, "text": "The Virtualization framework makes it easy to configure isolated virtual machines"}, {"start": 516.0, "text": "with basic NAT or bridge networking."}, {"start": 519.0, "text": "For more advanced use cases, however, you may want to have more control"}, {"start": 523.0, "text": "of how VMs interact with each other or with the external network."}, {"start": 527.0, "text": "For example, you may want to test connections to your server virtual machine"}, {"start": 531.0, "text": "from clients on either the same or a different network."}, {"start": 534.0, "text": "The vmnet framework allows you to create custom network topologies"}, {"start": 538.0, "text": "to support these advanced use cases."}, {"start": 541.0, "text": "Using the vmnet framework, you can create custom network topologies"}, {"start": 545.0, "text": "for your macOS and Linux VMs."}, {"start": 547.0, "text": "vmnet allows you to control how your VMs can communicate with each other."}, {"start": 551.0, "text": "vmnet also allows you to configure various parameters of those custom networks."}, {"start": 556.0, "text": "For example, you can configure the DHCP settings for the network,"}, {"start": 560.0, "text": "or add rules to forward TCP or UDP host ports"}, {"start": 563.0, "text": "to specific virtual machines."}, {"start": 566.0, "text": "To use vmnet with the Virtualization framework,"}, {"start": 569.0, "text": "you first create a vmnet network configuration object."}, {"start": 572.0, "text": "You use that configuration to construct a vmnet network object."}, {"start": 576.0, "text": "You can then use that network object to construct a network device attachment."}, {"start": 581.0, "text": "This network device attachment is then attached to a network device configuration,"}, {"start": 585.0, "text": "which is in turn added to a virtual machine configuration."}, {"start": 589.0, "text": "Finally, you use that virtual machine configuration"}, {"start": 592.0, "text": "to construct a virtual machine."}, {"start": 594.0, "text": "If you want a second virtual machine to use the same vmnet network,"}, {"start": 597.0, "text": "you follow the same steps to configure that second virtual machine,"}, {"start": 601.0, "text": "making sure to use the same vmnet network object."}, {"start": 604.0, "text": "Now I'll show you these steps in code."}, {"start": 607.0, "text": "You first create a vmnet configuration object"}, {"start": 610.0, "text": "using vmnet_network_configuration_create."}, {"start": 613.0, "text": "vmnet provides several functions to customize that network:"}, {"start": 616.0, "text": "for example, you can configure the network's DHCP settings,"}, {"start": 620.0, "text": "enable port forwarding, etc."}, {"start": 623.0, "text": "Once you have a network configuration object,"}, {"start": 625.0, "text": "you can use vmnet_network_create to construct a vmnet network object."}, {"start": 630.0, "text": "You then construct a VZVmnetNetworkDeviceAttachment"}, {"start": 634.0, "text": "to allow Virtualization to use the vmnet network you just created."}, {"start": 639.0, "text": "Next, set the attachment on a VZVirtioNetworkDeviceConfiguration object."}, {"start": 644.0, "text": "This networkDeviceConfiguration is added to the array of networkDevices"}, {"start": 648.0, "text": "on your VZVirtualMachineConfiguration object."}, {"start": 651.0, "text": "And finally, this configuration will be used to construct your VZVirtualMachine."}, {"start": 656.0, "text": "A vmnet network object is a reference counted Objective-C object."}, {"start": 660.0, "text": "The network goes away when the last reference is released."}, {"start": 664.0, "text": "This also implies that a vmnet network is not persisted when your app quits."}, {"start": 668.0, "text": "If you want to create a consistent network configuration,"}, {"start": 671.0, "text": "your app must persist your vmnet settings itself."}, {"start": 675.0, "text": "vmnet provides the vmnet_network_copy_serialization"}, {"start": 679.0, "text": "and vmnet_network_create_with_serialization APIs to allow you to transfer a vmnet network"}, {"start": 684.0, "text": "across an XPC connection from one process to another."}, {"start": 688.0, "text": "This is useful if you would like to run multiple VMs in separate processes"}, {"start": 692.0, "text": "but connect them to the same network."}, {"start": 695.0, "text": "Next, I'll show you how to use DiskImageKit to efficiently work with disk images."}, {"start": 700.0, "text": "The Virtualization framework supports using standard raw disk image files"}, {"start": 704.0, "text": "to back virtual machine disks."}, {"start": 706.0, "text": "This simple format maps disk blocks to file blocks one-to-one."}, {"start": 710.0, "text": "This simplicity means that the format is widely supported by existing software."}, {"start": 715.0, "text": "However, this simplicity comes with a cost."}, {"start": 718.0, "text": "Raw disk images cannot inherently represent sparsity"}, {"start": 721.0, "text": "for example, a 100 gigabyte disk is represented by a 100 gigabyte file."}, {"start": 727.0, "text": "This also makes snapshots expensive."}, {"start": 729.0, "text": "Snapshotting a VM's disk requires making a copy of the entire disk."}, {"start": 735.0, "text": "DiskImageKit is a new framework in macOS 27"}, {"start": 738.0, "text": "that is designed to make disk image management more efficient."}, {"start": 741.0, "text": "It supports the Apple Sparse Image Format or ASIF that was introduced in macOS 26."}, {"start": 747.0, "text": "DiskImageKit allows you to construct a stack of images,"}, {"start": 750.0, "text": "allowing writes to go into an overlay layer while leaving the base layer unmodified."}, {"start": 755.0, "text": "DiskImageKit also supports raw disk images."}, {"start": 759.0, "text": "When constructing a stacked image,"}, {"start": 761.0, "text": "DiskImageKit supports a few different types of layers."}, {"start": 764.0, "text": "The bottom layer of a stacked image is called the base layer."}, {"start": 767.0, "text": "This layer can be of any format that is supported by DiskImageKit."}, {"start": 771.0, "text": "Upper layers are always ASIF images."}, {"start": 773.0, "text": "These layers can be either cache or overlay layers."}, {"start": 777.0, "text": "A cache layer can be used to improve performance"}, {"start": 780.0, "text": "when underlying layers exist on slow storage"}, {"start": 783.0, "text": "like a remote network filesystem."}, {"start": 786.0, "text": "When processing a read request, if the cache layer cannot satisfy the read,"}, {"start": 790.0, "text": "DiskImageKit will satisfy the read from lower layers,"}, {"start": 793.0, "text": "but store a copy of the data in the cache layer."}, {"start": 795.0, "text": "Subsequent reads of the same data will then be read from the cache."}, {"start": 801.0, "text": "Overlay layers can be used to implement copy-on-write semantics for snapshots."}, {"start": 805.0, "text": "When writing to a layered image,"}, {"start": 807.0, "text": "if DiskImageKit encounters a writable overlay while traversing the stack,"}, {"start": 811.0, "text": "it will store the writes in that layer."}, {"start": 814.0, "text": "DiskImageKit allows read-only layers to be shared by multiple concurrent stacks."}, {"start": 819.0, "text": "This allows efficient reuse of shared content"}, {"start": 821.0, "text": "between multiple virtual machines"}, {"start": 823.0, "text": "while keeping their independent writes separate."}, {"start": 827.0, "text": "ASIF images are sparse."}, {"start": 829.0, "text": "This means that an ASIF image may logically represent more blocks"}, {"start": 832.0, "text": "than are actually stored in the image."}, {"start": 834.0, "text": "When reading from an ASIF file, blocks that are not stored in the image"}, {"start": 837.0, "text": "are treated as if they were zero-filled."}, {"start": 840.0, "text": "I'll walk through how DiskImageKit would process read and write requests"}, {"start": 843.0, "text": "for an example stack."}, {"start": 845.0, "text": "In this example, the base layer has content for blocks 0, 1 and 4."}, {"start": 850.0, "text": "The cache layer does not have content for any blocks."}, {"start": 853.0, "text": "The overlay layer has updated content for block 4,"}, {"start": 856.0, "text": "and also has content for block 5."}, {"start": 859.0, "text": "Note that a layer can have a different logical size"}, {"start": 861.0, "text": "than the layers above or below it."}, {"start": 864.0, "text": "To satisfy a read of block 0,"}, {"start": 866.0, "text": "DiskImageKit will traverse the layers of the stacked image"}, {"start": 869.0, "text": "until it finds a layer that contains the content for this block."}, {"start": 872.0, "text": "This read will be satisfied by the base layer."}, {"start": 875.0, "text": "Because there was a cache layer,"}, {"start": 877.0, "text": "DiskImageKit will cache the contents of this block"}, {"start": 879.0, "text": "and then return the contents to the caller."}, {"start": 882.0, "text": "Subsequent reads of this same block will be satisfied by the cache layer."}, {"start": 887.0, "text": "When writing block 2,"}, {"start": 888.0, "text": "DiskImageKit will discover that the top layer is an overlay"}, {"start": 891.0, "text": "and store the content there."}, {"start": 894.0, "text": "To use DiskImageKit images with Virtualization,"}, {"start": 897.0, "text": "you first start by creating a DiskImage object."}, {"start": 901.0, "text": "If you'd like to use a layered image,"}, {"start": 902.0, "text": "you create multiple DiskImage objects and then append them in order."}, {"start": 907.0, "text": "You can then construct a VZDiskImageStorageDeviceAttachment"}, {"start": 910.0, "text": "from your stackedImage."}, {"start": 912.0, "text": "This can then be attached to a storageDeviceConfiguration,"}, {"start": 915.0, "text": "for example a VZVirtioBlockDeviceConfiguration."}, {"start": 920.0, "text": "Add this storageDeviceConfiguration"}, {"start": 921.0, "text": "to your virtual machine configuration's storageDevices."}, {"start": 925.0, "text": "Finally, create your VZVirtualMachine using this configuration."}, {"start": 930.0, "text": "When using stacked images,"}, {"start": 931.0, "text": "it is worth noting that shallow stacks perform better."}, {"start": 934.0, "text": "There is a performance cost"}, {"start": 935.0, "text": "to increasing the depth of a disk image stack."}, {"start": 938.0, "text": "Keep in mind that a virtual machine is comprised of more than just disk images."}, {"start": 943.0, "text": "For example, a virtual Mac has an auxiliary storage file,"}, {"start": 946.0, "text": "and a VM using the EFI boot loader has an EFI variable store file."}, {"start": 951.0, "text": "If you want to clone a VM and use a shared base layer,"}, {"start": 954.0, "text": "remember that you must duplicate those other files."}, {"start": 957.0, "text": "Finally, I'll show you how the custom Virtio APIs"}, {"start": 960.0, "text": "allow you to build custom communication channels"}, {"start": 962.0, "text": "between your app and your Linux virtual machines."}, {"start": 966.0, "text": "Although the Virtualization framework already supports a wide range"}, {"start": 969.0, "text": "of standard device classes,"}, {"start": 971.0, "text": "some use cases may require something more specialized."}, {"start": 974.0, "text": "Perhaps you want to implement a custom protocol"}, {"start": 977.0, "text": "for performance-critical communication between host and guest."}, {"start": 980.0, "text": "Maybe you want to implement a coprocessor, such as a Virtio crypto device."}, {"start": 985.0, "text": "You might want to provide efficient guest access"}, {"start": 987.0, "text": "to machine learning accelerators."}, {"start": 989.0, "text": "That's where the custom Virtio device API comes in."}, {"start": 993.0, "text": "Virtio is an industry standard for paravirtualized devices."}, {"start": 997.0, "text": "It's the protocol used to implement many of the built in Virtualization devices."}, {"start": 1001.0, "text": "In macOS 27, the Virtualization framework"}, {"start": 1004.0, "text": "allows you to implement your own Virtio devices,"}, {"start": 1007.0, "text": "allowing custom communication between your host app and your Linux virtual machines."}, {"start": 1011.0, "text": "This is especially useful for performance-critical scenarios"}, {"start": 1014.0, "text": "where you need low-latency, high-throughput communication."}, {"start": 1018.0, "text": "The Virtio protocol makes use of memory buffers"}, {"start": 1021.0, "text": "shared between the guest and the host."}, {"start": 1023.0, "text": "These buffers are organized into Virtio queues."}, {"start": 1027.0, "text": "Virtio is designed to minimize the number of context switches"}, {"start": 1029.0, "text": "between the guest and the host."}, {"start": 1032.0, "text": "The device driver in the guest notifies the device running on the host"}, {"start": 1035.0, "text": "when data has been enqueued."}, {"start": 1037.0, "text": "Similarly, the host can use an interrupt"}, {"start": 1040.0, "text": "to inform the guest driver about enqueued data."}, {"start": 1044.0, "text": "In macOS 27, the VZCustomVirtioDevice class"}, {"start": 1047.0, "text": "can be used to implement your custom device."}, {"start": 1050.0, "text": "Your app sets a delegate on the device."}, {"start": 1052.0, "text": "This delegate will be notified when the guest enqueues data on its queue."}, {"start": 1056.0, "text": "You can also initiate activity in the guest by triggering an interrupt on the device."}, {"start": 1061.0, "text": "To use the custom Virtio device API,"}, {"start": 1064.0, "text": "you start by creating a VZCustomVirtioDeviceConfiguration object."}, {"start": 1068.0, "text": "You configure this object with your device's Virtio device identity,"}, {"start": 1072.0, "text": "its PCI class and subclass,"}, {"start": 1074.0, "text": "and the number of Virtio queues your device uses."}, {"start": 1078.0, "text": "You also set a provider on the configuration."}, {"start": 1081.0, "text": "VZCustomVirtioDeviceDelegateProvider is used to configure a delegate"}, {"start": 1085.0, "text": "that implements the VZCustomVirtioDevice- ConfigurationDelegate protocol."}, {"start": 1090.0, "text": "You then add this deviceConfiguration to your virtualMachineConfiguration's"}, {"start": 1094.0, "text": "customVirtioDevices array,"}, {"start": 1096.0, "text": "and create a VZVirtualMachine using that configuration."}, {"start": 1100.0, "text": "When the virtual machine is started,"}, {"start": 1102.0, "text": "a VZCustomVirtioDevice object is created,"}, {"start": 1105.0, "text": "and your configuration delegate's didCreateDevice function is called."}, {"start": 1109.0, "text": "In this function, you should set the device's delegate."}, {"start": 1112.0, "text": "This delegate should implement the VZCustomVirtioDeviceDelegate protocol."}, {"start": 1116.0, "text": "You can also hang onto the device itself"}, {"start": 1119.0, "text": "so that your device can trigger guest interrupts."}, {"start": 1122.0, "text": "There are several functions in the VZCustomVirtioDeviceDelegate protocol"}, {"start": 1126.0, "text": "that can be used to monitor the device's lifecycle"}, {"start": 1128.0, "text": "and interact with the device."}, {"start": 1131.0, "text": "The didReceiveNotificationFor function is where you implement logic"}, {"start": 1135.0, "text": "to dequeue elements from your device's queue,"}, {"start": 1137.0, "text": "process those elements, and then return them to the queue."}, {"start": 1141.0, "text": "Remember that custom devices require custom drivers"}, {"start": 1144.0, "text": "to allow the guest to use your device."}, {"start": 1147.0, "text": "Virtio queues are designed to provide efficient communication"}, {"start": 1150.0, "text": "between the guest and the host."}, {"start": 1152.0, "text": "Make sure to follow best practices when designing your guest driver"}, {"start": 1155.0, "text": "to make optimal use of Virtio queues."}, {"start": 1158.0, "text": "Before I wrap up,"}, {"start": 1160.0, "text": "I want to briefly mention some other advancements to Virtualization"}, {"start": 1163.0, "text": "that can really make your app shine."}, {"start": 1166.0, "text": "iCloud support is particularly valuable for desktop experiences,"}, {"start": 1170.0, "text": "allowing people to access their iCloud data and services in the VM."}, {"start": 1174.0, "text": "EFI Secure Boot hardens Linux VMs with modern security features."}, {"start": 1179.0, "text": "macOS guests can take advantage of Metal features like argument buffers"}, {"start": 1183.0, "text": "and indirect command buffers."}, {"start": 1186.0, "text": "You're now ready to add even more capabilities"}, {"start": 1188.0, "text": "to your Virtualization app."}, {"start": 1190.0, "text": "Automate the setup of macOS user accounts"}, {"start": 1192.0, "text": "by configuring them with provisioning options."}, {"start": 1195.0, "text": "Use the Accessory Access framework to attach USB devices to a VM."}, {"start": 1200.0, "text": "Customize networking for your VMs by building your own network topology"}, {"start": 1204.0, "text": "and configuring port forwarding."}, {"start": 1207.0, "text": "Use the DiskImageKit framework to create efficient, sparse disk images."}, {"start": 1211.0, "text": "And for custom, high-performance device needs in Linux guests,"}, {"start": 1214.0, "text": "consider creating custom devices with Virtio."}, {"start": 1218.0, "text": "Thanks for watching!"}, {"start": 1219.0, "text": "Have a great WWDC."}]}