Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] SecureStorage.GetOrSetAsync(key, value?) #27966

Open
scarletquasar opened this issue Feb 21, 2025 · 0 comments
Open

[Feature] SecureStorage.GetOrSetAsync(key, value?) #27966

scarletquasar opened this issue Feb 21, 2025 · 0 comments
Labels
area-essentials Essentials: Device, Display, Connectivity, Secure Storage, Sensors, App Info essentials-secure-storage proposal/open t/enhancement ☀️ New feature or request
Milestone

Comments

@scarletquasar
Copy link

scarletquasar commented Feb 21, 2025

Description

An interesting way to get values would be GetOrSetAsync, like we have in IMemoryCache from ASP.NET, currently, this functionality could also be chained in a task array to properly setup values in function like OnInitializedAsync from blazor (using hybrid), like the example:

protected override async Task OnInitializedAsync() {
        var tasks = new List<Task>
        {
            SecureStorage.Default.GetOrSetAsync("user_email", ExternalBackendService.GetUserEmail()),
            SecureStorage.Default.GetOrSetAsync("user_id", ExternalBackendService.GetUserId()),
        };

       var result = await Task.WhenAll(tasks);
       SomeStateFunction(result);
}

That would be a pretty cool advantage over:

protected override async Task OnInitializedAsync() {
        var userEmail = await SecureStorage.Default.GetAsync("user_email");
        var userId = await SecureStorage.Default.GetAsync("user_id");

        if (userEmail is null)
        {
            var thisUserEmail = ExternalBackendService.GetUserEmail();
            await SecureStorage.Default.SetAsync("user_email", thisUserEmail);
            userEmail = thisUserEmail;
        }
        
        if (userId is null)
        {
            var thisUserId = ExternalBackendService.GetUserIdl();
            await SecureStorage.Default.SetAsync("user_email", thisUserId);
            userId = thisUserId;
        }
       SomeStateFunction(userEmail);
       SomeOtherStateFunction(userId);
}

Public API Changes

string result = await SecureStorage.[Profile].GetOrSetAsync("key", "value"); //New Api

Internally example application (could be used as an extension):

public static async Task<string> GetOrSetAsync(string key, string defaultValue) 
{
       // Throwing only "key", not "defaultValue", since the default variable can come
       // from a dynamic configuration source and can be null in some occasions, making
       // the same behavior as "GetAsync"
      ArgumentException.ThrowIfNull(key, nameof(key));
      
     var existingValue = await SecureStorage.Current.GetAsync(key);

     if (existingValue == null)
     {
          await SecureStorage.Current.SetAsync(key, defaultValue);
          return defaultValue;
     }
    
    return existingValue;
}

This implementation could be improved by changing the internal default SecureStorageImplementation to automatically support that method by creating the native PlatformGetOrSetAsync binding to programatically execute the operations closer to the providers.

Intended Use-Case

Currently, this situation can be achieved by the creation of a helper method, or even an external library that can be used across codebases. I believe that with the correct implementation across native platforms, this functionality can grant atomicity to specific process, ease the internal development process for the final user (such as the example I mentioned where it could be easily used with Task.WhenAll.

The real motivation besides the real improvements that the function can bring, was the open minded situation where the MAUI project stills right now - that I found by reading some proposal issues along the time, like the one where I found the following comment, I am even inclinated to contribute myself to make these things happen as possible.

Image

@jfversluis jfversluis added t/enhancement ☀️ New feature or request area-essentials Essentials: Device, Display, Connectivity, Secure Storage, Sensors, App Info essentials-secure-storage labels Feb 22, 2025
@jfversluis jfversluis added this to the Backlog milestone Feb 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-essentials Essentials: Device, Display, Connectivity, Secure Storage, Sensors, App Info essentials-secure-storage proposal/open t/enhancement ☀️ New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants