-
Étendez les capacités de votre app de virtualisation
Intégrez les nouvelles capacités puissantes de macOS 27 à votre app de virtualisation. Découvrez comment automatiser la configuration des invités macOS en configurant le compte utilisateur lors du premier démarrage. Nous explorons des processus avancés impliquant le passthrough d'accessoires USB aux machines virtuelles, ainsi que des topologies réseau personnalisées et la redirection de ports. Vous découvrez également les améliorations récentes qui peuvent enrichir l'expérience d'utilisation des machines virtuelles de votre app.
Chapitres
- 0:01 - Introduction
- 1:04 - Approvisionnement des invités macOS
- 4:34 - Accessory Access
- 8:26 - Topologies réseau avancées
- 11:35 - DiskImageKit
- 15:57 - Virtio personnalisé
Ressources
Vidéos connexes
WWDC26
-
Rechercher dans cette vidéo…
-
-
1:57 - Provision a macOS guest
import Virtualization let provisioningOptions = VZMacGuestProvisioningOptions() provisioningOptions.fullName = fullName provisioningOptions.username = username provisioningOptions.password = password provisioningOptions.logsInAutomatically = true provisioningOptions.enablesRemoteLogin = true let startOptions = VZMacOSVirtualMachineStartOptions() try startOptions.setGuestProvisioning(provisioningOptions) try await virtualMachine.start(options: startOptions) -
7:12 - Register an Accessory Access listener
import AccessoryAccess let criteria: [AAUSBAccessoryMatchingCriteria] = [] let accessories = try await AAUSBAccessoryManager.shared.registerListener(self, matchingCriteria: criteria) for accessory in accessories { // Handle previously attached accessories. } -
7:39 - Respond to USB accessory connection
import AccessoryAccess import Virtualization class AccessoryListener: NSObject, AAUSBAccessoryListener { func usbAccessoryDidConnect(_ usbAccessory: AAUSBAccessory) { virtualMachine.queue.async { do { let configuration = VZUSBPassthroughDeviceConfiguration(device: usbAccessory) let device = try VZUSBPassthroughDevice(configuration: configuration) self.virtualMachine.usbControllers.first?.attach(device: device) { error in // Handle error if necessary... } } catch { // Handle error... } } } } -
10:04 - Create a custom vmnet network
import Virtualization import vmnet var status: vmnet_return_t = .VMNET_FAILURE guard let networkConfiguration = vmnet_network_configuration_create(.VMNET_SHARED_MODE, &status) else { ... } guard let network = vmnet_network_create(networkConfiguration, &status) else { ... } let attachment = VZVmnetNetworkDeviceAttachment(network: network) let networkDeviceConfiguration = VZVirtioNetworkDeviceConfiguration() networkDeviceConfiguration.attachment = attachment virtualMachineConfiguration.networkDevices = [networkDeviceConfiguration] let virtualMachine = VZVirtualMachine(configuration: virtualMachineConfiguration) -
14:54 - Use DiskImageKit with Virtualization
import DiskImageKit import Virtualization let baseImage = try DiskImage(opening: .open(url: baseLayerURL, mode: .readOnly)) let cacheImage = try baseImage.appending(.asifLayer(url: cacheLayerURL, type: .cache)) let overlayImage = try DiskImage(opening: .open(url: overlayLayerURL)) let stackedImage = try cacheImage.appending(overlayImage) let storageDeviceAttachment = try VZDiskImageStorageDeviceAttachment(diskImage: stackedImage) let storageDeviceConfiguration = VZVirtioBlockDeviceConfiguration(attachment: storageDeviceAttachment) virtualMachineConfiguration.storageDevices = [storageDeviceConfiguration] let virtualMachine = VZVirtualMachine(configuration: virtualMachineConfiguration) -
17:41 - Configure a custom Virtio device
import Virtualization let deviceConfiguration = VZCustomVirtioDeviceConfiguration() // Virtio entropy device. deviceConfiguration.deviceID = 4 // PCI class for crypto devices. deviceConfiguration.pciClassID = 0x10 // PCI subclass for network and computing encryption controllers. deviceConfiguration.pciSubclassID = 0x00 // An entropy device uses a single Virtio queue. deviceConfiguration.virtioQueueCount = 1 deviceConfiguration.provider = VZCustomVirtioDeviceDelegateProvider(deviceQueue: deviceQueue, delegate: provider) virtualMachineConfiguration.customVirtioDevices = [deviceConfiguration] let virtualMachine = VZVirtualMachine(configuration: virtualMachineConfiguration) -
18:20 - Attach a delegate to a VZCustomVirtioDevice
import Virtualization class DeviceConfigurationDelegate: NSObject, VZCustomVirtioDeviceConfigurationDelegate { func customVirtioConfiguration(_ deviceConfiguration: VZCustomVirtioDeviceConfiguration, didCreateDevice device: VZCustomVirtioDevice) { device.delegate = deviceDelegate self.device = device } } -
18:42 - Process Virtio queue elements
import Virtualization class DeviceDelegate: NSObject, VZCustomVirtioDeviceDelegate { func customVirtioDevice(_ device: VZCustomVirtioDevice, didReceiveNotificationFor queue: VZVirtioQueue) { while let element = queue.nextElement() { // Process element... element.returnToQueue() } } }
-