diff --git a/src/ScreenTime/STWebHistory.cs b/src/ScreenTime/STWebHistory.cs
new file mode 100644
index 000000000000..7ac9466bd313
--- /dev/null
+++ b/src/ScreenTime/STWebHistory.cs
@@ -0,0 +1,41 @@
+using System.Diagnostics.CodeAnalysis;
+
+using Foundation;
+
+namespace ScreenTime {
+ public partial class STWebHistory {
+ /// Create a new for the specified bundle identifier.
+ /// The bundle identifier whose web history to retrieve.
+ /// In case of failure, an error describing the failure, otherwise null.
+ /// A new , or null in case of failure.
+ public static STWebHistory? Create (string bundleIdentifier, out NSError? error)
+ {
+ var rv = new STWebHistory (NSObjectFlag.Empty);
+ rv.InitializeHandle (rv._InitWithBundleIdentifier (bundleIdentifier, out error), "initWithBundleIdentifier:error:", false);
+ if (rv.Handle == IntPtr.Zero) {
+ rv.Dispose ();
+ return null;
+ }
+ return rv;
+ }
+
+ /// Create a new for the specified bundle identifier and browsing profile.
+ /// The bundle identifier whose web history to retrieve.
+ /// The identifier for the browsing profile whose web histor to retrieve.
+ /// In case of failure, an error describing the failure, otherwise null.
+ /// A new , or null in case of failure.
+ [SupportedOSPlatform ("ios18.4")]
+ [SupportedOSPlatform ("maccatalyst18.4")]
+ [SupportedOSPlatform ("macos15.4")]
+ public static STWebHistory? Create (string bundleIdentifier, NSString profileIdentifier, out NSError? error)
+ {
+ var rv = new STWebHistory (NSObjectFlag.Empty);
+ rv.InitializeHandle (rv._InitWithBundleIdentifier (bundleIdentifier, profileIdentifier, out error), "initWithBundleIdentifier:profileIdentifier:error:", false);
+ if (rv.Handle == IntPtr.Zero) {
+ rv.Dispose ();
+ return null;
+ }
+ return rv;
+ }
+ }
+}
diff --git a/src/frameworks.sources b/src/frameworks.sources
index 1c537b16ebcb..9b18879867c5 100644
--- a/src/frameworks.sources
+++ b/src/frameworks.sources
@@ -1615,6 +1615,9 @@ SCRIPTINGBRIDGE_SOURCES = \
# ScreenTime
+SCREENTIME_SOURCES = \
+ ScreenTime/STWebHistory.cs \
+
# SearchKit
SEARCHKIT_SOURCES = \
diff --git a/src/screentime.cs b/src/screentime.cs
index 71bcc81adc0e..1cdb53de20e8 100644
--- a/src/screentime.cs
+++ b/src/screentime.cs
@@ -47,11 +47,41 @@ interface STScreenTimeConfigurationObserver {
[iOS (14, 0)]
[MacCatalyst (14, 0)]
[BaseType (typeof (NSObject))]
- [DisableDefaultCtor]
interface STWebHistory {
-
+#if !XAMCORE_5_0
+ [Obsolete ("Use the 'Create' method instead, because there's no way to return an error from a constructor.")]
[Export ("initWithBundleIdentifier:error:")]
NativeHandle Constructor (string bundleIdentifier, [NullAllowed] out NSError error);
+#endif
+
+#if XAMCORE_5_0
+ [Internal]
+#else
+ [Internal, Sealed]
+#endif
+ [Export ("initWithBundleIdentifier:error:")]
+ NativeHandle _InitWithBundleIdentifier (string bundleIdentifier, [NullAllowed] out NSError error);
+
+ // STWebHistoryProfileIdentifier is a strongly typed enum, but Apple doesn't define any values for it, so bind as NSString
+ [iOS (18, 4), MacCatalyst (18, 4), Mac (15, 4)]
+ [Internal]
+ [Export ("initWithBundleIdentifier:profileIdentifier:error:")]
+ NativeHandle _InitWithBundleIdentifier (string bundleIdentifier, [NullAllowed] /* STWebHistoryProfileIdentifier */ NSString profileIdentifier, [NullAllowed] out NSError error);
+
+ // STWebHistoryProfileIdentifier is a strongly typed enum, but Apple doesn't define any values for it, so bind as NSString
+ [iOS (18, 4), MacCatalyst (18, 4), Mac (15, 4)]
+ [Export ("initWithProfileIdentifier:")]
+ NativeHandle Constructor ([NullAllowed] /* STWebHistoryProfileIdentifier */ NSString profileIdentifier);
+
+ [iOS (18, 4), MacCatalyst (18, 4), Mac (15, 4)]
+ [Export ("fetchHistoryDuringInterval:completionHandler:")]
+ [Async]
+ void FetchHistory (NSDateInterval interval, STWebHistoryFetchHistoryCallback completionHandler);
+
+ [iOS (18, 4), MacCatalyst (18, 4), Mac (15, 4)]
+ [Export ("fetchAllHistoryWithCompletionHandler:")]
+ [Async]
+ void FetchHistory (STWebHistoryFetchHistoryCallback completionHandler);
[Export ("deleteHistoryForURL:")]
void DeleteHistory (NSUrl url);
@@ -63,6 +93,8 @@ interface STWebHistory {
void DeleteAllHistory ();
}
+ delegate void STWebHistoryFetchHistoryCallback ([NullAllowed] NSSet urls, [NullAllowed] NSError error);
+
[iOS (14, 0)]
[MacCatalyst (14, 0)]
[BaseType (typeof (UIViewController))]
@@ -89,6 +121,12 @@ interface STWebpageController {
[Export ("setBundleIdentifier:error:")]
bool SetBundleIdentifier (string bundleIdentifier, [NullAllowed] out NSError error);
+
+ // STWebHistoryProfileIdentifier is a strongly typed enum, but Apple doesn't define any values for it, so bind as NSString
+ [iOS (18, 4), MacCatalyst (18, 4), Mac (15, 4)]
+ [Export ("profileIdentifier", ArgumentSemantic.Copy), NullAllowed]
+ /* STWebHistoryProfileIdentifier */
+ NSString ProfileIdentifier { get; set; }
}
}
diff --git a/tests/cecil-tests/ConstructorTest.KnownFailures.cs b/tests/cecil-tests/ConstructorTest.KnownFailures.cs
index 3b8d9fd54b69..5483f0e29e79 100644
--- a/tests/cecil-tests/ConstructorTest.KnownFailures.cs
+++ b/tests/cecil-tests/ConstructorTest.KnownFailures.cs
@@ -145,7 +145,6 @@ public partial class ConstructorTest {
"PencilKit.PKDrawing::.ctor(Foundation.NSData,Foundation.NSError&)",
"Phase.PhaseSoundEvent::.ctor(Phase.PhaseEngine,System.String,Foundation.NSError&)",
"Phase.PhaseSoundEvent::.ctor(Phase.PhaseEngine,System.String,Phase.PhaseMixerParameters,Foundation.NSError&)",
- "ScreenTime.STWebHistory::.ctor(System.String,Foundation.NSError&)",
"ShazamKit.SHCustomCatalog::.ctor(Foundation.NSData,Foundation.NSError&)",
"ShazamKit.SHSignature::.ctor(Foundation.NSData,Foundation.NSError&)",
"SoundAnalysis.SNAudioFileAnalyzer::.ctor(Foundation.NSUrl,Foundation.NSError&)",
diff --git a/tests/cecil-tests/Documentation.KnownFailures.txt b/tests/cecil-tests/Documentation.KnownFailures.txt
index 125a1b01a831..7b7c67595502 100644
--- a/tests/cecil-tests/Documentation.KnownFailures.txt
+++ b/tests/cecil-tests/Documentation.KnownFailures.txt
@@ -35302,10 +35302,14 @@ M:ScreenTime.STScreenTimeConfiguration.EncodeTo(Foundation.NSCoder)
M:ScreenTime.STScreenTimeConfigurationObserver.#ctor(CoreFoundation.DispatchQueue)
M:ScreenTime.STScreenTimeConfigurationObserver.StartObserving
M:ScreenTime.STScreenTimeConfigurationObserver.StopObserving
-M:ScreenTime.STWebHistory.#ctor(System.String,Foundation.NSError@)
+M:ScreenTime.STWebHistory.#ctor(Foundation.NSString)
M:ScreenTime.STWebHistory.DeleteAllHistory
M:ScreenTime.STWebHistory.DeleteHistory(Foundation.NSDateInterval)
M:ScreenTime.STWebHistory.DeleteHistory(Foundation.NSUrl)
+M:ScreenTime.STWebHistory.FetchHistory(Foundation.NSDateInterval,ScreenTime.STWebHistoryFetchHistoryCallback)
+M:ScreenTime.STWebHistory.FetchHistory(ScreenTime.STWebHistoryFetchHistoryCallback)
+M:ScreenTime.STWebHistory.FetchHistoryAsync
+M:ScreenTime.STWebHistory.FetchHistoryAsync(Foundation.NSDateInterval)
M:ScreenTime.STWebpageController.#ctor(System.String,Foundation.NSBundle)
M:ScreenTime.STWebpageController.SetBundleIdentifier(System.String,Foundation.NSError@)
M:ScriptingBridge.ISBApplicationDelegate.EventFailed(System.IntPtr,Foundation.NSError)
@@ -55803,6 +55807,7 @@ P:ScreenCaptureKit.SCWindow.Active
P:ScreenCaptureKit.SCWindow.OnScreen
P:ScreenTime.STScreenTimeConfiguration.EnforcesChildRestrictions
P:ScreenTime.STScreenTimeConfigurationObserver.Configuration
+P:ScreenTime.STWebpageController.ProfileIdentifier
P:ScreenTime.STWebpageController.SuppressUsageRecording
P:ScreenTime.STWebpageController.Url
P:ScreenTime.STWebpageController.UrlIsBlocked
@@ -66856,6 +66861,7 @@ T:ScreenCaptureKit.SCStreamType
T:ScreenTime.STScreenTimeConfiguration
T:ScreenTime.STScreenTimeConfigurationObserver
T:ScreenTime.STWebHistory
+T:ScreenTime.STWebHistoryFetchHistoryCallback
T:ScreenTime.STWebpageController
T:ScriptingBridge.AESendMode
T:ScriptingBridge.ISBApplicationDelegate
diff --git a/tests/monotouch-test/ScreenTime/STWebHistoryTest.cs b/tests/monotouch-test/ScreenTime/STWebHistoryTest.cs
new file mode 100644
index 000000000000..ccfb3a58ebeb
--- /dev/null
+++ b/tests/monotouch-test/ScreenTime/STWebHistoryTest.cs
@@ -0,0 +1,45 @@
+//
+// Unit tests for STWebHistory
+//
+// Authors:
+// Rolf Bjarne Kvinge
+//
+// Copyright 2025 Microsoft Corp. All rights reserved.
+//
+
+#if HAS_SCREENTIME
+
+using System;
+
+using Foundation;
+using ScreenTime;
+
+using NUnit.Framework;
+
+namespace MonoTouchFixtures.ScreenTime {
+
+ [TestFixture]
+ [Preserve (AllMembers = true)]
+ public class STWebHistoryTest {
+
+ [Test]
+ public void Create_WithBundleIdentifier ()
+ {
+ TestRuntime.AssertXcodeVersion (16, 3);
+ using var obj = STWebHistory.Create ("com.xamarin.monotouch-test", out var error);
+ Assert.IsNotNull (obj, "Object");
+ Assert.IsNull (error, "Error");
+ }
+
+ [Test]
+ public void Create_WithBundleIdentifierAndProfile ()
+ {
+ TestRuntime.AssertXcodeVersion (16, 3);
+ using var obj = STWebHistory.Create ("com.xamarin.monotouch-test", (NSString) "profile", out var error);
+ Assert.IsNotNull (obj, "Object");
+ Assert.IsNull (error, "Error");
+ }
+ }
+}
+
+#endif
diff --git a/tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-ScreenTime.todo b/tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-ScreenTime.todo
deleted file mode 100644
index f8cb47795538..000000000000
--- a/tests/xtro-sharpie/api-annotations-dotnet/MacCatalyst-ScreenTime.todo
+++ /dev/null
@@ -1,6 +0,0 @@
-!missing-selector! STWebHistory::initWithBundleIdentifier:profileIdentifier:error: not bound
-!missing-selector! STWebHistory::initWithProfileIdentifier: not bound
-!missing-selector! STWebpageController::profileIdentifier not bound
-!missing-selector! STWebpageController::setProfileIdentifier: not bound
-!missing-selector! STWebHistory::fetchAllHistoryWithCompletionHandler: not bound
-!missing-selector! STWebHistory::fetchHistoryDuringInterval:completionHandler: not bound
diff --git a/tests/xtro-sharpie/api-annotations-dotnet/iOS-ScreenTime.todo b/tests/xtro-sharpie/api-annotations-dotnet/iOS-ScreenTime.todo
deleted file mode 100644
index f8cb47795538..000000000000
--- a/tests/xtro-sharpie/api-annotations-dotnet/iOS-ScreenTime.todo
+++ /dev/null
@@ -1,6 +0,0 @@
-!missing-selector! STWebHistory::initWithBundleIdentifier:profileIdentifier:error: not bound
-!missing-selector! STWebHistory::initWithProfileIdentifier: not bound
-!missing-selector! STWebpageController::profileIdentifier not bound
-!missing-selector! STWebpageController::setProfileIdentifier: not bound
-!missing-selector! STWebHistory::fetchAllHistoryWithCompletionHandler: not bound
-!missing-selector! STWebHistory::fetchHistoryDuringInterval:completionHandler: not bound
diff --git a/tests/xtro-sharpie/api-annotations-dotnet/macOS-ScreenTime.todo b/tests/xtro-sharpie/api-annotations-dotnet/macOS-ScreenTime.todo
deleted file mode 100644
index f8cb47795538..000000000000
--- a/tests/xtro-sharpie/api-annotations-dotnet/macOS-ScreenTime.todo
+++ /dev/null
@@ -1,6 +0,0 @@
-!missing-selector! STWebHistory::initWithBundleIdentifier:profileIdentifier:error: not bound
-!missing-selector! STWebHistory::initWithProfileIdentifier: not bound
-!missing-selector! STWebpageController::profileIdentifier not bound
-!missing-selector! STWebpageController::setProfileIdentifier: not bound
-!missing-selector! STWebHistory::fetchAllHistoryWithCompletionHandler: not bound
-!missing-selector! STWebHistory::fetchHistoryDuringInterval:completionHandler: not bound