What's New / Spatial, 3D & RealityKit

What's new in FoveatedStreaming

+8 NewvisionOS

FoveatedStreaming handles streaming sessions where detail is concentrated in a focus region and the rest of the frame is rendered at lower fidelity. The API covers streaming providers, session setup, and status reporting.

The 27 SDK adds 8 APIs and removes or deprecates none. New types include the struct FocusRegion, the protocol FoveatedStreamingProviderContext, and the enums FoveatedStreamingProviderEndpoint and StreamingProviderStatus. Other additions are FoveatedStreamingSession, the streamingProviderScene entry point, and an isMicrophoneEnabled flag.

New

8
struct

FocusRegion

NewvisionOS
public struct FocusRegion : Sendable, Equatable

Eye input data that describes where the end user is looking, relative to the device pose.

Declaration
public struct FocusRegion : Sendable, Equatable {

    /// The direction of the user's gaze in device-relative coordinates.
    public var direction: simd_float3

    /// The estimated distance to the user's focal point, in meters.
    public var distance: Float

    /// The timestamp at which this focus region sample was captured,
    /// measured as system uptime in seconds.
    public var timestamp: TimeInterval

    public init(direction: simd_float3, distance: Float, timestamp: TimeInterval)

    /// Returns a Boolean value indicating whether two values are equal.
    ///
    /// Equality is the inverse of inequality. For any values `a` and `b`,
    /// `a == b` implies that `a != b` is `false`.
    ///
    /// - Parameters:
    ///   - lhs: A value to compare.
    ///   - rhs: Another value to compare.
    public static func == (a: FocusRegion, b: FocusRegion) -> Bool
}
protocol

FoveatedStreamingProviderContext

NewvisionOS
public protocol FoveatedStreamingProviderContext : AnyObject, Observable
Declaration
public protocol FoveatedStreamingProviderContext : AnyObject, Observable {

    /// A token to be used for billing large buffer allocations to the host app.
    ///
    /// Use this token to ensure large allocations are billed to the calling app instead of your extension:
    /// - When you create an <doc://com.apple.documentation/documentation/iosurface/IOSurface>
    ///   in this process, use <doc://com.apple.documentation/documentation/iosurface/iosurfacesetownershipidentity(_:_:_:_:)>
    ///   with this token to attribute the memory.
    /// - When you create an <doc://com.apple.documentation/documentation/metal/mtlresource> in this process (such as an `MTLBuffer` or `MTLTexture`),
    ///   use <doc://com.apple.documentation/documentation/metal/mtlresource/setownerwithidentity:>
    ///   with this token to attribute the memory.
    ///
    /// - Warning: Failure to properly attribute large buffers can result in process termination.
    var taskIDToken: task_id_token_t { get }

    /// A convenience function that reports the current status of the foveated streaming provider.
    ///
    /// - If the status is `connecting`, then ``FoveatedStreamingProvider/init(context:)`` is in the middle of being called.
    /// - If the status is `connected`, then ``FoveatedStreamingProvider/init(context:)`` has completed its call without error.  The stream is assumed running.
    /// - If the status is `disconnecting`, then ``FoveatedStreamingProvider/disconnect()`` is in the middle of being called.
    /// - If the status is `disconnected`, then ``FoveatedStreamingProvider/disconnect()`` has completed its call without error.  The stream has been cleanly disconnected.
    /// - If the status is `interrupted`, then ``FoveatedStreamingProviderContext/reportConnectionInterrupted(_:)`` has been called.
    var status: StreamingProviderStatus { get }

    /// A convenience function that reports if microphone support is enabled for the process.
    var microphoneEnabled: Bool { get }

    /// The endpoint for which a connection is being requested (local IP or remote URL).
    var endpoint: FoveatedStreamingProviderEndpoint { get }

    /// The latest eye input data, to be used to enable foveated streaming.
    var latestFocusRegion: FocusRegion? { get set }

    /// Reports that a previously-established connection was unexpectedly lost.
    ///
    /// This may only be called while the provider is in the ``StreamingProviderStatus/connected``
    /// state. Calling this transitions the session to ``StreamingProviderStatus/error(_:)``.
    ///
    /// After calling this method, the provider should consider the session terminated.
    /// ``FoveatedStreamingProvider/disconnect()`` will **not** be called.
    func reportConnectionInterrupted(_ error: any Error)

