Skip to content

Commit d8059ba

Browse files
add AppHandle.fetch_data_store_identifiers and AppHandle.remove_data_store (#12900)
* add `AppHandle::fetch_all_data_store_identifiers` and `AppHandle::remove_data_store` * make it run on main thread, so you can call the function from any thread and it works. * changes file * update signature, move functions to RuntimeHandle * add api --------- Co-authored-by: Lucas Nogueira <lucas@tauri.app>
1 parent be2e6b8 commit d8059ba

File tree

13 files changed

+286
-11
lines changed

13 files changed

+286
-11
lines changed

.changes/datastore_api.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@tauri-apps/api": minor:feat
3+
---
4+
5+
add `AppHandle.fetch_data_store_identifiers` and `AppHandle.remove_data_store` (macOS and iOS only)

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/tauri-runtime-wry/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ rustc-args = ["--cfg", "docsrs"]
1717
rustdoc-args = ["--cfg", "docsrs"]
1818

1919
[dependencies]
20-
wry = { version = "0.50.3", default-features = false, features = [
20+
wry = { version = "0.50.4", default-features = false, features = [
2121
"drag-drop",
2222
"protocol",
2323
"os-webview",

crates/tauri-runtime-wry/src/lib.rs

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ use tao::platform::windows::{WindowBuilderExtWindows, WindowExtWindows};
4040
use webview2_com::FocusChangedEventHandler;
4141
#[cfg(windows)]
4242
use windows::Win32::Foundation::HWND;
43-
#[cfg(any(target_os = "macos", target_os = "ios"))]
44-
use wry::WebViewBuilderExtDarwin;
4543
#[cfg(windows)]
4644
use wry::WebViewBuilderExtWindows;
45+
#[cfg(any(target_os = "macos", target_os = "ios"))]
46+
use wry::{WebViewBuilderExtDarwin, WebViewExtDarwin};
4747

4848
use tao::{
4949
dpi::{
@@ -1180,11 +1180,15 @@ unsafe impl Send for GtkBox {}
11801180
pub struct SendRawWindowHandle(pub raw_window_handle::RawWindowHandle);
11811181
unsafe impl Send for SendRawWindowHandle {}
11821182

1183-
#[cfg(target_os = "macos")]
1184-
#[derive(Debug, Clone)]
11851183
pub enum ApplicationMessage {
1184+
#[cfg(target_os = "macos")]
11861185
Show,
1186+
#[cfg(target_os = "macos")]
11871187
Hide,
1188+
#[cfg(any(target_os = "macos", target_os = "ios"))]
1189+
FetchDataStoreIdentifiers(Box<dyn FnOnce(Vec<[u8; 16]>) + Send + 'static>),
1190+
#[cfg(any(target_os = "macos", target_os = "ios"))]
1191+
RemoveDataStore([u8; 16], Box<dyn FnOnce(Result<()>) + Send + 'static>),
11881192
}
11891193

11901194
pub enum WindowMessage {
@@ -1347,7 +1351,6 @@ pub enum Message<T: 'static> {
13471351
#[cfg(target_os = "macos")]
13481352
SetActivationPolicy(ActivationPolicy),
13491353
RequestExit(i32),
1350-
#[cfg(target_os = "macos")]
13511354
Application(ApplicationMessage),
13521355
Window(WindowId, WindowMessage),
13531356
Webview(WindowId, WebviewId, WebviewMessage),
@@ -2507,6 +2510,29 @@ impl<T: UserEvent> RuntimeHandle<T> for WryHandle<T> {
25072510
{
25082511
dispatch(f)
25092512
}
2513+
2514+
#[cfg(any(target_os = "macos", target_os = "ios"))]
2515+
fn fetch_data_store_identifiers<F: FnOnce(Vec<[u8; 16]>) + Send + 'static>(
2516+
&self,
2517+
cb: F,
2518+
) -> Result<()> {
2519+
send_user_message(
2520+
&self.context,
2521+
Message::Application(ApplicationMessage::FetchDataStoreIdentifiers(Box::new(cb))),
2522+
)
2523+
}
2524+
2525+
#[cfg(any(target_os = "macos", target_os = "ios"))]
2526+
fn remove_data_store<F: FnOnce(Result<()>) + Send + 'static>(
2527+
&self,
2528+
uuid: [u8; 16],
2529+
cb: F,
2530+
) -> Result<()> {
2531+
send_user_message(
2532+
&self.context,
2533+
Message::Application(ApplicationMessage::RemoveDataStore(uuid, Box::new(cb))),
2534+
)
2535+
}
25102536
}
25112537

25122538
impl<T: UserEvent> Wry<T> {
@@ -2923,14 +2949,29 @@ fn handle_user_message<T: UserEvent>(
29232949
event_loop.set_activation_policy_at_runtime(tao_activation_policy(activation_policy))
29242950
}
29252951
Message::RequestExit(_code) => panic!("cannot handle RequestExit on the main thread"),
2926-
#[cfg(target_os = "macos")]
29272952
Message::Application(application_message) => match application_message {
2953+
#[cfg(target_os = "macos")]
29282954
ApplicationMessage::Show => {
29292955
event_loop.show_application();
29302956
}
2957+
#[cfg(target_os = "macos")]
29312958
ApplicationMessage::Hide => {
29322959
event_loop.hide_application();
29332960
}
2961+
#[cfg(any(target_os = "macos", target_os = "ios"))]
2962+
ApplicationMessage::FetchDataStoreIdentifiers(cb) => {
2963+
if let Err(e) = WebView::fetch_data_store_identifiers(cb) {
2964+
// this shouldn't ever happen because we're running on the main thread
2965+
// but let's be safe and warn here
2966+
log::error!("failed to fetch data store identifiers: {e}");
2967+
}
2968+
}
2969+
#[cfg(any(target_os = "macos", target_os = "ios"))]
2970+
ApplicationMessage::RemoveDataStore(uuid, cb) => {
2971+
WebView::remove_data_store(&uuid, move |res| {
2972+
cb(res.map_err(|_| Error::FailedToRemoveDataStore))
2973+
})
2974+
}
29342975
},
29352976
Message::Window(id, window_message) => {
29362977
let w = windows.0.borrow().get(&id).map(|w| {

crates/tauri-runtime/src/lib.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ pub enum Error {
182182
InvalidProxyUrl,
183183
#[error("window not found")]
184184
WindowNotFound,
185+
#[cfg(any(target_os = "macos", target_os = "ios"))]
186+
#[error("failed to remove data store")]
187+
FailedToRemoveDataStore,
185188
}
186189

187190
/// Result type.
@@ -338,6 +341,21 @@ pub trait RuntimeHandle<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'st
338341
fn run_on_android_context<F>(&self, f: F)
339342
where
340343
F: FnOnce(&mut jni::JNIEnv, &jni::objects::JObject, &jni::objects::JObject) + Send + 'static;
344+
345+
#[cfg(any(target_os = "macos", target_os = "ios"))]
346+
#[cfg_attr(docsrs, doc(cfg(any(target_os = "macos", target_os = "ios"))))]
347+
fn fetch_data_store_identifiers<F: FnOnce(Vec<[u8; 16]>) + Send + 'static>(
348+
&self,
349+
cb: F,
350+
) -> Result<()>;
351+
352+
#[cfg(any(target_os = "macos", target_os = "ios"))]
353+
#[cfg_attr(docsrs, doc(cfg(any(target_os = "macos", target_os = "ios"))))]
354+
fn remove_data_store<F: FnOnce(Result<()>) + Send + 'static>(
355+
&self,
356+
uuid: [u8; 16],
357+
cb: F,
358+
) -> Result<()>;
341359
}
342360

343361
pub trait EventLoopProxy<T: UserEvent>: Debug + Clone + Send + Sync {

crates/tauri/build.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ const PLUGINS: &[(&str, &[(&str, bool)])] = &[
152152
("identifier", true),
153153
("app_show", false),
154154
("app_hide", false),
155+
("fetch_data_store_identifiers", false),
156+
("remove_data_store", false),
155157
("default_window_icon", false),
156158
("set_app_theme", false),
157159
],

crates/tauri/permissions/app/autogenerated/reference.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,32 @@ Denies the default_window_icon command without any pre-configured scope.
9797
<tr>
9898
<td>
9999

100+
`core:app:allow-fetch-data-store-identifiers`
101+
102+
</td>
103+
<td>
104+
105+
Enables the fetch_data_store_identifiers command without any pre-configured scope.
106+
107+
</td>
108+
</tr>
109+
110+
<tr>
111+
<td>
112+
113+
`core:app:deny-fetch-data-store-identifiers`
114+
115+
</td>
116+
<td>
117+
118+
Denies the fetch_data_store_identifiers command without any pre-configured scope.
119+
120+
</td>
121+
</tr>
122+
123+
<tr>
124+
<td>
125+
100126
`core:app:allow-identifier`
101127

102128
</td>
@@ -149,6 +175,32 @@ Denies the name command without any pre-configured scope.
149175
<tr>
150176
<td>
151177

178+
`core:app:allow-remove-data-store`
179+
180+
</td>
181+
<td>
182+
183+
Enables the remove_data_store command without any pre-configured scope.
184+
185+
</td>
186+
</tr>
187+
188+
<tr>
189+
<td>
190+
191+
`core:app:deny-remove-data-store`
192+
193+
</td>
194+
<td>
195+
196+
Denies the remove_data_store command without any pre-configured scope.
197+
198+
</td>
199+
</tr>
200+
201+
<tr>
202+
<td>
203+
152204
`core:app:allow-set-app-theme`
153205

154206
</td>

crates/tauri/scripts/bundle.global.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/tauri/src/app.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,59 @@ impl AppHandle<crate::Wry> {
370370
}
371371
}
372372

373+
#[cfg(target_vendor = "apple")]
374+
impl<R: Runtime> AppHandle<R> {
375+
/// Fetches all Data Store Indentifiers by this app
376+
///
377+
/// Needs to be called from Main Thread
378+
pub async fn fetch_data_store_identifiers(&self) -> crate::Result<Vec<[u8; 16]>> {
379+
use std::sync::Mutex;
380+
381+
let (tx, rx) = tokio::sync::oneshot::channel::<Result<Vec<[u8; 16]>, tauri_runtime::Error>>();
382+
let lock: Arc<Mutex<Option<_>>> = Arc::new(Mutex::new(Some(tx)));
383+
let runtime_handle = self.runtime_handle.clone();
384+
385+
self.run_on_main_thread(move || {
386+
let cloned_lock = lock.clone();
387+
if let Err(err) = runtime_handle.fetch_data_store_identifiers(move |ids| {
388+
if let Some(tx) = cloned_lock.lock().unwrap().take() {
389+
let _ = tx.send(Ok(ids));
390+
}
391+
}) {
392+
if let Some(tx) = lock.lock().unwrap().take() {
393+
let _ = tx.send(Err(err));
394+
}
395+
}
396+
})?;
397+
398+
rx.await?.map_err(Into::into)
399+
}
400+
/// Deletes a Data Store of this app
401+
///
402+
/// Needs to be called from Main Thread
403+
pub async fn remove_data_store(&self, uuid: [u8; 16]) -> crate::Result<()> {
404+
use std::sync::Mutex;
405+
406+
let (tx, rx) = tokio::sync::oneshot::channel::<Result<(), tauri_runtime::Error>>();
407+
let lock: Arc<Mutex<Option<_>>> = Arc::new(Mutex::new(Some(tx)));
408+
let runtime_handle = self.runtime_handle.clone();
409+
410+
self.run_on_main_thread(move || {
411+
let cloned_lock = lock.clone();
412+
if let Err(err) = runtime_handle.remove_data_store(uuid, move |result| {
413+
if let Some(tx) = cloned_lock.lock().unwrap().take() {
414+
let _ = tx.send(result);
415+
}
416+
}) {
417+
if let Some(tx) = lock.lock().unwrap().take() {
418+
let _ = tx.send(Err(err));
419+
}
420+
}
421+
})?;
422+
rx.await?.map_err(Into::into)
423+
}
424+
}
425+
373426
impl<R: Runtime> Clone for AppHandle<R> {
374427
fn clone(&self) -> Self {
375428
Self {

crates/tauri/src/app/plugin.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,27 @@ pub fn app_hide<R: Runtime>(app: AppHandle<R>) -> crate::Result<()> {
4646
Ok(())
4747
}
4848

49+
#[command(root = "crate")]
50+
#[allow(unused_variables)]
51+
pub async fn fetch_data_store_identifiers<R: Runtime>(
52+
app: AppHandle<R>,
53+
) -> crate::Result<Vec<[u8; 16]>> {
54+
#[cfg(target_vendor = "apple")]
55+
return app.fetch_data_store_identifiers().await;
56+
#[cfg(not(target_vendor = "apple"))]
57+
return Ok(Vec::new());
58+
}
59+
60+
#[command(root = "crate")]
61+
#[allow(unused_variables)]
62+
pub async fn remove_data_store<R: Runtime>(app: AppHandle<R>, uuid: [u8; 16]) -> crate::Result<()> {
63+
#[cfg(target_vendor = "apple")]
64+
app.remove_data_store(uuid).await?;
65+
#[cfg(not(target_vendor = "apple"))]
66+
let _ = uuid;
67+
Ok(())
68+
}
69+
4970
#[command(root = "crate")]
5071
pub fn default_window_icon<R: Runtime>(
5172
webview: Webview<R>,
@@ -71,6 +92,8 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
7192
identifier,
7293
app_show,
7394
app_hide,
95+
fetch_data_store_identifiers,
96+
remove_data_store,
7497
default_window_icon,
7598
set_app_theme,
7699
])

0 commit comments

Comments
 (0)