C#/Xamarin Maui

[.NET MAUI] CommunityToolkit.Maui - FileSaver, FolderPicker

kjun.kr 2023. 3. 5. 00:20
728x90
728x170

파일 저장시 필요한 FileSaver 와 폴더 선택에 필요한 FolderPicker 를 알아봅니다.

iOS 는 정상 동작하나 파일명이 guid 형태로 저장됩니다.
(text.txt 로 파일이름을 주었지만 guid.txt 로 저장됩니다.)

Android 에서는 Android12 버전에서만 정상 동작합니다.
Android13 버전에서는 Storage 권한을 득하지 못해 정상적으로 동작하지 않습니다.(이슈로 올라와 있음)
시뮬레이터 Android12 로 하나 만들어 테스트 했습니다.

MauiProgram.cs

using CommunityToolkit.Maui;
using CommunityToolkit.Maui.Storage;

namespace Maui.ToolKitMaui
{
    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                .UseMauiCommunityToolkit()
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                    fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
                });

            // FileSaver 주입
            builder.Services.AddSingleton<IFileSaver>(FileSaver.Default);
            builder.Services.AddTransient<MainPage>();

            return builder.Build();
        }
    }
}

MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    x:Class="Maui.ToolKitMaui.MainPage"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:animations="clr-namespace:Maui.ToolKitMaui.Animations"
    xmlns:mct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
    BackgroundColor="White">

    <ScrollView>
        <VerticalStackLayout
            Padding="30,0"
            Spacing="15"
            VerticalOptions="Center">
            <Entry
                x:Name="saveEntry"
                BackgroundColor="LightGray"
                Text="Save Content"
                TextColor="Black" />
            <HorizontalStackLayout>
                <Button
                    x:Name="fileButton"
                    Clicked="fileButton_Clicked"
                    HorizontalOptions="Center"
                    Text="Save File" />
                <Label
                    x:Name="savePathLabel"
                    Margin="10,0"
                    TextColor="Black"
                    VerticalTextAlignment="Center" />
            </HorizontalStackLayout>
            <HorizontalStackLayout>
                <Button
                    x:Name="pickButton"
                    Clicked="pickButton_Clicked"
                    HorizontalOptions="Center"
                    Text="Pick Folder" />
                <Label
                    x:Name="pickPathLabel"
                    Margin="10,0"
                    TextColor="Black"
                    VerticalTextAlignment="Center" />
            </HorizontalStackLayout>
        </VerticalStackLayout>
    </ScrollView>

</ContentPage>


MainPage.xaml.cs

using System.Text;

using CommunityToolkit.Maui.Alerts;
using CommunityToolkit.Maui.Core;
using CommunityToolkit.Maui.Storage;

using Font = Microsoft.Maui.Font;

namespace Maui.ToolKitMaui
{
    public partial class MainPage : ContentPage
    {
        IFileSaver fileSaver;
        CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();

        public MainPage(IFileSaver fileSaver)
        {
            InitializeComponent();

            this.fileSaver = fileSaver;

            this.BindingContext = new MainViewModel();

            CheckPermission();
        }

        private async void fileButton_Clicked(object sender, EventArgs e)
        {
            using var stream = new MemoryStream(Encoding.Default.GetBytes(this.saveEntry.Text));

            var result = await this.fileSaver.SaveAsync("test.txt", stream, cancellationTokenSource.Token);

            if (result.IsSuccessful)
            {
                this.savePathLabel.Text = result.FilePath;
            }
        }

        private async void pickButton_Clicked(object sender, EventArgs e)
        {
            var result = await FolderPicker.PickAsync(cancellationTokenSource.Token);

            if (result.IsSuccessful)
            {
                this.pickPathLabel.Text = result.Folder.Path;
            }
        }

        private async void CheckPermission()
        {
            PermissionStatus readStatus = await Permissions.CheckStatusAsync<Permissions.StorageRead>();

            if (readStatus != PermissionStatus.Granted)
            {
                if (Permissions.ShouldShowRationale<Permissions.StorageRead>())
                {
                    await DisplayAlert("Permission", "Need Permissions", "OK");
                }

                var status = await Permissions.RequestAsync<Permissions.StorageRead>();

                if (status != PermissionStatus.Granted)
                {
                    await DisplayAlert("Permission Check", "Need Permissions", "OK");
                    return;
                }

                if (readStatus == PermissionStatus.Granted)
                {
                    PermissionStatus writeStatus = await Permissions.CheckStatusAsync<Permissions.StorageWrite>();

                    if (writeStatus != PermissionStatus.Granted)
                    {
                        if (Permissions.ShouldShowRationale<Permissions.StorageWrite>())
                        {
                            await DisplayAlert("Permission", "Need Permissions", "OK");
                        }

                        status = await Permissions.RequestAsync<Permissions.StorageWrite>();

                        if (status != PermissionStatus.Granted)
                        {
                            await DisplayAlert("Permission Check", "Need Permissions", "OK");
                            return;
                        }
                    }
                }
            }
        }
    }
}


Android 결과

(파일 저장시 test 폴더에 test.txt 파일이 있어 덮어쓰기 하였습니다.)

iOS 결과
(아래 그림처럼 파일 저장 시 test.txt 로 파일명을 주었는데도 guid.txt 로 저장됩니다. 버그인걸까요?;;)


[Source]
https://github.com/kei-soft/KJunBlog/tree/master/Maui.ToolKitMaui

GitHub - kei-soft/KJunBlog

Contribute to kei-soft/KJunBlog development by creating an account on GitHub.

github.com


참고
https://learn.microsoft.com/en-us/dotnet/communitytoolkit/maui/essentials/

Essentials - .NET MAUI Community Toolkit - .NET Community Toolkit

The .NET MAUI Community Toolkit Essentials provides developers with cross-platform APIs for their applications.

learn.microsoft.com

 

728x90
그리드형