    /// Notifies the host app that the list of available message channels has updated.
    func availableMessageChannelsDidUpdate(_ channelIds: Set<String>)

    /// Notifies the host app that a message channel received data.
    func messageChannelDidReceiveData(channelId: String, data: Data)

    /// Notifies the host app that a message channel has closed.
    func messageChannelDidClose(channelId: String)

    /// Attributes an IOSurface's memory to the host app instead of the extension.
    func registerForMemoryAttribution(_ surface: IOSurface)

    /// Attributes a Metal resource's memory to the host app instead of the extension.
    func registerForMemoryAttribution(_ resource: any MTLResource)
}
enum

FoveatedStreamingProviderEndpoint

NewvisionOS
public enum FoveatedStreamingProviderEndpoint : Codable, Sendable, Equatable

The streaming endpoint provided to a FoveatedStreamingProvider extension.

This describes where the extension should connect to stream content.

## Local Connections

For local (same-network) streaming, the endpoint contains:

  • The IP address of the streaming PC
  • Opaque barcode data scanned during QR pairing (contains credentials the extension uses to authenticate)
  • An optional expected certificate fingerprint attested by the session management protocol

## Remote Connections

For cloud/remote streaming, the endpoint contains:

  • The URL of the remote streaming server
  • HTTP headers for signaling authentication
Declaration
public enum FoveatedStreamingProviderEndpoint : Codable, Sendable, Equatable {

    /// Information obtained during QR code pairing for a local connection.
    public struct LocalPairingInformation : Codable, Sendable, Equatable {

        /// The raw barcode data as read from the scanned QR code.
        public var barcodeData: Data

        /// The barcode content decoded as a UTF-8 string, if representable.
        public var barcodeString: String?

        /// The SHA-256 fingerprint of the server's TLS certificate, as attested by
        /// the session management protocol during a previous successful pairing.
        ///
        /// The extension **must** verify the server's actual certificate matches this value, if non-`nil`.
        public var expectedCertificateFingerprint: Data?

        public init(barcodeData: Data, barcodeString: String? = nil, expectedCertificateFingerprint: Data? = nil)

        /// Returns a Boolean value indicating whether two values are equal.
        ///
        /// Equality is the inverse of inequality. For any values `a` and `b`,
        /// `a == b` implies that `a != b` is `false`.
        ///
        /// - Parameters:
        ///   - lhs: A value to compare.
        ///   - rhs: Another value to compare.
        public static func == (a: FoveatedStreamingProviderEndpoint.LocalPairingInformation, b: FoveatedStreamingProviderEndpoint.LocalPairingInformation) -> Bool

        /// Encodes this value into the given encoder.
        ///
        /// If the value fails to encode anything, `encoder` will encode an empty
        /// keyed container in its place.
        ///
        /// This function throws an error if any values are invalid for the given
        /// encoder's format.
        ///
        /// - Parameter encoder: The encoder to write data to.
        public func encode(to encoder: any Encoder) throws

        /// Creates a new instance by decoding from the given decoder.
        ///
        /// This initializer throws an error if reading from the decoder fails, or
        /// if the data read is corrupted or otherwise invalid.
        ///
        /// - Parameter decoder: The decoder to read data from.
        public init(from decoder: any Decoder) throws
    }

    /// A local streaming endpoint on the same network.
    ///
    /// - Parameters:
    ///   - ipAddress: The IP address of the streaming PC.
    ///   - barcode: Opaque credential data obtained during QR code pairing.
    ///     The extension is responsible for decoding this (e.g., extracting client tokens for CloudXR).
    ///   - expectedCertificateFingerprint: The SHA-256 fingerprint of the server's TLS certificate,
    ///     as attested by the session management protocol during a previous successful pairing.
    ///     The extension **must** verify the server's actual certificate matches this value.
    ///     `nil` for first-time connections where no stored credentials exist.
    case local(ipAddress: any IPAddress, pairingInformation: FoveatedStreamingProviderEndpoint.LocalPairingInformation)
}
extension

FoveatedStreamingProviderEndpoint

NewvisionOS
extension FoveatedStreamingProviderEndpoint
Declaration
extension FoveatedStreamingProviderEndpoint {

