diff --git a/src/ARKit/ARAnchor_C.cs b/src/ARKit/ARAnchor_C.cs
new file mode 100644
index 000000000000..1c2427edf197
--- /dev/null
+++ b/src/ARKit/ARAnchor_C.cs
@@ -0,0 +1,87 @@
+//
+// ARAnchor.cs: Bindings for the ARKit C API anchor types
+//
+// Copyright 2025 Microsoft Corp
+//
+
+#if __MACOS__
+#nullable enable
+
+using System;
+using System.Runtime.InteropServices;
+using CoreFoundation;
+using ObjCRuntime;
+
+using Matrix4 = global::CoreGraphics.NMatrix4;
+
+namespace ARKit {
+
+ /// Represents an ARKit anchor in the C API.
+ [SupportedOSPlatform ("macos26.0")]
+ public class ARAnchor : ARObject {
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern /* simd_float4x4 */ SimdFloat4x4 ar_anchor_get_origin_from_anchor_transform (IntPtr anchor);
+
+ [DllImport (Constants.ARKitLibrary)]
+ unsafe static extern void ar_anchor_get_identifier (IntPtr anchor, byte* out_identifier);
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern double ar_anchor_get_timestamp (IntPtr anchor);
+
+ [Preserve (Conditional = true)]
+ internal ARAnchor (NativeHandle handle, bool owns)
+ : base (handle, owns)
+ {
+ }
+
+ /// Gets the transform from this anchor to the origin coordinate system.
+ public Matrix4 OriginFromAnchorTransform {
+ get {
+ var simd = ar_anchor_get_origin_from_anchor_transform (GetCheckedHandle ());
+ return simd.ToNMatrix4 ();
+ }
+ }
+
+ /// Gets the unique identifier of this anchor.
+ public Guid Identifier {
+ get {
+ unsafe {
+ byte* uuid = stackalloc byte [16];
+ ar_anchor_get_identifier (GetCheckedHandle (), uuid);
+ return new Guid (new ReadOnlySpan (uuid, 16));
+ }
+ }
+ }
+
+ /// Gets the timestamp associated with this anchor.
+ public double Timestamp {
+ get {
+ return ar_anchor_get_timestamp (GetCheckedHandle ());
+ }
+ }
+ }
+
+ /// Represents a trackable ARKit anchor that can report whether it is currently tracked.
+ [SupportedOSPlatform ("macos26.0")]
+ public class ARTrackableAnchor : ARAnchor {
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern byte ar_trackable_anchor_is_tracked (IntPtr anchor);
+
+ [Preserve (Conditional = true)]
+ internal ARTrackableAnchor (NativeHandle handle, bool owns)
+ : base (handle, owns)
+ {
+ }
+
+ /// Gets a value indicating whether this anchor is currently tracked.
+ public bool IsTracked {
+ get {
+ return ar_trackable_anchor_is_tracked (GetCheckedHandle ()) != 0;
+ }
+ }
+ }
+}
+
+#endif // __MACOS__
diff --git a/src/ARKit/ARAuthorizationResult.cs b/src/ARKit/ARAuthorizationResult.cs
new file mode 100644
index 000000000000..bc4e30118bf9
--- /dev/null
+++ b/src/ARKit/ARAuthorizationResult.cs
@@ -0,0 +1,102 @@
+//
+// ARAuthorizationResult.cs: Bindings for the ARKit C API authorization types
+//
+// Copyright 2025 Microsoft Corp
+//
+
+#if __MACOS__
+#nullable enable
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using CoreFoundation;
+using ObjCRuntime;
+
+namespace ARKit {
+
+ /// Represents a single authorization result from the ARKit C API.
+ [SupportedOSPlatform ("macos26.0")]
+ public class ARAuthorizationResult : ARObject {
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern /* ar_authorization_type_t */ nuint ar_authorization_result_get_authorization_type (IntPtr authorization_result);
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern /* ar_authorization_status_t */ nint ar_authorization_result_get_status (IntPtr authorization_result);
+
+ [Preserve (Conditional = true)]
+ internal ARAuthorizationResult (NativeHandle handle, bool owns)
+ : base (handle, owns)
+ {
+ }
+
+ /// Gets the authorization type associated with this result.
+ public ARAuthorizationType AuthorizationType {
+ get {
+ return (ARAuthorizationType) (ulong) ar_authorization_result_get_authorization_type (GetCheckedHandle ());
+ }
+ }
+
+ /// Gets the authorization status associated with this result.
+ public ARAuthorizationStatus Status {
+ get {
+ return (ARAuthorizationStatus) (long) ar_authorization_result_get_status (GetCheckedHandle ());
+ }
+ }
+ }
+
+ /// Represents a collection of authorization results from the ARKit C API.
+ [SupportedOSPlatform ("macos26.0")]
+ public class ARAuthorizationResults : ARObject {
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern /* size_t */ nuint ar_authorization_results_get_count (IntPtr authorization_results);
+
+ [DllImport (Constants.ARKitLibrary)]
+ unsafe static extern void ar_authorization_results_enumerate_results_f (
+ IntPtr authorization_results,
+ void* context,
+ delegate* unmanaged enumerator);
+
+ [Preserve (Conditional = true)]
+ internal ARAuthorizationResults (NativeHandle handle, bool owns)
+ : base (handle, owns)
+ {
+ }
+
+ /// Gets the number of authorization results in this collection.
+ public nuint Count {
+ get {
+ return ar_authorization_results_get_count (GetCheckedHandle ());
+ }
+ }
+
+ /// Returns all authorization results in this collection as an array.
+ public ARAuthorizationResult [] GetResults ()
+ {
+ var results = new List ();
+ unsafe {
+ delegate* unmanaged callback = &EnumerateCallback;
+ var handle = GCHandle.Alloc (results);
+ try {
+ ar_authorization_results_enumerate_results_f (GetCheckedHandle (), (void*) GCHandle.ToIntPtr (handle), callback);
+ } finally {
+ handle.Free ();
+ }
+ }
+ return results.ToArray ();
+ }
+
+ [UnmanagedCallersOnly]
+ unsafe static byte EnumerateCallback (void* context, IntPtr authorization_result)
+ {
+ var handle = GCHandle.FromIntPtr ((IntPtr) context);
+ var results = (List) handle.Target!;
+ results.Add (new ARAuthorizationResult (authorization_result, owns: false));
+ return 1; // continue
+ }
+ }
+}
+
+#endif // __MACOS__
diff --git a/src/ARKit/ARDataProvider.cs b/src/ARKit/ARDataProvider.cs
new file mode 100644
index 000000000000..b2bde9b81efd
--- /dev/null
+++ b/src/ARKit/ARDataProvider.cs
@@ -0,0 +1,159 @@
+//
+// ARDataProvider.cs: Bindings for the ARKit C API data provider types
+//
+// Copyright 2025 Microsoft Corp
+//
+
+#if __MACOS__
+#nullable enable
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using CoreFoundation;
+using ObjCRuntime;
+
+namespace ARKit {
+
+ /// Represents an ARKit data provider.
+ [SupportedOSPlatform ("macos26.0")]
+ public class ARDataProvider : ARObject {
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern /* ar_data_provider_state_t */ nint ar_data_provider_get_state (IntPtr data_provider);
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern /* ar_authorization_type_t */ nuint ar_data_provider_get_required_authorization_type (IntPtr data_provider);
+
+ [Preserve (Conditional = true)]
+ internal ARDataProvider (NativeHandle handle, bool owns)
+ : base (handle, owns)
+ {
+ }
+
+ /// Gets the current state of this data provider.
+ public ARDataProviderState State {
+ get {
+ return (ARDataProviderState) (long) ar_data_provider_get_state (GetCheckedHandle ());
+ }
+ }
+
+ /// Gets the authorization type required by this data provider.
+ public ARAuthorizationType RequiredAuthorizationType {
+ get {
+ return (ARAuthorizationType) (ulong) ar_data_provider_get_required_authorization_type (GetCheckedHandle ());
+ }
+ }
+ }
+
+ /// Represents a mutable collection of ARKit data providers.
+ [SupportedOSPlatform ("macos26.0")]
+ public class ARDataProviders : ARObject {
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern /* ar_data_providers_t */ IntPtr ar_data_providers_create ();
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern void ar_data_providers_add_data_provider (IntPtr data_providers, IntPtr data_provider_to_add);
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern void ar_data_providers_add_data_providers (IntPtr data_providers, IntPtr data_providers_to_add);
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern void ar_data_providers_remove_data_provider (IntPtr data_providers, IntPtr data_provider_to_remove);
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern void ar_data_providers_remove_data_providers (IntPtr data_providers, IntPtr data_providers_to_remove);
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern /* size_t */ nuint ar_data_providers_get_count (IntPtr data_providers);
+
+ [DllImport (Constants.ARKitLibrary)]
+ unsafe static extern void ar_data_providers_enumerate_data_providers_f (
+ IntPtr data_providers,
+ void* context,
+ delegate* unmanaged enumerator);
+
+ [Preserve (Conditional = true)]
+ internal ARDataProviders (NativeHandle handle, bool owns)
+ : base (handle, owns)
+ {
+ }
+
+ /// Creates a new empty collection of data providers.
+ public ARDataProviders ()
+ : base (ar_data_providers_create (), owns: true)
+ {
+ }
+
+ /// Gets the number of data providers in this collection.
+ public nuint Count {
+ get {
+ return ar_data_providers_get_count (GetCheckedHandle ());
+ }
+ }
+
+ /// Adds a data provider to this collection.
+ public void Add (ARDataProvider dataProvider)
+ {
+ if (dataProvider is null)
+ ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (dataProvider));
+ ar_data_providers_add_data_provider (GetCheckedHandle (), dataProvider.GetCheckedHandle ());
+ GC.KeepAlive (dataProvider);
+ }
+
+ /// Adds all data providers from another collection to this collection.
+ public void Add (ARDataProviders dataProviders)
+ {
+ if (dataProviders is null)
+ ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (dataProviders));
+ ar_data_providers_add_data_providers (GetCheckedHandle (), dataProviders.GetCheckedHandle ());
+ GC.KeepAlive (dataProviders);
+ }
+
+ /// Removes a data provider from this collection.
+ public void Remove (ARDataProvider dataProvider)
+ {
+ if (dataProvider is null)
+ ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (dataProvider));
+ ar_data_providers_remove_data_provider (GetCheckedHandle (), dataProvider.GetCheckedHandle ());
+ GC.KeepAlive (dataProvider);
+ }
+
+ /// Removes all data providers from another collection from this collection.
+ public void Remove (ARDataProviders dataProviders)
+ {
+ if (dataProviders is null)
+ ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (dataProviders));
+ ar_data_providers_remove_data_providers (GetCheckedHandle (), dataProviders.GetCheckedHandle ());
+ GC.KeepAlive (dataProviders);
+ }
+
+ /// Returns all data providers in this collection as an array.
+ public ARDataProvider [] GetDataProviders ()
+ {
+ var results = new List ();
+ unsafe {
+ delegate* unmanaged callback = &EnumerateCallback;
+ var handle = GCHandle.Alloc (results);
+ try {
+ ar_data_providers_enumerate_data_providers_f (GetCheckedHandle (), (void*) GCHandle.ToIntPtr (handle), callback);
+ } finally {
+ handle.Free ();
+ }
+ }
+ return results.ToArray ();
+ }
+
+ [UnmanagedCallersOnly]
+ unsafe static byte EnumerateCallback (void* context, IntPtr data_provider)
+ {
+ var handle = GCHandle.FromIntPtr ((IntPtr) context);
+ var results = (List) handle.Target!;
+ results.Add (new ARDataProvider (data_provider, owns: false));
+ return 1; // continue
+ }
+ }
+}
+
+#endif // __MACOS__
diff --git a/src/ARKit/AREnums.cs b/src/ARKit/AREnums.cs
new file mode 100644
index 000000000000..2a0ab11d4cf4
--- /dev/null
+++ b/src/ARKit/AREnums.cs
@@ -0,0 +1,101 @@
+//
+// AREnums.cs: Enums for the ARKit C API
+//
+// Copyright 2025 Microsoft Corp
+//
+
+#if __MACOS__
+#nullable enable
+
+using System;
+using ObjCRuntime;
+
+namespace ARKit {
+
+ /// Status of an authorization for ARKit data.
+ [SupportedOSPlatform ("macos26.0")]
+ [NativeName ("ar_authorization_status_t")]
+ public enum ARAuthorizationStatus : long {
+ /// The user has not yet granted permission.
+ NotDetermined = 0,
+ /// The user has explicitly granted permission.
+ Allowed = 1,
+ /// The user has explicitly denied permission.
+ Denied = 2,
+ }
+
+ /// Types of authorization for ARKit data.
+ [Flags]
+ [SupportedOSPlatform ("macos26.0")]
+ [NativeName ("ar_authorization_type_t")]
+ public enum ARAuthorizationType : ulong {
+ /// No authorization type.
+ None = 0,
+ /// Authorization type used when requesting hand tracking.
+ HandTracking = (1 << 0),
+ /// Authorization type used when requesting world sensing (image tracking, plane detection, scene reconstruction).
+ WorldSensing = (1 << 1),
+ /// Authorization type used when requesting camera access.
+ CameraAccess = (1 << 3),
+ }
+
+ /// State of an ARKit data provider.
+ [SupportedOSPlatform ("macos26.0")]
+ [NativeName ("ar_data_provider_state_t")]
+ public enum ARDataProviderState : long {
+ /// The data provider is initialized but not yet running.
+ Initialized = 0,
+ /// The data provider is running.
+ Running = 1,
+ /// The data provider is paused.
+ Paused = 2,
+ /// The data provider has stopped.
+ Stopped = 3,
+ }
+
+ /// Status of a device anchor query.
+ [SupportedOSPlatform ("macos26.0")]
+ [NativeName ("ar_device_anchor_query_status_t")]
+ public enum ARDeviceAnchorQueryStatus : long {
+ /// The device anchor at the specified timestamp was successfully obtained.
+ Success = 0,
+ /// The device anchor at the specified timestamp failed to be obtained.
+ Failure = 1,
+ }
+
+ /// Tracking states of a device anchor.
+ [SupportedOSPlatform ("macos26.0")]
+ [NativeName ("ar_device_anchor_tracking_state_t")]
+ public enum ARDeviceAnchorTrackingState : long {
+ /// The anchor is not tracked.
+ Untracked = 0,
+ /// Only orientation is currently tracked.
+ OrientationTracked = 1,
+ /// Both position and orientation are currently tracked.
+ Tracked = 2,
+ }
+
+ /// Error codes for ARKit session operations.
+ [SupportedOSPlatform ("macos26.0")]
+ [NativeName ("ar_session_error_code_t")]
+ public enum ARSessionErrorCode : long {
+ /// A data provider requires an authorization that has not been granted by the user.
+ DataProviderNotAuthorized = 100,
+ /// A data provider has failed to run.
+ DataProviderFailedToRun = 101,
+ }
+
+ /// Error codes for ARKit world tracking operations.
+ [SupportedOSPlatform ("macos26.0")]
+ [NativeName ("ar_world_tracking_error_code_t")]
+ public enum ARWorldTrackingErrorCode : long {
+ /// A world anchor failed to be added.
+ AddAnchorFailed = 200,
+ /// The maximum number of world anchors has been reached.
+ AnchorMaxLimitReached = 201,
+ /// A world anchor failed to be removed.
+ RemoveAnchorFailed = 202,
+ }
+}
+
+#endif // __MACOS__
diff --git a/src/ARKit/ARError_C.cs b/src/ARKit/ARError_C.cs
new file mode 100644
index 000000000000..fe2fc41014cf
--- /dev/null
+++ b/src/ARKit/ARError_C.cs
@@ -0,0 +1,60 @@
+//
+// ARError.cs: Bindings for the ARKit C API ar_error_t
+//
+// Copyright 2025 Microsoft Corp
+//
+
+#if __MACOS__
+#nullable enable
+
+using System.Runtime.InteropServices;
+using CoreFoundation;
+using ObjCRuntime;
+
+namespace ARKit {
+
+ /// Represents an error from the ARKit C API.
+ [SupportedOSPlatform ("macos26.0")]
+ public class ARError : ARObject {
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern /* ar_error_code_t */ nint ar_error_get_error_code (IntPtr error);
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern /* CFErrorRef */ IntPtr ar_error_copy_cf_error (IntPtr error);
+
+ [Preserve (Conditional = true)]
+ internal ARError (NativeHandle handle, bool owns)
+ : base (handle, owns)
+ {
+ }
+
+ /// Gets the error domain string for ARKit errors.
+ public static NSString? ErrorDomain {
+ get {
+ var h = Dlfcn.dlopen (Constants.ARKitLibrary, 0);
+ try {
+ return Dlfcn.GetStringConstant (h, "ar_error_domain");
+ } finally {
+ Dlfcn.dlclose (h);
+ }
+ }
+ }
+
+ /// Gets the error code associated with this error.
+ public nint ErrorCode {
+ get {
+ return ar_error_get_error_code (GetCheckedHandle ());
+ }
+ }
+
+ /// Gets a representation of this ARKit error.
+ public CFException CFError {
+ get {
+ return CFException.FromCFError (ar_error_copy_cf_error (GetCheckedHandle ()), true);
+ }
+ }
+ }
+}
+
+#endif // __MACOS__
diff --git a/src/ARKit/ARFaceGeometry.cs b/src/ARKit/ARFaceGeometry.cs
index 516b1078b22b..3a1ec8684535 100644
--- a/src/ARKit/ARFaceGeometry.cs
+++ b/src/ARKit/ARFaceGeometry.cs
@@ -1,3 +1,4 @@
+#if !__MACOS__
//
// ARFaceGeometry.cs: Nicer code for ARFaceGeometry
//
@@ -62,3 +63,5 @@ public unsafe short [] GetTriangleIndices ()
}
}
}
+
+#endif // !__MACOS__
diff --git a/src/ARKit/ARObject.cs b/src/ARKit/ARObject.cs
new file mode 100644
index 000000000000..cd635c229255
--- /dev/null
+++ b/src/ARKit/ARObject.cs
@@ -0,0 +1,76 @@
+//
+// ARObject.cs: Base class for the ARKit C API object types
+//
+// Provides ar_retain/ar_release lifecycle management following the
+// same pattern as CoreFoundation.OSLog (os_retain/os_release).
+//
+// Copyright 2025 Microsoft Corp
+//
+
+#if __MACOS__
+
+#nullable enable
+
+using System.Numerics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using CoreFoundation;
+using ObjCRuntime;
+
+using Matrix4 = global::CoreGraphics.NMatrix4;
+
+namespace ARKit {
+
+ // On ARM64, simd_float4x4 (4 × simd_float4) is an HVA returned in NEON registers v0-v3.
+ // NMatrix4 has 16 individual float fields and is NOT recognized as HVA by .NET, causing
+ // garbage when used as a P/Invoke return type. This struct uses Vector4 fields (128-bit
+ // SIMD type on ARM64) which .NET correctly classifies as HVA.
+ [StructLayout (LayoutKind.Sequential)]
+ internal struct SimdFloat4x4 {
+ public Vector4 Column0;
+ public Vector4 Column1;
+ public Vector4 Column2;
+ public Vector4 Column3;
+
+ public unsafe Matrix4 ToNMatrix4 ()
+ {
+ // Both SimdFloat4x4 and NMatrix4 are 64-byte column-major matrices with
+ // identical memory layout, so we can safely reinterpret the bits.
+ var self = this;
+ return *(Matrix4*) &self;
+ }
+ }
+
+ /// Base class for ARKit C API object types that use ar_retain/ar_release for lifecycle management.
+ [SupportedOSPlatform ("macos26.0")]
+ public class ARObject : NativeObject {
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern IntPtr ar_retain (IntPtr obj);
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern void ar_release (IntPtr obj);
+
+ [Preserve (Conditional = true)]
+ internal ARObject (NativeHandle handle, bool owns)
+ : base (handle, owns)
+ {
+ }
+
+ /// Retains the native ARKit object by calling ar_retain.
+ protected internal override void Retain ()
+ {
+ if (Handle != IntPtr.Zero)
+ ar_retain (Handle);
+ }
+
+ /// Releases the native ARKit object by calling ar_release.
+ protected internal override void Release ()
+ {
+ if (Handle != IntPtr.Zero)
+ ar_release (Handle);
+ }
+ }
+}
+
+#endif // __MACOS__
diff --git a/src/ARKit/ARPlaneGeometry.cs b/src/ARKit/ARPlaneGeometry.cs
index c41ae053c2f8..ad3f6800a8d7 100644
--- a/src/ARKit/ARPlaneGeometry.cs
+++ b/src/ARKit/ARPlaneGeometry.cs
@@ -1,3 +1,4 @@
+#if !__MACOS__
//
// ARPlaneGeometry.cs: Nicer code for ARPlaneGeometry
//
@@ -74,3 +75,5 @@ public unsafe Vector3 [] GetBoundaryVertices ()
}
}
}
+
+#endif // !__MACOS__
diff --git a/src/ARKit/ARPointCloud.cs b/src/ARKit/ARPointCloud.cs
index 5b295a966491..3b353a67e3f7 100644
--- a/src/ARKit/ARPointCloud.cs
+++ b/src/ARKit/ARPointCloud.cs
@@ -1,3 +1,4 @@
+#if !__MACOS__
//
// ARPointCloud.cs: Nicer code for ARPointCloud
//
@@ -43,3 +44,5 @@ public unsafe ulong [] Identifiers {
}
}
}
+
+#endif // !__MACOS__
diff --git a/src/ARKit/ARSession_C.cs b/src/ARKit/ARSession_C.cs
new file mode 100644
index 000000000000..ab44b58fc9fd
--- /dev/null
+++ b/src/ARKit/ARSession_C.cs
@@ -0,0 +1,144 @@
+//
+// ARSession.cs: Bindings for the ARKit C API session types
+//
+// Copyright 2025 Microsoft Corp
+//
+
+#if __MACOS__
+#nullable enable
+
+using System;
+using System.Runtime.InteropServices;
+using CoreFoundation;
+using ObjCRuntime;
+
+namespace ARKit {
+
+ /// Represents an ARKit device for session creation on macOS.
+ [SupportedOSPlatform ("macos26.0")]
+ public class ARDevice : ARObject {
+
+ [Preserve (Conditional = true)]
+ internal ARDevice (NativeHandle handle, bool owns)
+ : base (handle, owns)
+ {
+ }
+ }
+
+ /// Represents an ARKit session that manages data providers.
+ [SupportedOSPlatform ("macos26.0")]
+ public class ARSession : ARObject {
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern /* ar_session_t */ IntPtr ar_session_create_with_device (IntPtr device);
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern void ar_session_run (IntPtr session, IntPtr data_providers);
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern void ar_session_stop (IntPtr session);
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern /* ar_data_providers_t */ IntPtr ar_session_copy_data_providers (IntPtr session);
+
+ [DllImport (Constants.ARKitLibrary)]
+ unsafe static extern void ar_session_set_data_provider_state_change_handler_f (
+ IntPtr session,
+ IntPtr queue,
+ void* context,
+ delegate* unmanaged handler);
+
+ [Preserve (Conditional = true)]
+ internal ARSession (NativeHandle handle, bool owns)
+ : base (handle, owns)
+ {
+ }
+
+ /// Creates a new ARKit session connected to the specified device.
+ public ARSession (ARDevice device)
+ : base (ar_session_create_with_device (device.GetCheckedHandle ()), owns: true)
+ {
+ GC.KeepAlive (device);
+ }
+
+ /// Runs the specified data providers on this session.
+ public void Run (ARDataProviders dataProviders)
+ {
+ if (dataProviders is null)
+ ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (dataProviders));
+ ar_session_run (GetCheckedHandle (), dataProviders.GetCheckedHandle ());
+ GC.KeepAlive (dataProviders);
+ }
+
+ /// Stops all running data providers on this session.
+ public void Stop ()
+ {
+ ar_session_stop (GetCheckedHandle ());
+ }
+
+ /// Gets a copy of the collection of all data providers on this session.
+ public ARDataProviders CopyDataProviders ()
+ {
+ return new ARDataProviders (ar_session_copy_data_providers (GetCheckedHandle ()), owns: true);
+ }
+
+ /// Delegate for handling data provider state changes.
+ public delegate void DataProviderStateChangeHandler (ARDataProviders dataProviders, ARDataProviderState newState, ARError? error, ARDataProvider? failedDataProvider);
+
+ GCHandle _stateChangeGCHandle;
+
+ /// Sets a handler for responding to data provider state changes.
+ public void SetDataProviderStateChangeHandler (DispatchQueue? queue, DataProviderStateChangeHandler? handler)
+ {
+ var oldGCHandle = _stateChangeGCHandle;
+
+ if (handler is null) {
+ _stateChangeGCHandle = default;
+ unsafe {
+ ar_session_set_data_provider_state_change_handler_f (
+ GetCheckedHandle (),
+ queue.GetHandle (),
+ null,
+ null);
+ }
+ } else {
+ _stateChangeGCHandle = GCHandle.Alloc (handler);
+ unsafe {
+ delegate* unmanaged callback = &StateChangeTrampoline;
+ ar_session_set_data_provider_state_change_handler_f (
+ GetCheckedHandle (),
+ queue.GetHandle (),
+ (void*) GCHandle.ToIntPtr (_stateChangeGCHandle),
+ callback);
+ }
+ }
+
+ // Free old GCHandle after setting the new native handler to avoid
+ // a race where an in-flight callback uses a freed handle.
+ if (oldGCHandle.IsAllocated)
+ oldGCHandle.Free ();
+ GC.KeepAlive (queue);
+ }
+
+ [UnmanagedCallersOnly]
+ unsafe static void StateChangeTrampoline (void* context, IntPtr dataProviders, nint newState, IntPtr error, IntPtr failedDataProvider)
+ {
+ var handle = GCHandle.FromIntPtr ((IntPtr) context);
+ var handler = (DataProviderStateChangeHandler) handle.Target!;
+ handler (
+ new ARDataProviders (dataProviders, owns: false),
+ (ARDataProviderState) (long) newState,
+ error == IntPtr.Zero ? null : new ARError (error, owns: false),
+ failedDataProvider == IntPtr.Zero ? null : new ARDataProvider (failedDataProvider, owns: false));
+ }
+
+ protected override void Dispose (bool disposing)
+ {
+ base.Dispose (disposing);
+ if (_stateChangeGCHandle.IsAllocated)
+ _stateChangeGCHandle.Free ();
+ }
+ }
+}
+
+#endif // __MACOS__
diff --git a/src/ARKit/ARSkeleton.cs b/src/ARKit/ARSkeleton.cs
index c88e3aa295c1..0592b2a8b257 100644
--- a/src/ARKit/ARSkeleton.cs
+++ b/src/ARKit/ARSkeleton.cs
@@ -1,3 +1,4 @@
+#if !__MACOS__
using System.ComponentModel;
#nullable enable
@@ -6,12 +7,14 @@ namespace ARKit {
public partial class ARSkeleton {
[SupportedOSPlatform ("ios14.0")]
[UnsupportedOSPlatform ("maccatalyst")]
+ [UnsupportedOSPlatform ("macos")]
[UnsupportedOSPlatform ("tvos")]
[DllImport (Constants.ARKitLibrary)]
static extern IntPtr /* NSString */ ARSkeletonJointNameForRecognizedPointKey (/* NSString */ IntPtr recognizedPointKey);
[SupportedOSPlatform ("ios14.0")]
[UnsupportedOSPlatform ("maccatalyst")]
+ [UnsupportedOSPlatform ("macos")]
[UnsupportedOSPlatform ("tvos")]
public static NSString? CreateJointName (NSString recognizedPointKey)
{
@@ -23,3 +26,5 @@ public partial class ARSkeleton {
}
}
}
+
+#endif // !__MACOS__
diff --git a/src/ARKit/ARSkeleton2D.cs b/src/ARKit/ARSkeleton2D.cs
index 2b18d9ef38d5..de6d891988fa 100644
--- a/src/ARKit/ARSkeleton2D.cs
+++ b/src/ARKit/ARSkeleton2D.cs
@@ -1,3 +1,4 @@
+#if !__MACOS__
//
// ARSkeleton2D.cs: Nicer code for ARSkeleton2D
//
@@ -26,3 +27,5 @@ public unsafe Vector2 [] JointLandmarks {
}
}
}
+
+#endif // !__MACOS__
diff --git a/src/ARKit/ARSkeleton3D.cs b/src/ARKit/ARSkeleton3D.cs
index a5033bab227f..c47612d7c494 100644
--- a/src/ARKit/ARSkeleton3D.cs
+++ b/src/ARKit/ARSkeleton3D.cs
@@ -1,3 +1,4 @@
+#if !__MACOS__
//
// ARSkeleton3D.cs: Nicer code for ARSkeleton3D
//
@@ -37,3 +38,5 @@ public unsafe Matrix4 [] JointLocalTransforms {
}
}
}
+
+#endif // !__MACOS__
diff --git a/src/ARKit/ARWorldTracking.cs b/src/ARKit/ARWorldTracking.cs
new file mode 100644
index 000000000000..53d71f2c2a86
--- /dev/null
+++ b/src/ARKit/ARWorldTracking.cs
@@ -0,0 +1,177 @@
+//
+// ARWorldTracking.cs: Bindings for the ARKit C API world tracking types
+//
+// Copyright 2025 Microsoft Corp
+//
+
+#if __MACOS__
+#nullable enable
+
+using System;
+using System.Runtime.InteropServices;
+using CoreFoundation;
+using ObjCRuntime;
+
+using Matrix4 = global::CoreGraphics.NMatrix4;
+
+namespace ARKit {
+
+ /// Represents a device anchor that provides device pose information.
+ [SupportedOSPlatform ("macos26.0")]
+ public class ARDeviceAnchor : ARTrackableAnchor {
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern /* ar_device_anchor_t */ IntPtr ar_device_anchor_create ();
+
+ [DllImport (Constants.ARKitLibrary)]
+ unsafe static extern void ar_device_anchor_get_identifier (IntPtr anchor, byte* out_identifier);
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern /* simd_float4x4 */ SimdFloat4x4 ar_device_anchor_get_origin_from_anchor_transform (IntPtr anchor);
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern double ar_device_anchor_get_timestamp (IntPtr anchor);
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern byte ar_device_anchor_is_tracked (IntPtr anchor);
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern /* ar_device_anchor_tracking_state_t */ nint ar_device_anchor_get_tracking_state (IntPtr anchor);
+
+ [Preserve (Conditional = true)]
+ internal ARDeviceAnchor (NativeHandle handle, bool owns)
+ : base (handle, owns)
+ {
+ }
+
+ /// Creates a new device anchor.
+ public ARDeviceAnchor ()
+ : base (ar_device_anchor_create (), owns: true)
+ {
+ }
+
+ /// Gets the unique identifier of this device anchor.
+ public new Guid Identifier {
+ get {
+ unsafe {
+ byte* uuid = stackalloc byte [16];
+ ar_device_anchor_get_identifier (GetCheckedHandle (), uuid);
+ return new Guid (new ReadOnlySpan (uuid, 16));
+ }
+ }
+ }
+
+ /// Gets the transform from this device anchor to the origin coordinate system.
+ public new Matrix4 OriginFromAnchorTransform {
+ get {
+ var simd = ar_device_anchor_get_origin_from_anchor_transform (GetCheckedHandle ());
+ return simd.ToNMatrix4 ();
+ }
+ }
+
+ /// Gets the timestamp associated with this device anchor.
+ public new double Timestamp {
+ get {
+ return ar_device_anchor_get_timestamp (GetCheckedHandle ());
+ }
+ }
+
+ /// Gets a value indicating whether this device anchor is currently tracked.
+ public new bool IsTracked {
+ get {
+ return ar_device_anchor_is_tracked (GetCheckedHandle ()) != 0;
+ }
+ }
+
+ /// Gets the tracking state of this device anchor.
+ public ARDeviceAnchorTrackingState TrackingState {
+ get {
+ return (ARDeviceAnchorTrackingState) (long) ar_device_anchor_get_tracking_state (GetCheckedHandle ());
+ }
+ }
+ }
+
+ /// Represents a world tracking configuration.
+ [SupportedOSPlatform ("macos26.0")]
+ public class ARWorldTrackingConfiguration : ARObject {
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern /* ar_world_tracking_configuration_t */ IntPtr ar_world_tracking_configuration_create ();
+
+ [Preserve (Conditional = true)]
+ internal ARWorldTrackingConfiguration (NativeHandle handle, bool owns)
+ : base (handle, owns)
+ {
+ }
+
+ /// Creates a new world tracking configuration.
+ public ARWorldTrackingConfiguration ()
+ : base (ar_world_tracking_configuration_create (), owns: true)
+ {
+ }
+ }
+
+ /// Represents a world tracking data provider.
+ [SupportedOSPlatform ("macos26.0")]
+ public class ARWorldTrackingProvider : ARDataProvider {
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern /* ar_world_tracking_provider_t */ IntPtr ar_world_tracking_provider_create (IntPtr world_tracking_configuration);
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern byte ar_world_tracking_provider_is_supported ();
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern /* ar_device_anchor_query_status_t */ nint ar_world_tracking_provider_query_device_anchor_at_timestamp (
+ IntPtr world_tracking_provider,
+ double timestamp,
+ IntPtr device_anchor);
+
+ [DllImport (Constants.ARKitLibrary)]
+ static extern /* ar_authorization_type_t */ nuint ar_world_tracking_provider_get_required_authorization_type ();
+
+ [Preserve (Conditional = true)]
+ internal ARWorldTrackingProvider (NativeHandle handle, bool owns)
+ : base (handle, owns)
+ {
+ }
+
+ /// Creates a new world tracking provider with the specified configuration.
+ public ARWorldTrackingProvider (ARWorldTrackingConfiguration configuration)
+ : base (ar_world_tracking_provider_create (configuration.GetCheckedHandle ()), owns: true)
+ {
+ GC.KeepAlive (configuration);
+ }
+
+ /// Gets a value indicating whether this device supports the world tracking provider.
+ public static bool IsSupported {
+ get {
+ return ar_world_tracking_provider_is_supported () != 0;
+ }
+ }
+
+ /// Gets the authorization type required by the world tracking provider.
+ public static new ARAuthorizationType RequiredAuthorizationType {
+ get {
+ return (ARAuthorizationType) (ulong) ar_world_tracking_provider_get_required_authorization_type ();
+ }
+ }
+
+ /// Queries the device anchor at the given timestamp.
+ /// The timestamp to query, as mach absolute time in seconds.
+ /// The device anchor to populate with the query result.
+ /// The status of the query.
+ /// This API is not thread safe.
+ public ARDeviceAnchorQueryStatus QueryDeviceAnchor (double timestamp, ARDeviceAnchor deviceAnchor)
+ {
+ if (deviceAnchor is null)
+ ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (deviceAnchor));
+ var result = (ARDeviceAnchorQueryStatus) (long) ar_world_tracking_provider_query_device_anchor_at_timestamp (
+ GetCheckedHandle (), timestamp, deviceAnchor.GetCheckedHandle ());
+ GC.KeepAlive (deviceAnchor);
+ return result;
+ }
+ }
+}
+
+#endif // __MACOS__
diff --git a/src/arkit.cs b/src/arkit.cs
index 9cd07608967d..cd7d95e03387 100644
--- a/src/arkit.cs
+++ b/src/arkit.cs
@@ -1,3 +1,4 @@
+#if !__MACOS__
//
// ARKit bindings
//
@@ -230,6 +231,7 @@ public enum ARPlaneClassification : long {
[iOS (13, 0)]
[Native]
+ [NoMac]
public enum ARCoachingGoal : long {
Tracking,
HorizontalPlane,
@@ -242,6 +244,7 @@ public enum ARCoachingGoal : long {
[iOS (13, 0)]
[Flags]
[Native]
+ [NoMac]
public enum ARFrameSemantics : long {
None = 0x0,
PersonSegmentation = 1 << 0,
@@ -255,6 +258,7 @@ public enum ARFrameSemantics : long {
[iOS (13, 0)]
[Native]
+ [NoMac]
public enum ARMatteResolution : long {
Full = 0,
Half = 1,
@@ -262,6 +266,7 @@ public enum ARMatteResolution : long {
[iOS (13, 0)]
[Native]
+ [NoMac]
public enum ARRaycastTarget : long {
ExistingPlaneGeometry,
ExistingPlaneInfinite,
@@ -270,6 +275,7 @@ public enum ARRaycastTarget : long {
[iOS (13, 0)]
[Native]
+ [NoMac]
public enum ARRaycastTargetAlignment : long {
Horizontal,
Vertical,
@@ -277,6 +283,7 @@ public enum ARRaycastTargetAlignment : long {
}
[iOS (13, 0)]
+ [NoMac]
public enum ARSegmentationClass : byte {
None = 0,
Person = 255,
@@ -284,6 +291,7 @@ public enum ARSegmentationClass : byte {
[iOS (13, 0)]
[Native]
+ [NoMac]
public enum ARCollaborationDataPriority : long {
Critical,
Optional,
@@ -292,6 +300,7 @@ public enum ARCollaborationDataPriority : long {
[iOS (14, 0)]
[Native]
+ [NoMac]
public enum ARAltitudeSource : long {
Unknown,
Coarse,
@@ -301,6 +310,7 @@ public enum ARAltitudeSource : long {
[iOS (14, 0)]
[Native]
+ [NoMac]
public enum ARConfidenceLevel : long {
Low,
Medium,
@@ -309,6 +319,7 @@ public enum ARConfidenceLevel : long {
[iOS (14, 0)]
[Native]
+ [NoMac]
public enum ARGeoTrackingAccuracy : long {
Undetermined,
Low,
@@ -318,6 +329,7 @@ public enum ARGeoTrackingAccuracy : long {
[iOS (14, 0)]
[Native]
+ [NoMac]
public enum ARGeoTrackingState : long {
NotAvailable,
Initializing,
@@ -327,6 +339,7 @@ public enum ARGeoTrackingState : long {
[iOS (14, 0)]
[Native]
+ [NoMac]
public enum ARGeoTrackingStateReason : long {
None,
NotAvailableAtLocation,
@@ -341,6 +354,7 @@ public enum ARGeoTrackingStateReason : long {
[iOS (14, 3)]
[Native]
+ [NoMac]
public enum ARAppClipCodeUrlDecodingState : long {
Decoding,
Failed,
@@ -642,6 +656,7 @@ Vector3 Extent {
/// Geometry representing a plane detected in the real world.
[BaseType (typeof (NSObject))]
[DisableDefaultCtor]
+ [NoMac]
interface ARPlaneGeometry : NSSecureCoding {
[Export ("vertexCount")]
nuint VertexCount { get; }
@@ -674,6 +689,7 @@ interface ARPlaneGeometry : NSSecureCoding {
[BaseType (typeof (SCNGeometry))]
[DisableDefaultCtor]
+ [NoMac]
interface ARSCNPlaneGeometry {
[Static]
[Export ("planeGeometryWithDevice:")]
@@ -750,6 +766,7 @@ interface ARReferenceImage : NSCopying {
/// Summary information about the video feed used in the AR simulation.
[BaseType (typeof (NSObject))]
[DisableDefaultCtor]
+ [NoMac]
interface ARVideoFormat : NSCopying {
[iOS (13, 0)]
@@ -832,6 +849,7 @@ interface ARSCNView : ARSessionProviding {
ARRaycastQuery CreateRaycastQuery (CGPoint point, ARRaycastTarget target, ARRaycastTargetAlignment alignment);
}
+ [NoMac]
interface IARSCNViewDelegate { }
/// Delegate object for objects.
@@ -907,6 +925,7 @@ interface ARSKView : ARSessionProviding {
ARHitTestResult [] HitTest (CGPoint point, ARHitTestResultType types);
}
+ [NoMac]
interface IARSKViewDelegate { }
/// Delegate object allowing the developer to respond to events relating to a .
@@ -957,6 +976,7 @@ interface ARSKViewDelegate : SKViewDelegate, ARSessionObserver {
void DidRemoveNode (ARSKView view, SKNode node, ARAnchor anchor);
}
+ [NoMac]
delegate void GetGeolocationCallback (CLLocationCoordinate2D coordinate, double altitude, [NullAllowed] NSError error);
///
@@ -1050,6 +1070,7 @@ interface ARSession {
void CaptureHighResolutionFrame ([NullAllowed] AVCapturePhotoSettings photoSettings, ARSessionCaptureHighResolutionFrame completion);
}
+ [NoMac]
delegate void ARSessionCaptureHighResolutionFrame ([NullAllowed] ARFrame frame, [NullAllowed] NSError error);
/// Interface defining methods that respond to events in an .
@@ -1107,6 +1128,7 @@ interface ARSessionObserver {
void DidChangeGeoTrackingStatus (ARSession session, ARGeoTrackingStatus geoTrackingStatus);
}
+ [NoMac]
interface IARSessionDelegate { }
/// Delegate object for the object, allowing the developer to respond to events relating to the augmented-reality session.
@@ -2114,6 +2136,7 @@ Vector3 Extent {
[iOS (13, 0)]
[BaseType (typeof (NSObject))]
[DisableDefaultCtor]
+ [NoMac]
interface ARBody2D {
[Export ("skeleton")]
@@ -2123,6 +2146,7 @@ interface ARBody2D {
[iOS (13, 0)]
[BaseType (typeof (ARAnchor))]
[DisableDefaultCtor]
+ [NoMac]
interface ARBodyAnchor : ARTrackable {
[Export ("initWithAnchor:")]
@@ -2140,6 +2164,7 @@ interface ARBodyAnchor : ARTrackable {
[iOS (13, 0)]
[BaseType (typeof (UIView))]
+ [NoMac]
interface ARCoachingOverlayView {
// inherited from UIView
@@ -2173,11 +2198,13 @@ interface ARCoachingOverlayView {
void SetActive (bool active, bool animated);
}
+ [NoMac]
interface IARCoachingOverlayViewDelegate { }
[iOS (13, 0)]
[Protocol, Model]
[BaseType (typeof (NSObject))]
+ [NoMac]
interface ARCoachingOverlayViewDelegate {
[Export ("coachingOverlayViewDidRequestSessionReset:")]
@@ -2193,6 +2220,7 @@ interface ARCoachingOverlayViewDelegate {
[iOS (13, 0)]
[BaseType (typeof (NSObject))]
[DisableDefaultCtor]
+ [NoMac]
interface ARCollaborationData : NSSecureCoding {
[Export ("priority")]
@@ -2201,6 +2229,7 @@ interface ARCollaborationData : NSSecureCoding {
[iOS (13, 0)]
[BaseType (typeof (ARConfiguration))]
+ [NoMac]
interface ARBodyTrackingConfiguration {
// From the parent, needed in all subclasses
@@ -2251,6 +2280,7 @@ interface ARBodyTrackingConfiguration {
[iOS (13, 0)]
[BaseType (typeof (ARConfiguration))]
+ [NoMac]
interface ARPositionalTrackingConfiguration {
// From the parent, needed in all subclasses
@@ -2272,6 +2302,7 @@ interface ARPositionalTrackingConfiguration {
[iOS (13, 0)]
[BaseType (typeof (NSObject))]
[DisableDefaultCtor]
+ [NoMac]
interface ARMatteGenerator {
[DesignatedInitializer]
@@ -2288,6 +2319,7 @@ interface ARMatteGenerator {
[iOS (13, 0)]
[BaseType (typeof (NSObject))]
[DisableDefaultCtor]
+ [NoMac]
interface ARRaycastQuery {
[Export ("initWithOrigin:direction:allowingTarget:alignment:")]
@@ -2316,6 +2348,7 @@ Vector3 Direction {
[iOS (13, 0)]
[BaseType (typeof (NSObject))]
[DisableDefaultCtor]
+ [NoMac]
interface ARRaycastResult {
[Export ("worldTransform")]
@@ -2334,10 +2367,12 @@ Matrix4 WorldTransform {
ARAnchor Anchor { get; }
}
+ [NoMac]
interface IARSessionProviding { }
[iOS (13, 0)]
[Protocol]
+ [NoMac]
interface ARSessionProviding {
[Abstract]
@@ -2348,6 +2383,7 @@ interface ARSessionProviding {
[iOS (13, 0)]
[BaseType (typeof (NSObject))]
[DisableDefaultCtor]
+ [NoMac]
interface ARSkeleton {
[Export ("definition")]
@@ -2363,6 +2399,7 @@ interface ARSkeleton {
[iOS (13, 0)]
[BaseType (typeof (ARSkeleton))]
[DisableDefaultCtor]
+ [NoMac]
interface ARSkeleton3D {
[EditorBrowsable (EditorBrowsableState.Advanced)]
@@ -2393,6 +2430,7 @@ interface ARSkeleton3D {
[iOS (13, 0)]
[BaseType (typeof (ARSkeleton))]
[DisableDefaultCtor]
+ [NoMac]
interface ARSkeleton2D {
[EditorBrowsable (EditorBrowsableState.Advanced)]
@@ -2411,6 +2449,7 @@ interface ARSkeleton2D {
[iOS (13, 0)]
[BaseType (typeof (NSObject))]
[DisableDefaultCtor]
+ [NoMac]
interface ARSkeletonDefinition {
[Static]
@@ -2472,6 +2511,7 @@ enum ARSkeletonJointName {
[iOS (13, 0)]
[BaseType (typeof (NSObject))]
[DisableDefaultCtor]
+ [NoMac]
interface ARTrackedRaycast {
[Export ("stopTracking")]
@@ -2481,6 +2521,7 @@ interface ARTrackedRaycast {
[iOS (13, 0)]
[BaseType (typeof (ARAnchor))]
[DisableDefaultCtor]
+ [NoMac]
interface ARParticipantAnchor {
// Inlined from 'ARAnchorCopying' protocol (we can't have constructors in interfaces)
@@ -2503,6 +2544,7 @@ enum ARSceneReconstruction : ulong {
[iOS (13, 4)]
[BaseType (typeof (ARAnchor))]
[DisableDefaultCtor]
+ [NoMac]
interface ARMeshAnchor {
// Inlined from 'ARAnchorCopying' protocol (we can't have constructors in interfaces)
@@ -2519,6 +2561,7 @@ interface ARMeshAnchor {
[iOS (13, 4)]
[BaseType (typeof (NSObject))]
[DisableDefaultCtor]
+ [NoMac]
interface ARGeometrySource : NSSecureCoding {
[Export ("buffer", ArgumentSemantic.Strong)]
@@ -2550,6 +2593,7 @@ enum ARGeometryPrimitiveType : long {
[iOS (13, 4)]
[BaseType (typeof (NSObject))]
[DisableDefaultCtor]
+ [NoMac]
interface ARGeometryElement : NSSecureCoding {
[Export ("buffer", ArgumentSemantic.Strong)]
@@ -2584,6 +2628,7 @@ enum ARMeshClassification : long {
[iOS (13, 4)]
[BaseType (typeof (NSObject))]
[DisableDefaultCtor]
+ [NoMac]
interface ARMeshGeometry : NSSecureCoding {
[Export ("vertices", ArgumentSemantic.Strong)]
@@ -2603,6 +2648,7 @@ interface ARMeshGeometry : NSSecureCoding {
[iOS (14, 0)]
[BaseType (typeof (NSObject))]
[DisableDefaultCtor]
+ [NoMac]
interface ARDepthData {
[Export ("depthMap", ArgumentSemantic.Assign)]
CVPixelBuffer DepthMap { get; }
@@ -2613,6 +2659,7 @@ interface ARDepthData {
[iOS (14, 0)]
[BaseType (typeof (ARAnchor))]
+ [NoMac]
interface ARGeoAnchor : ARTrackable {
// Inlined from 'ARAnchorCopying' protocol (we can't have constructors in interfaces)
[Export ("initWithAnchor:")]
@@ -2642,6 +2689,7 @@ interface ARGeoAnchor : ARTrackable {
[iOS (14, 0)]
[BaseType (typeof (ARConfiguration))]
+ [NoMac]
interface ARGeoTrackingConfiguration {
[Static]
[Export ("supportedVideoFormats")]
@@ -2700,6 +2748,7 @@ interface ARGeoTrackingConfiguration {
[iOS (14, 0)]
[BaseType (typeof (NSObject))]
[DisableDefaultCtor]
+ [NoMac]
interface ARGeoTrackingStatus : NSCopying, NSSecureCoding {
[Export ("state")]
ARGeoTrackingState State { get; }
@@ -2714,6 +2763,7 @@ interface ARGeoTrackingStatus : NSCopying, NSSecureCoding {
[iOS (14, 3)]
[BaseType (typeof (ARAnchor))]
[DisableDefaultCtor]
+ [NoMac]
interface ARAppClipCodeAnchor : ARTrackable {
// Inlined from 'ARAnchorCopying' protocol (we can't have constructors in interfaces)
@@ -2732,6 +2782,7 @@ interface ARAppClipCodeAnchor : ARTrackable {
[iOS (16, 0)]
[BaseType (typeof (NSObject))]
+ [NoMac]
interface ARPlaneExtent : NSSecureCoding {
[Export ("rotationOnYAxis")]
float RotationOnYAxis { get; }
@@ -2745,3 +2796,5 @@ interface ARPlaneExtent : NSSecureCoding {
}
+
+#endif // !__MACOS__
diff --git a/src/build/dotnet/generator-frameworks.g.cs b/src/build/dotnet/generator-frameworks.g.cs
index 9346b0afb5e1..1ab89f9fc24e 100644
--- a/src/build/dotnet/generator-frameworks.g.cs
+++ b/src/build/dotnet/generator-frameworks.g.cs
@@ -162,6 +162,7 @@ partial class Frameworks {
"AdSupport",
"AppKit",
"AppTrackingTransparency",
+ "ARKit",
"AudioToolbox",
"AudioUnit",
"AuthenticationServices",
diff --git a/src/frameworks.sources b/src/frameworks.sources
index a8254313ba3f..e5f976ba6ebf 100644
--- a/src/frameworks.sources
+++ b/src/frameworks.sources
@@ -159,6 +159,14 @@ APPKIT_SOURCES = \
# ARKit
ARKIT_SOURCES = \
+ ARKit/ARObject.cs \
+ ARKit/AREnums.cs \
+ ARKit/ARError_C.cs \
+ ARKit/ARAnchor_C.cs \
+ ARKit/ARAuthorizationResult.cs \
+ ARKit/ARDataProvider.cs \
+ ARKit/ARSession_C.cs \
+ ARKit/ARWorldTracking.cs \
ARKit/ARFaceGeometry.cs \
ARKit/ARPlaneGeometry.cs \
ARKit/ARPointCloud.cs \
@@ -2001,6 +2009,7 @@ MACOS_FRAMEWORKS = \
AdSupport \
AppKit XKit \
AppTrackingTransparency \
+ ARKit \
AudioToolbox \
AudioUnit \
AutomaticAssessmentConfiguration \
diff --git a/src/rsp/dotnet/macos-defines-dotnet.rsp b/src/rsp/dotnet/macos-defines-dotnet.rsp
index 17b1bd296208..b6a5b32c62ec 100644
--- a/src/rsp/dotnet/macos-defines-dotnet.rsp
+++ b/src/rsp/dotnet/macos-defines-dotnet.rsp
@@ -5,6 +5,7 @@
-d:HAS_ADSUPPORT
-d:HAS_APPKIT
-d:HAS_APPTRACKINGTRANSPARENCY
+-d:HAS_ARKIT
-d:HAS_AUDIOTOOLBOX
-d:HAS_AUDIOUNIT
-d:HAS_AUTHENTICATIONSERVICES
diff --git a/tests/cecil-tests/ApiTest.KnownFailures.cs b/tests/cecil-tests/ApiTest.KnownFailures.cs
index 2127b451fa98..a363e7a9932e 100644
--- a/tests/cecil-tests/ApiTest.KnownFailures.cs
+++ b/tests/cecil-tests/ApiTest.KnownFailures.cs
@@ -356,6 +356,19 @@ public partial class ApiTest {
"AppKit.NSPressGestureRecognizer/Callback.Activated(AppKit.NSPressGestureRecognizer)",
"AppKit.NSRotationGestureRecognizer/Callback",
"AppKit.NSRotationGestureRecognizer/Callback.Activated(AppKit.NSRotationGestureRecognizer)",
+ "ARKit.ARAnchor..ctor(ObjCRuntime.NativeHandle, System.Boolean)",
+ "ARKit.ARAuthorizationResult..ctor(ObjCRuntime.NativeHandle, System.Boolean)",
+ "ARKit.ARAuthorizationResults..ctor(ObjCRuntime.NativeHandle, System.Boolean)",
+ "ARKit.ARDataProvider..ctor(ObjCRuntime.NativeHandle, System.Boolean)",
+ "ARKit.ARDataProviders..ctor(ObjCRuntime.NativeHandle, System.Boolean)",
+ "ARKit.ARDevice..ctor(ObjCRuntime.NativeHandle, System.Boolean)",
+ "ARKit.ARDeviceAnchor..ctor(ObjCRuntime.NativeHandle, System.Boolean)",
+ "ARKit.ARError..ctor(ObjCRuntime.NativeHandle, System.Boolean)",
+ "ARKit.ARObject..ctor(ObjCRuntime.NativeHandle, System.Boolean)",
+ "ARKit.ARSession..ctor(ObjCRuntime.NativeHandle, System.Boolean)",
+ "ARKit.ARTrackableAnchor..ctor(ObjCRuntime.NativeHandle, System.Boolean)",
+ "ARKit.ARWorldTrackingConfiguration..ctor(ObjCRuntime.NativeHandle, System.Boolean)",
+ "ARKit.ARWorldTrackingProvider..ctor(ObjCRuntime.NativeHandle, System.Boolean)",
"AudioToolbox.AudioConverter..ctor(ObjCRuntime.NativeHandle, System.Boolean)",
"AudioToolbox.AudioFile..ctor(ObjCRuntime.NativeHandle, System.Boolean)",
"AudioToolbox.MusicPlayer..ctor(ObjCRuntime.NativeHandle, System.Boolean)",
diff --git a/tests/dotnet/UnitTests/ProjectTest.cs b/tests/dotnet/UnitTests/ProjectTest.cs
index db0634f8b81e..47edd8846da3 100644
--- a/tests/dotnet/UnitTests/ProjectTest.cs
+++ b/tests/dotnet/UnitTests/ProjectTest.cs
@@ -3302,6 +3302,7 @@ public void AppendRuntimeIdentifierToOutputPath_DisableDirectoryBuildProps (Appl
"/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit",
"/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices",
"/System/Library/Frameworks/AppTrackingTransparency.framework/Versions/A/AppTrackingTransparency",
+ "/System/Library/Frameworks/ARKit.framework/Versions/A/ARKit",
"/System/Library/Frameworks/AudioToolbox.framework/Versions/A/AudioToolbox",
"/System/Library/Frameworks/AudioUnit.framework/Versions/A/AudioUnit",
"/System/Library/Frameworks/AuthenticationServices.framework/Versions/A/AuthenticationServices",
diff --git a/tests/dotnet/UnitTests/expected/MacOSX-CoreCLR-Interpreter-size.txt b/tests/dotnet/UnitTests/expected/MacOSX-CoreCLR-Interpreter-size.txt
index f991490a3294..51e44e1e1024 100644
--- a/tests/dotnet/UnitTests/expected/MacOSX-CoreCLR-Interpreter-size.txt
+++ b/tests/dotnet/UnitTests/expected/MacOSX-CoreCLR-Interpreter-size.txt
@@ -1,10 +1,10 @@
-AppBundleSize: 247,357,169 bytes (241,559.7 KB = 235.9 MB)
+AppBundleSize: 247,382,138 bytes (241,584.1 KB = 235.9 MB)
# The following list of files and their sizes is just informational / for review, and isn't used in the test:
Contents/_CodeSignature/CodeResources: 67,160 bytes (65.6 KB = 0.1 MB)
-Contents/Info.plist: 725 bytes (0.7 KB = 0.0 MB)
-Contents/MacOS/SizeTestApp: 8,001,536 bytes (7,814.0 KB = 7.6 MB)
+Contents/Info.plist: 734 bytes (0.7 KB = 0.0 MB)
+Contents/MacOS/SizeTestApp: 8,000,896 bytes (7,813.4 KB = 7.6 MB)
Contents/MonoBundle/.xamarin/osx-arm64/Microsoft.CSharp.dll: 893,200 bytes (872.3 KB = 0.9 MB)
-Contents/MonoBundle/.xamarin/osx-arm64/Microsoft.macOS.dll: 36,723,712 bytes (35,863.0 KB = 35.0 MB)
+Contents/MonoBundle/.xamarin/osx-arm64/Microsoft.macOS.dll: 36,736,512 bytes (35,875.5 KB = 35.0 MB)
Contents/MonoBundle/.xamarin/osx-arm64/Microsoft.VisualBasic.Core.dll: 1,335,048 bytes (1,303.8 KB = 1.3 MB)
Contents/MonoBundle/.xamarin/osx-arm64/Microsoft.VisualBasic.dll: 17,712 bytes (17.3 KB = 0.0 MB)
Contents/MonoBundle/.xamarin/osx-arm64/Microsoft.Win32.Primitives.dll: 16,144 bytes (15.8 KB = 0.0 MB)
@@ -178,7 +178,7 @@ Contents/MonoBundle/.xamarin/osx-arm64/System.Xml.XPath.dll: 16,136 bytes (15.8
Contents/MonoBundle/.xamarin/osx-arm64/System.Xml.XPath.XDocument.dll: 17,672 bytes (17.3 KB = 0.0 MB)
Contents/MonoBundle/.xamarin/osx-arm64/WindowsBase.dll: 16,656 bytes (16.3 KB = 0.0 MB)
Contents/MonoBundle/.xamarin/osx-x64/Microsoft.CSharp.dll: 796,432 bytes (777.8 KB = 0.8 MB)
-Contents/MonoBundle/.xamarin/osx-x64/Microsoft.macOS.dll: 36,723,712 bytes (35,863.0 KB = 35.0 MB)
+Contents/MonoBundle/.xamarin/osx-x64/Microsoft.macOS.dll: 36,736,512 bytes (35,875.5 KB = 35.0 MB)
Contents/MonoBundle/.xamarin/osx-x64/Microsoft.VisualBasic.Core.dll: 1,166,600 bytes (1,139.3 KB = 1.1 MB)
Contents/MonoBundle/.xamarin/osx-x64/Microsoft.VisualBasic.dll: 17,720 bytes (17.3 KB = 0.0 MB)
Contents/MonoBundle/.xamarin/osx-x64/Microsoft.Win32.Primitives.dll: 16,144 bytes (15.8 KB = 0.0 MB)
diff --git a/tests/introspection/ApiCtorInitTest.cs b/tests/introspection/ApiCtorInitTest.cs
index 53a9b0d0ca5c..2e16182ae08a 100644
--- a/tests/introspection/ApiCtorInitTest.cs
+++ b/tests/introspection/ApiCtorInitTest.cs
@@ -731,7 +731,7 @@ protected virtual bool SkipCheckShouldReExposeBaseCtor (Type type)
return SkipDueToAttribute (type);
}
-#if HAS_ARKIT
+#if HAS_ARKIT && !__MACOS__
///
/// Ensures that all subclasses of a base class that conforms to IARAnchorCopying re-expose its constructor.
/// Note: we cannot have constructors in protocols so we have to inline them in every subclass.
diff --git a/tests/monotouch-test/ARKit/ARAnchorTest.cs b/tests/monotouch-test/ARKit/ARAnchorTest.cs
index 567a7638839d..d56e75165a89 100644
--- a/tests/monotouch-test/ARKit/ARAnchorTest.cs
+++ b/tests/monotouch-test/ARKit/ARAnchorTest.cs
@@ -7,7 +7,7 @@
// Copyright 2018 Microsoft. All rights reserved.
//
-#if HAS_ARKIT
+#if HAS_ARKIT && !__MACOS__
using ARKit;
using Xamarin.Utils;
diff --git a/tests/monotouch-test/ARKit/ARConfigurationTest.cs b/tests/monotouch-test/ARKit/ARConfigurationTest.cs
index 567cf41d6182..809ffec670a9 100644
--- a/tests/monotouch-test/ARKit/ARConfigurationTest.cs
+++ b/tests/monotouch-test/ARKit/ARConfigurationTest.cs
@@ -1,4 +1,4 @@
-#if HAS_ARKIT
+#if HAS_ARKIT && !__MACOS__
using System.Reflection;
using ARKit;
diff --git a/tests/monotouch-test/ARKit/AREnvironmentProbeAnchorTest.cs b/tests/monotouch-test/ARKit/AREnvironmentProbeAnchorTest.cs
index 186da1aebbc3..41a312752ee4 100644
--- a/tests/monotouch-test/ARKit/AREnvironmentProbeAnchorTest.cs
+++ b/tests/monotouch-test/ARKit/AREnvironmentProbeAnchorTest.cs
@@ -7,7 +7,7 @@
// Copyright 2018 Microsoft. All rights reserved.
//
-#if HAS_ARKIT
+#if HAS_ARKIT && !__MACOS__
using ARKit;
using Xamarin.Utils;
diff --git a/tests/monotouch-test/ARKit/ARFaceGeometryTest.cs b/tests/monotouch-test/ARKit/ARFaceGeometryTest.cs
index b69229252223..964b0a40ddba 100644
--- a/tests/monotouch-test/ARKit/ARFaceGeometryTest.cs
+++ b/tests/monotouch-test/ARKit/ARFaceGeometryTest.cs
@@ -7,7 +7,7 @@
// Copyright 2017 Microsoft. All rights reserved.
//
-#if HAS_ARKIT
+#if HAS_ARKIT && !__MACOS__
using System.Threading.Tasks;
using ARKit;
diff --git a/tests/monotouch-test/ARKit/ARObjectTest.cs b/tests/monotouch-test/ARKit/ARObjectTest.cs
new file mode 100644
index 000000000000..36586b4d7e0d
--- /dev/null
+++ b/tests/monotouch-test/ARKit/ARObjectTest.cs
@@ -0,0 +1,307 @@
+//
+// Unit tests for the ARKit C API bindings (ar_* functions)
+//
+// These tests exercise the new C-style ARKit API that was
+// introduced on macOS 26.0. The API uses OS_OBJECT patterns
+// (ar_retain/ar_release) rather than Objective-C.
+//
+
+#if __MACOS__
+
+using System;
+using ARKit;
+using CoreGraphics;
+using Foundation;
+using ObjCRuntime;
+using Xamarin.Utils;
+
+using Matrix4 = global::CoreGraphics.NMatrix4;
+
+namespace MonoTouchFixtures.ARKit {
+
+ [TestFixture]
+ [Preserve (AllMembers = true)]
+ public class ARObjectTest {
+
+ [SetUp]
+ public void SetUp ()
+ {
+ TestRuntime.AssertXcodeVersion (26, 0);
+ TestRuntime.AssertSystemVersion (ApplePlatform.MacOSX, 26, 0, throwIfOtherPlatform: false);
+ }
+
+ #region ARWorldTrackingConfiguration
+
+ [Test]
+ public void ARWorldTrackingConfiguration_Create ()
+ {
+ using var config = new ARWorldTrackingConfiguration ();
+ Assert.AreNotEqual (IntPtr.Zero, config.Handle, "Handle");
+ }
+
+ [Test]
+ public void ARWorldTrackingConfiguration_Dispose ()
+ {
+ var config = new ARWorldTrackingConfiguration ();
+ Assert.AreNotEqual (IntPtr.Zero, config.Handle, "Handle before dispose");
+ config.Dispose ();
+ Assert.That (config.Handle, Is.EqualTo (NativeHandle.Zero), "Handle after dispose");
+ }
+
+ #endregion
+
+ #region ARWorldTrackingProvider
+
+ [Test]
+ public void ARWorldTrackingProvider_IsSupported ()
+ {
+ var supported = ARWorldTrackingProvider.IsSupported;
+ Assert.IsNotNull (supported.ToString ());
+ }
+
+ [Test]
+ public void ARWorldTrackingProvider_RequiredAuthorizationType ()
+ {
+ var authType = ARWorldTrackingProvider.RequiredAuthorizationType;
+ Assert.That ((ulong) authType, Is.LessThanOrEqualTo ((ulong) (
+ ARAuthorizationType.HandTracking |
+ ARAuthorizationType.WorldSensing |
+ ARAuthorizationType.CameraAccess)),
+ "RequiredAuthorizationType should be a valid flags combination");
+ }
+
+ [Test]
+ public void ARWorldTrackingProvider_Create ()
+ {
+ using var config = new ARWorldTrackingConfiguration ();
+ using var provider = new ARWorldTrackingProvider (config);
+ Assert.AreNotEqual (IntPtr.Zero, provider.Handle, "Handle");
+ }
+
+ [Test]
+ public void ARWorldTrackingProvider_State ()
+ {
+ using var config = new ARWorldTrackingConfiguration ();
+ using var provider = new ARWorldTrackingProvider (config);
+ Assert.AreEqual (ARDataProviderState.Initialized, provider.State, "State");
+ }
+
+ [Test]
+ public void ARWorldTrackingProvider_RequiredAuthorizationType_Instance ()
+ {
+ // RequiredAuthorizationType is static, verify via type name
+ var authType = ARWorldTrackingProvider.RequiredAuthorizationType;
+ Assert.That ((ulong) authType, Is.LessThanOrEqualTo ((ulong) (
+ ARAuthorizationType.HandTracking |
+ ARAuthorizationType.WorldSensing |
+ ARAuthorizationType.CameraAccess)),
+ "Static RequiredAuthorizationType");
+ }
+
+ #endregion
+
+ #region ARDataProviders
+
+ [Test]
+ public void ARDataProviders_CreateEmpty ()
+ {
+ using var providers = new ARDataProviders ();
+ Assert.AreNotEqual (IntPtr.Zero, providers.Handle, "Handle");
+ Assert.AreEqual ((nuint) 0, providers.Count, "Count");
+ }
+
+ [Test]
+ public void ARDataProviders_AddRemove ()
+ {
+ using var config = new ARWorldTrackingConfiguration ();
+ using var provider = new ARWorldTrackingProvider (config);
+ using var providers = new ARDataProviders ();
+
+ Assert.AreEqual ((nuint) 0, providers.Count, "Count before add");
+ providers.Add (provider);
+ Assert.AreEqual ((nuint) 1, providers.Count, "Count after add");
+ providers.Remove (provider);
+ Assert.AreEqual ((nuint) 0, providers.Count, "Count after remove");
+ }
+
+ [Test]
+ public void ARDataProviders_GetDataProviders ()
+ {
+ using var config = new ARWorldTrackingConfiguration ();
+ using var provider = new ARWorldTrackingProvider (config);
+ using var providers = new ARDataProviders ();
+
+ providers.Add (provider);
+ var result = providers.GetDataProviders ();
+ Assert.AreEqual (1, result.Length, "Length");
+ Assert.AreNotEqual (IntPtr.Zero, result [0].Handle, "result[0].Handle");
+ }
+
+ [Test]
+ public void ARDataProviders_Dispose ()
+ {
+ var providers = new ARDataProviders ();
+ Assert.AreNotEqual (IntPtr.Zero, providers.Handle, "Handle before dispose");
+ providers.Dispose ();
+ Assert.That (providers.Handle, Is.EqualTo (NativeHandle.Zero), "Handle after dispose");
+ }
+
+ #endregion
+
+ #region ARDeviceAnchor
+
+ [Test]
+ public void ARDeviceAnchor_Create ()
+ {
+ using var anchor = new ARDeviceAnchor ();
+ Assert.AreNotEqual (IntPtr.Zero, anchor.Handle, "Handle");
+ }
+
+ [Test]
+ public void ARDeviceAnchor_Identifier ()
+ {
+ using var anchor = new ARDeviceAnchor ();
+ var id = anchor.Identifier;
+ Assert.IsNotNull (id.ToString ());
+ }
+
+ [Test]
+ public void ARDeviceAnchor_TrackingState ()
+ {
+ using var anchor = new ARDeviceAnchor ();
+ var state = anchor.TrackingState;
+ Assert.That ((long) state, Is.GreaterThanOrEqualTo (0).And.LessThanOrEqualTo (2),
+ "TrackingState should be a valid enum value");
+ }
+
+ [Test]
+ public void ARDeviceAnchor_OriginFromAnchorTransform ()
+ {
+ using var anchor = new ARDeviceAnchor ();
+ var transform = anchor.OriginFromAnchorTransform;
+ // Verify the P/Invoke returns valid (finite) values — a freshly created
+ // device anchor returns all zeros before being populated by world tracking.
+ Assert.That (float.IsFinite (transform.M11), "M11 is finite");
+ Assert.That (float.IsFinite (transform.M22), "M22 is finite");
+ Assert.That (float.IsFinite (transform.M33), "M33 is finite");
+ Assert.That (float.IsFinite (transform.M44), "M44 is finite");
+ }
+
+ [Test]
+ public void ARDeviceAnchor_Timestamp ()
+ {
+ using var anchor = new ARDeviceAnchor ();
+ var timestamp = anchor.Timestamp;
+ // Freshly created anchor - timestamp should be a non-negative value
+ Assert.That (timestamp, Is.GreaterThanOrEqualTo (0.0), "Timestamp");
+ }
+
+ [Test]
+ public void ARDeviceAnchor_IsTracked ()
+ {
+ using var anchor = new ARDeviceAnchor ();
+ // Just verify the P/Invoke doesn't crash
+ var tracked = anchor.IsTracked;
+ Assert.IsNotNull (tracked.ToString ());
+ }
+
+ [Test]
+ public void ARDeviceAnchor_Dispose ()
+ {
+ var anchor = new ARDeviceAnchor ();
+ Assert.AreNotEqual (IntPtr.Zero, anchor.Handle, "Handle before dispose");
+ anchor.Dispose ();
+ Assert.That (anchor.Handle, Is.EqualTo (NativeHandle.Zero), "Handle after dispose");
+ }
+
+ #endregion
+
+ #region ARError
+
+ [Test]
+ public void ARError_ErrorDomain ()
+ {
+ var domain = ARError.ErrorDomain;
+ Assert.IsNotNull (domain, "ErrorDomain");
+ Assert.AreNotEqual (0, domain!.Length, "ErrorDomain.Length");
+ }
+
+ #endregion
+
+ #region ARSession
+
+ [Test]
+ public void ARSession_SetDataProviderStateChangeHandler_Null ()
+ {
+ // We can't create an ARSession without an ARDevice, but we can verify
+ // that the delegate type and handler machinery compile and work.
+ // This is a compile-time verification that the delegate signature is correct.
+ ARSession.DataProviderStateChangeHandler? handler = null;
+ Assert.IsNull (handler);
+ }
+
+ #endregion
+
+ #region Enum values
+
+ [Test]
+ public void ARAuthorizationType_Flags ()
+ {
+ Assert.AreEqual ((ulong) 0, (ulong) ARAuthorizationType.None, "None");
+ Assert.AreEqual ((ulong) 1, (ulong) ARAuthorizationType.HandTracking, "HandTracking");
+ Assert.AreEqual ((ulong) 2, (ulong) ARAuthorizationType.WorldSensing, "WorldSensing");
+ Assert.AreEqual ((ulong) 8, (ulong) ARAuthorizationType.CameraAccess, "CameraAccess");
+ }
+
+ [Test]
+ public void ARDataProviderState_Values ()
+ {
+ Assert.AreEqual (0, (int) ARDataProviderState.Initialized, "Initialized");
+ Assert.AreEqual (1, (int) ARDataProviderState.Running, "Running");
+ Assert.AreEqual (2, (int) ARDataProviderState.Paused, "Paused");
+ Assert.AreEqual (3, (int) ARDataProviderState.Stopped, "Stopped");
+ }
+
+ [Test]
+ public void ARSessionErrorCode_Values ()
+ {
+ Assert.AreEqual (100, (int) ARSessionErrorCode.DataProviderNotAuthorized, "DataProviderNotAuthorized");
+ Assert.AreEqual (101, (int) ARSessionErrorCode.DataProviderFailedToRun, "DataProviderFailedToRun");
+ }
+
+ [Test]
+ public void ARWorldTrackingErrorCode_Values ()
+ {
+ Assert.AreEqual (200, (int) ARWorldTrackingErrorCode.AddAnchorFailed, "AddAnchorFailed");
+ Assert.AreEqual (201, (int) ARWorldTrackingErrorCode.AnchorMaxLimitReached, "AnchorMaxLimitReached");
+ Assert.AreEqual (202, (int) ARWorldTrackingErrorCode.RemoveAnchorFailed, "RemoveAnchorFailed");
+ }
+
+ [Test]
+ public void ARDeviceAnchorQueryStatus_Values ()
+ {
+ Assert.AreEqual (0, (int) ARDeviceAnchorQueryStatus.Success, "Success");
+ Assert.AreEqual (1, (int) ARDeviceAnchorQueryStatus.Failure, "Failure");
+ }
+
+ [Test]
+ public void ARDeviceAnchorTrackingState_Values ()
+ {
+ Assert.AreEqual (0, (int) ARDeviceAnchorTrackingState.Untracked, "Untracked");
+ Assert.AreEqual (1, (int) ARDeviceAnchorTrackingState.OrientationTracked, "OrientationTracked");
+ Assert.AreEqual (2, (int) ARDeviceAnchorTrackingState.Tracked, "Tracked");
+ }
+
+ [Test]
+ public void ARAuthorizationStatus_Values ()
+ {
+ Assert.AreEqual (0, (int) ARAuthorizationStatus.NotDetermined, "NotDetermined");
+ Assert.AreEqual (1, (int) ARAuthorizationStatus.Allowed, "Allowed");
+ Assert.AreEqual (2, (int) ARAuthorizationStatus.Denied, "Denied");
+ }
+
+ #endregion
+ }
+}
+
+#endif // __MACOS__
diff --git a/tests/monotouch-test/ARKit/ARPlaneGeometryTest.cs b/tests/monotouch-test/ARKit/ARPlaneGeometryTest.cs
index 7faf0ea2ae5e..0cc8f0f2f71d 100644
--- a/tests/monotouch-test/ARKit/ARPlaneGeometryTest.cs
+++ b/tests/monotouch-test/ARKit/ARPlaneGeometryTest.cs
@@ -7,7 +7,7 @@
// Copyright 2018 Microsoft. All rights reserved.
//
-#if HAS_ARKIT
+#if HAS_ARKIT && !__MACOS__
using System.Threading.Tasks;
using ARKit;
diff --git a/tests/monotouch-test/ARKit/ARPointCloudTest.cs b/tests/monotouch-test/ARKit/ARPointCloudTest.cs
index f3a1bb31f5e4..4688ff923c9d 100644
--- a/tests/monotouch-test/ARKit/ARPointCloudTest.cs
+++ b/tests/monotouch-test/ARKit/ARPointCloudTest.cs
@@ -7,7 +7,7 @@
// Copyright 2017 Microsoft. All rights reserved.
//
-#if HAS_ARKIT
+#if HAS_ARKIT && !__MACOS__
using System.Threading.Tasks;
using ARKit;
diff --git a/tests/monotouch-test/ARKit/ARReferenceObjectTest.cs b/tests/monotouch-test/ARKit/ARReferenceObjectTest.cs
index b4e1e373fbbd..0ff0e0bd0bf0 100644
--- a/tests/monotouch-test/ARKit/ARReferenceObjectTest.cs
+++ b/tests/monotouch-test/ARKit/ARReferenceObjectTest.cs
@@ -7,7 +7,7 @@
// Copyright 2018 Microsoft. All rights reserved.
//
-#if HAS_ARKIT
+#if HAS_ARKIT && !__MACOS__
using ARKit;
using Xamarin.Utils;
diff --git a/tests/monotouch-test/ARKit/ARSkeleton2DTest.cs b/tests/monotouch-test/ARKit/ARSkeleton2DTest.cs
index 8155bf910b39..7b512a56f567 100644
--- a/tests/monotouch-test/ARKit/ARSkeleton2DTest.cs
+++ b/tests/monotouch-test/ARKit/ARSkeleton2DTest.cs
@@ -7,7 +7,7 @@
// Copyright 2019 Microsoft. All rights reserved.
//
-#if HAS_ARKIT
+#if HAS_ARKIT && !__MACOS__
using System.Threading.Tasks;
using ARKit;
diff --git a/tests/monotouch-test/ARKit/ARSkeleton3DTest.cs b/tests/monotouch-test/ARKit/ARSkeleton3DTest.cs
index b0c41d273dd0..e9baefd41ad6 100644
--- a/tests/monotouch-test/ARKit/ARSkeleton3DTest.cs
+++ b/tests/monotouch-test/ARKit/ARSkeleton3DTest.cs
@@ -7,7 +7,7 @@
// Copyright 2019 Microsoft. All rights reserved.
//
-#if HAS_ARKIT
+#if HAS_ARKIT && !__MACOS__
using System.Threading.Tasks;
using ARKit;
diff --git a/tests/monotouch-test/ARKit/ARSkeletonTest.cs b/tests/monotouch-test/ARKit/ARSkeletonTest.cs
index 28d6eddd37c2..ab4421632f4f 100644
--- a/tests/monotouch-test/ARKit/ARSkeletonTest.cs
+++ b/tests/monotouch-test/ARKit/ARSkeletonTest.cs
@@ -1,4 +1,4 @@
-#if HAS_ARKIT
+#if HAS_ARKIT && !__MACOS__
using System.Threading.Tasks;
using ARKit;
diff --git a/tests/xtro-sharpie/api-annotations-dotnet/macOS-ARKit.ignore b/tests/xtro-sharpie/api-annotations-dotnet/macOS-ARKit.ignore
new file mode 100644
index 000000000000..b6ba7f5da212
--- /dev/null
+++ b/tests/xtro-sharpie/api-annotations-dotnet/macOS-ARKit.ignore
@@ -0,0 +1,40 @@
+#
+# OS_OBJECT_DECL protocols - these are ObjC protocol declarations generated
+# by the OS_OBJECT_DECL macro for the C API types. They are bound as C#
+# classes (not protocols) following the same pattern as Network and Security.
+#
+!missing-protocol! OS_ar_anchor not bound
+!missing-protocol! OS_ar_authorization_result not bound
+!missing-protocol! OS_ar_authorization_results not bound
+!missing-protocol! OS_ar_data_provider not bound
+!missing-protocol! OS_ar_data_providers not bound
+!missing-protocol! OS_ar_device not bound
+!missing-protocol! OS_ar_device_anchor not bound
+!missing-protocol! OS_ar_error not bound
+!missing-protocol! OS_ar_session not bound
+!missing-protocol! OS_ar_strings not bound
+!missing-protocol! OS_ar_trackable_anchor not bound
+!missing-protocol! OS_ar_world_anchor not bound
+!missing-protocol! OS_ar_world_anchors not bound
+!missing-protocol! OS_ar_world_tracking_configuration not bound
+!missing-protocol! OS_ar_world_tracking_provider not bound
+
+#
+# Block-based API variants - we bind the function pointer (_f) variants
+# instead, which are more natural from C#.
+#
+!missing-pinvoke! ar_authorization_results_enumerate_results is not bound
+!missing-pinvoke! ar_data_providers_enumerate_data_providers is not bound
+!missing-pinvoke! ar_session_set_data_provider_state_change_handler is not bound
+
+#
+# Variadic C function - cannot be directly called from C#.
+# Use ar_data_providers_create() + ar_data_providers_add_data_provider() instead.
+#
+!missing-pinvoke! ar_data_providers_create_with_data_providers is not bound
+
+#
+# Manually bound field - xtro does not detect manual bindings
+# that are not processed by bgen.
+#
+!missing-field! ar_error_domain not bound
diff --git a/tests/xtro-sharpie/api-annotations-dotnet/macOS-ARKit.todo b/tests/xtro-sharpie/api-annotations-dotnet/macOS-ARKit.todo
deleted file mode 100644
index 19f0304ca320..000000000000
--- a/tests/xtro-sharpie/api-annotations-dotnet/macOS-ARKit.todo
+++ /dev/null
@@ -1,66 +0,0 @@
-!missing-field! ar_error_domain not bound
-!missing-pinvoke! ar_anchor_get_identifier is not bound
-!missing-pinvoke! ar_anchor_get_origin_from_anchor_transform is not bound
-!missing-pinvoke! ar_anchor_get_timestamp is not bound
-!missing-pinvoke! ar_authorization_result_get_authorization_type is not bound
-!missing-pinvoke! ar_authorization_result_get_status is not bound
-!missing-pinvoke! ar_authorization_results_enumerate_results is not bound
-!missing-pinvoke! ar_authorization_results_enumerate_results_f is not bound
-!missing-pinvoke! ar_authorization_results_get_count is not bound
-!missing-pinvoke! ar_data_provider_get_required_authorization_type is not bound
-!missing-pinvoke! ar_data_provider_get_state is not bound
-!missing-pinvoke! ar_data_providers_add_data_provider is not bound
-!missing-pinvoke! ar_data_providers_add_data_providers is not bound
-!missing-pinvoke! ar_data_providers_create is not bound
-!missing-pinvoke! ar_data_providers_create_with_data_providers is not bound
-!missing-pinvoke! ar_data_providers_enumerate_data_providers is not bound
-!missing-pinvoke! ar_data_providers_enumerate_data_providers_f is not bound
-!missing-pinvoke! ar_data_providers_get_count is not bound
-!missing-pinvoke! ar_data_providers_remove_data_provider is not bound
-!missing-pinvoke! ar_data_providers_remove_data_providers is not bound
-!missing-pinvoke! ar_device_anchor_create is not bound
-!missing-pinvoke! ar_device_anchor_get_identifier is not bound
-!missing-pinvoke! ar_device_anchor_get_origin_from_anchor_transform is not bound
-!missing-pinvoke! ar_device_anchor_get_timestamp is not bound
-!missing-pinvoke! ar_device_anchor_get_tracking_state is not bound
-!missing-pinvoke! ar_device_anchor_is_tracked is not bound
-!missing-pinvoke! ar_error_copy_cf_error is not bound
-!missing-pinvoke! ar_error_get_error_code is not bound
-!missing-pinvoke! ar_release is not bound
-!missing-pinvoke! ar_retain is not bound
-!missing-pinvoke! ar_session_copy_data_providers is not bound
-!missing-pinvoke! ar_session_create_with_device is not bound
-!missing-pinvoke! ar_session_run is not bound
-!missing-pinvoke! ar_session_set_data_provider_state_change_handler is not bound
-!missing-pinvoke! ar_session_set_data_provider_state_change_handler_f is not bound
-!missing-pinvoke! ar_session_stop is not bound
-!missing-pinvoke! ar_trackable_anchor_is_tracked is not bound
-!missing-pinvoke! ar_world_tracking_configuration_create is not bound
-!missing-pinvoke! ar_world_tracking_provider_create is not bound
-!missing-pinvoke! ar_world_tracking_provider_get_required_authorization_type is not bound
-!missing-pinvoke! ar_world_tracking_provider_is_supported is not bound
-!missing-pinvoke! ar_world_tracking_provider_query_device_anchor_at_timestamp is not bound
-!missing-protocol! OS_ar_anchor not bound
-!missing-protocol! OS_ar_authorization_result not bound
-!missing-protocol! OS_ar_authorization_results not bound
-!missing-protocol! OS_ar_data_provider not bound
-!missing-protocol! OS_ar_data_providers not bound
-!missing-protocol! OS_ar_device not bound
-!missing-protocol! OS_ar_device_anchor not bound
-!missing-protocol! OS_ar_error not bound
-!missing-protocol! OS_ar_session not bound
-!missing-protocol! OS_ar_strings not bound
-!missing-protocol! OS_ar_trackable_anchor not bound
-!missing-protocol! OS_ar_world_anchor not bound
-!missing-protocol! OS_ar_world_anchors not bound
-!missing-protocol! OS_ar_world_tracking_configuration not bound
-!missing-protocol! OS_ar_world_tracking_provider not bound
-
-# updated sharpie results
-!missing-enum! ar_authorization_status_t not bound
-!missing-enum! ar_authorization_type_t not bound
-!missing-enum! ar_data_provider_state_t not bound
-!missing-enum! ar_device_anchor_query_status_t not bound
-!missing-enum! ar_device_anchor_tracking_state_t not bound
-!missing-enum! ar_session_error_code_t not bound
-!missing-enum! ar_world_tracking_error_code_t not bound
diff --git a/tools/common/Frameworks.cs b/tools/common/Frameworks.cs
index 3ae4d13d039f..36353f45a153 100644
--- a/tools/common/Frameworks.cs
+++ b/tools/common/Frameworks.cs
@@ -294,6 +294,8 @@ public static Frameworks MacFrameworks {
{ "SecurityUI", "SecurityUI", 15, 4 },
{ "GameSave", "GameSave", 26, 0 },
+
+ { "ARKit", "ARKit", 26, 0 },
};
}
return mac_frameworks;