From 352fa40f5571168e462d5a4c27ae08b6be3f58a1 Mon Sep 17 00:00:00 2001 From: Simon Laux Date: Tue, 4 Mar 2025 23:46:49 +0100 Subject: [PATCH] feat: macOS: add `wry::fetch_all_data_store_identifiers` and `wry::remove_data_store` --- .changes/fetch_all_and_remove_data_store.md | 5 ++ src/error.rs | 3 ++ src/lib.rs | 3 ++ src/wkwebview/data_store.rs | 57 +++++++++++++++++++++ src/wkwebview/mod.rs | 3 ++ 5 files changed, 71 insertions(+) create mode 100644 .changes/fetch_all_and_remove_data_store.md create mode 100644 src/wkwebview/data_store.rs diff --git a/.changes/fetch_all_and_remove_data_store.md b/.changes/fetch_all_and_remove_data_store.md new file mode 100644 index 000000000..dbdc26237 --- /dev/null +++ b/.changes/fetch_all_and_remove_data_store.md @@ -0,0 +1,5 @@ +--- +"wry": patch +--- + +feat: macOS: add `wry::fetch_all_data_store_identifiers` and `wry::remove_data_store` diff --git a/src/error.rs b/src/error.rs index d9e8ef6d7..04818eefe 100644 --- a/src/error.rs +++ b/src/error.rs @@ -71,4 +71,7 @@ pub enum Error { #[error(transparent)] #[cfg(any(target_os = "macos", target_os = "ios"))] UrlPrase(#[from] url::ParseError), + #[cfg(any(target_os = "macos", target_os = "ios"))] + #[error(transparent)] + ObjcNS(#[from] objc2_foundation::NSError), } diff --git a/src/lib.rs b/src/lib.rs index 7ea996c5b..24113360b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1432,6 +1432,9 @@ impl WebViewBuilderExtDarwin for WebViewBuilder<'_> { } } +#[cfg(any(target_os = "macos", target_os = "ios",))] +pub use wkwebview::data_store::{fetch_all_data_store_identifiers, remove_data_store}; + #[cfg(windows)] #[derive(Clone)] pub(crate) struct PlatformSpecificWebViewAttributes { diff --git a/src/wkwebview/data_store.rs b/src/wkwebview/data_store.rs new file mode 100644 index 000000000..301b5625b --- /dev/null +++ b/src/wkwebview/data_store.rs @@ -0,0 +1,57 @@ +use std::ptr::NonNull; + +use block2::RcBlock; +use objc2::MainThreadMarker; +use objc2_foundation::{NSArray, NSError, NSUUID}; +use objc2_web_kit::WKWebsiteDataStore; + +use crate::Error; + +/// Fetches all Data Store Identifiers of this application +/// +/// Needs to run on main thread and needs an event loop to run. +pub fn fetch_all_data_store_identifiers( + cb: impl Fn(Vec<[u8; 16]>) + Send + 'static, +) -> Result<(), Error> { + let block = RcBlock::new(move |stores: NonNull>| { + let uuid_list = unsafe { stores.as_ref() } + .to_vec() + .iter() + .map(|uuid| uuid.as_bytes()) + .collect(); + cb(uuid_list); + }); + + match MainThreadMarker::new() { + Some(mtn) => unsafe { + WKWebsiteDataStore::fetchAllDataStoreIdentifiers(&block, mtn); + Ok(()) + }, + None => Err(Error::NotMainThread), + } +} + +/// Deletes a Data Store by Identifiers +/// +/// Needs to run on main thread and needs an event loop to run. +pub fn remove_data_store( + uuid: &[u8; 16], + cb: impl Fn(Result<(), Error>) + Send + 'static, +) -> Result<(), Error> { + let mtm = MainThreadMarker::new().ok_or(Error::NotMainThread)?; + let identifier = NSUUID::from_bytes(uuid.to_owned()); + + let block = RcBlock::new(move |error: *mut NSError| { + if error.is_null() { + cb(Ok(())) + } else { + cb(Err(unsafe { error.read() }.into())); + } + }); + + unsafe { + WKWebsiteDataStore::removeDataStoreForIdentifier_completionHandler(&identifier, &block, mtm); + } + + Ok(()) +} diff --git a/src/wkwebview/mod.rs b/src/wkwebview/mod.rs index 5f9860f2a..3f252d1f5 100644 --- a/src/wkwebview/mod.rs +++ b/src/wkwebview/mod.rs @@ -2,6 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT +#[cfg(target_os = "macos")] +pub(crate) mod data_store; + mod download; #[cfg(target_os = "macos")] mod drag_drop;