    /// Encodes this value into the given encoder.
    ///
    /// If the value fails to encode anything, `encoder` will encode an empty
    /// keyed container in its place.
    ///
    /// This function throws an error if any values are invalid for the given
    /// encoder's format.
    ///
    /// - Parameter encoder: The encoder to write data to.
    public func encode(to encoder: any Encoder) throws

    /// Creates a new instance by decoding from the given decoder.
    ///
    /// This initializer throws an error if reading from the decoder fails, or
    /// if the data read is corrupted or otherwise invalid.
    ///
    /// - Parameter decoder: The decoder to read data from.
    public init(from decoder: any Decoder) throws

    /// Returns a Boolean value indicating whether two values are equal.
    ///
    /// Equality is the inverse of inequality. For any values `a` and `b`,
    /// `a == b` implies that `a != b` is `false`.
    ///
    /// - Parameters:
    ///   - lhs: A value to compare.
    ///   - rhs: Another value to compare.
    public static func == (lhs: FoveatedStreamingProviderEndpoint, rhs: FoveatedStreamingProviderEndpoint) -> Bool
}
extension

FoveatedStreamingSession

NewvisionOS
extension FoveatedStreamingSession
Declaration
extension FoveatedStreamingSession {

    /// Represents a streaming provider extension that can be used for cloud streaming.
    ///
    /// `StreamingProvider` is a transportable value type carrying only the identifying
    /// information an app needs to render a picker and request a connection. The
    /// underlying `AppExtensionIdentity` lives only in `StreamReceiverDisplay`, since the
    /// extension point is host-gated and cannot be enumerated by third-party processes.
    public struct StreamingProvider : Hashable, Equatable, Sendable, Codable {

        /// The bundle identifier of the extension.
        ///
        /// This bundle identifier will be sent to endpoints during initial TCP handshake.
        public let bundleIdentifier: String

        /// The localized, human-readable display name of the provider.
        public let localizedName: String

        /// Returns a Boolean value indicating whether two values are equal.
        ///
        /// Equality is the inverse of inequality. For any values `a` and `b`,
        /// `a == b` implies that `a != b` is `false`.
        ///
        /// - Parameters:
        ///   - lhs: A value to compare.
        ///   - rhs: Another value to compare.
        public static func == (a: FoveatedStreamingSession.StreamingProvider, b: FoveatedStreamingSession.StreamingProvider) -> Bool

        /// Encodes this value into the given encoder.
        ///
        /// If the value fails to encode anything, `encoder` will encode an empty
        /// keyed container in its place.
        ///
        /// This function throws an error if any values are invalid for the given
        /// encoder's format.
        ///
        /// - Parameter encoder: The encoder to write data to.
        public func encode(to encoder: any Encoder) throws

        /// Hashes the essential components of this value by feeding them into the
        /// given hasher.
        ///
        /// Implement this method to conform to the `Hashable` protocol. The
        /// components used for hashing must be the same as the components compared
        /// in your type's `==` operator implementation. Call `hasher.combine(_:)`
        /// with each of these components.
        ///
        /// - Important: In your implementation of `hash(into:)`,
        ///   don't call `finalize()` on the `hasher` instance provided,
        ///   or replace it with a different instance.
        ///   Doing so may become a compile-time error in the future.
        ///
        /// - Parameter hasher: The hasher to use when combining the components
        ///   of this instance.
        public func hash(into hasher: inout Hasher)

        /// The hash value.
        ///
        /// Hash values are not guaranteed to be equal across different executions of
        /// your program. Do not save hash values to use during a future execution.
        ///
        /// - Important: `hashValue` is deprecated as a `Hashable` requirement. To
        ///   conform to `Hashable`, implement the `hash(into:)` requirement instead.
        ///   The compiler provides an implementation for `hashValue` for you.
        public var hashValue: Int { get }

        /// Creates a new instance by decoding from the given decoder.
        ///
        /// This initializer throws an error if reading from the decoder fails, or
        /// if the data read is corrupted or otherwise invalid.
        ///
        /// - Parameter decoder: The decoder to read data from.
        public init(from decoder: any Decoder) throws
    }

