Closed songjiachao closed 2 months ago
@songjiachao @FabianLars In my application, I implemented the Android save dialog like this:
https://github.com/mikoto2000/OASIZ_TimeLogger2/commit/aea157f5abab98995a84455a3014b5620be60568
Are there any good ideas for applying this to the save method of the dialog plugin?
In the best case, you just have to duplicate showFilePicker and modify it to your code. Since the rest of the android implementation is a bit buggy though i don't know how good that'll work.
@FabianLars
Thank you for your comment.
I didn't realize that open
was partially supported with Android.
It looks like I can create save
by imitating the code below.
I'll give it a try.
I implemented the part where the save dialog opens and the path is returned, but it seems that in Android, the file is created as soon as the file name is specified in the dialog...
Next, I need to create an Android version of the fs plugin's writeFile, otherwise this function itself will be meaningless.
Since it is necessary to obtain the OutputStream of the file entity from the URI using the code activity.getContentResolver().openOutputStream(uri)
, it is not possible to create a file in the Rust world.
Huh? Isn't there already a function to open a file on an Android device? The implementation of that seems to be helpful.
open used FilePickerUtils.getPathFromUri(activity, uri)
, I got real file path.
I try writeTextFile
with real file path, and I got this error.
E Tauri/Console: File: http://tauri.localhost/assets/index-Bg3l_cvu.js - Line 40 - Msg: Uncaught (in promise) failed to open file at path: /storage/emulated/0/Download/test.txt with error: Permission denied (os error 13)
It seems necessary to do activity.getContentResolver().openOutputStream(uri)
on the Android layer.
We have successfully implemented the minimum version. We will organize the code and create a pull request.
I just temporarily implemented saving image to iOS Photos library. You can use code below before tauri-plugin-dialog
implementing save
. If necessary modify code below to save file to iOS Files
run cargo add cc --build
under src-tauri
to add cc
crate
create ios_file.rs
under src-tauri/src
// src-tauri/src/ios_files.rs
extern "C" {
fn save_photo_to_photos(content: *const u8, length: usize);
}
pub fn save_photo(content: &[u8]) {
unsafe {
save_photo_to_photos(content.as_ptr(), content.len());
}
}
create save_photo.m
under src-tauri/src
// src-tauri/src/save_photo.m
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <Photos/Photos.h>
void save_photo_to_photos(const uint8_t *content, size_t length) {
NSData *imageData = [NSData dataWithBytes:content length:length];
UIImage *image = [UIImage imageWithData:imageData];
if (image == nil) {
NSLog(@"Failed to create image from data");
return;
}
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *request = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (!success) {
NSLog(@"Error saving image to Photos: %@", [error localizedDescription]);
} else {
NSLog(@"Image saved to Photos successfully!");
}
}];
}
compile objective-c code
// src-tauri/build.rs
fn main() {
tauri_build::build();
//
cc::Build::new()
.file("src/save_photo.m")
.compile("libsave_photo.a");
println!("cargo:rustc-link-lib=framework=Photos");
}
use ios_files::save_photo
& register save_image_to_photos
with tauri command
// src-tauri/src/lib.rs
// ...
#[cfg(target_os = "ios")]
mod ios_files;
#[cfg(target_os = "ios")]
#[tauri::command]
fn save_image_to_photos(content: Vec<u8>) {
ios_files::save_photo(&content);
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
// ...
.invoke_handler(tauri::generate_handler![save_image_to_photos])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
create src-tauri/Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Need access to your photo library.</string>
</dict>
</plist>
invoke save_image_to_photos
in webview
import { invoke } from '@tauri-apps/api/core';
// ...
const bin = new Uint8Array([]);
invoke('save_image_to_photos', { content: Array.from(bin) });
// ...
I see commits for iOS and Android in the commit history. Is there anything missing or can this be closed?
cc @lucasfernog (your commits)
nice catch, let's close it