    /// Returns a list of currently-available streaming providers.
    ///
    /// Discovery is performed by `StreamReceiverDisplay`, the only process holding the
    /// `com.apple.private.foveated-streaming-provider-host` entitlement required to
    /// enumerate the streaming-provider extension point. The returned set is filtered to

Truncated.

var

isMicrophoneEnabled

NewvisionOS
final public var isMicrophoneEnabled: Bool

Whether the microphone is currently enabled for this session.

Set this to true to unmute or false to mute while the session is .connected. If the daemon rejects the call (e.g. session not connected or missing TCC authorization), the value remains unchanged and an error is logged.

func

streamingProviderScene

NewvisionOS
public func streamingProviderScene<Provider>(providerType: Provider.Type) -> some AppExtensionScene where Provider : FoveatedStreamingProvider

Creates a complete AppExtensionScene for a streaming provider extension.

This function handles all XPC setup automatically, allowing extension authors to create a fully functional extension with minimal boilerplate.

## Example Usage

@main
struct MyProviderExtension: AppExtension {
    var body: some AppExtensionScene {
        streamingProviderScene(providerType: MyProvider.self)
    }
}

Parameters

providerType
The type of your FoveatedStreamingProvider implementation

ReturnsA configured AppExtensionScene ready to use

enum

StreamingProviderStatus

NewvisionOS
public enum StreamingProviderStatus : Codable, Hashable, Equatable, Sendable, CustomStringConvertible

An enum describing the state of a FoveatedStreamingProvider.

Declaration
public enum StreamingProviderStatus : Codable, Hashable, Equatable, Sendable, CustomStringConvertible {

    /// Connected and streaming.
    case connected

    /// ``FoveatedStreamingProvider/init(context:)`` is in progress.
    case connecting

    /// ``FoveatedStreamingProvider/disconnect()`` has been called.
    case disconnecting

    /// The session has been disconnected for the provided reason.
    ///
    /// If `error` is `nil`, then the disconnect event was requested by calling
    /// ``FoveatedStreamingProvider/disconnect()``.
    ///
    /// If `error` is non-`nil`, then the disconnect event was due to an unexpected error.
    case disconnected(error: String?)

    /// A textual representation of this instance.
    ///
    /// Calling this property directly is discouraged. Instead, convert an
    /// instance of any type to a string by using the `String(describing:)`
    /// initializer. This initializer works with any type, and uses the custom
    /// `description` property for types that conform to
    /// `CustomStringConvertible`:
    ///
    ///     struct Point: CustomStringConvertible {
    ///         let x: Int, y: Int
    ///
    ///         var description: String {
    ///             return "(\(x), \(y))"
    ///         }
    ///     }
    ///
    ///     let p = Point(x: 21, y: 30)
    ///     let s = String(describing: p)
    ///     print(s)
    ///     // Prints "(21, 30)"
    ///
    /// The conversion of `p` to a string in the assignment to `s` uses the
    /// `Point` type's `description` property.
    public var description: String { get }

    /// Returns a Boolean value indicating whether two values are equal.
    ///
    /// Equality is the inverse of inequality. For any values `a` and `b`,
    /// `a == b` implies that `a != b` is `false`.
    ///
    /// - Parameters:
    ///   - lhs: A value to compare.
    ///   - rhs: Another value to compare.
    public static func == (a: StreamingProviderStatus, b: StreamingProviderStatus) -> Bool

    /// Encodes this value into the given encoder.
    ///
    /// If the value fails to encode anything, `encoder` will encode an empty
    /// keyed container in its place.
    ///
    /// This function throws an error if any values are invalid for the given
    /// encoder's format.
    ///
    /// - Parameter encoder: The encoder to write data to.
    public func encode(to encoder: any Encoder) throws

    /// Hashes the essential components of this value by feeding them into the
    /// given hasher.
    ///
    /// Implement this method to conform to the `Hashable` protocol. The
    /// components used for hashing must be the same as the components compared
    /// in your type's `==` operator implementation. Call `hasher.combine(_:)`
    /// with each of these components.
    ///
    /// - Important: In your implementation of `hash(into:)`,
    ///   don't call `finalize()` on the `hasher` instance provided,
    ///   or replace it with a different instance.
    ///   Doing so may become a compile-time error in the future.
    ///
    /// - Parameter hasher: The hasher to use when combining the components
    ///   of this instance.

Truncated.

No APIs match your filter.

← More in Spatial, 3D & RealityKit