MAUI:画像保存の実装(FileSaver)
まずは、MAUIプロジェクトの実装を行います。
CommunityToolkit.MAUI
MAUI側では、CommunityToolkit.MAUIライブラリのFileSaverを利用しました。このライブラリは、各プラットフォームのネイティブなファイル保存機能をラップしたAPIを提供します。
ImageGeneratorプロジェクトに、CommunityToolkit.Mauiをインストールします。ソリューションエクスプローラーのImageGeneratorプロジェクトで右クリックし、メニューから[NuGetパッケージの管理]を選びます。参照タブでCommunityToolkit.Mauiを検索し、インストールします。
なお、最新バージョンは13.0ですが、筆者の作成時のプロジェクトでは、対応していないようで、バージョン12.3をインストールしました。
インストール後、MauiProgram.csで初期化処理を追加します。
using CommunityToolkit.Maui;
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseMauiCommunityToolkit() // 追加
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
});
~中略~
}
}
IHttpClientFactory
今回の実装では、HTTP通信を行うコードが複数あります。HttpClientクラスは、その都度インスタンスを生成すると、ソケットの枯渇などの問題が発生する可能性があります。.NETでは、IHttpClientFactoryを使用してHttpClientインスタンスを管理することが推奨されています。
IHttpClientFactoryを使うと、HttpClientの生成と破棄を任せることができ、インスタンスの問題を気にする必要がなくなります。またDIコンテナに登録することで、アプリケーション全体で安全にHttpClientを使用できます。
HttpClientの登録
CommunityToolkit.MAUIライブラリ同様、NuGetパッケージの管理から、Microsoft.Extensions.Httpパッケージを追加します。それから、MauiProgram.csに、IHttpClientFactoryを登録するコードを追加します。
// 第3回で登録したサービス builder.Services.AddSingleton<IImageGenerationService, OpenAIImageService>(); // HttpClientFactoryの登録 builder.Services.AddHttpClient();
AddHttpClient()を呼び出すことで、IHttpClientFactoryがDIコンテナに登録されます。
実装クラスの作成
MAUIの実装クラスとして、MauiImageSaveServiceクラスをImageGeneratorプロジェクトのServicesフォルダに新規作成します。
using CommunityToolkit.Maui.Storage;
public class MauiImageSaveService(IHttpClientFactory httpClientFactory) : IImageSaveService
{
public string ActionLabel => "保存"; // UI文言の設定 (4)
public async Task<bool> SaveImageAsync(string imageUrl, string fileName, object? jsRuntime = null)
{
// jsRuntimeはMAUI環境では使用しない
try
{
// HttpClientFactoryからHttpClientを取得 (1)
using var httpClient = httpClientFactory.CreateClient();
// 画像データをダウンロード (2)
var imageBytes = await httpClient.GetByteArrayAsync(imageUrl);
// FileSaverを使って保存 (3)
using var stream = new MemoryStream(imageBytes);
var result = await FileSaver.Default.SaveAsync(fileName, stream, default);
return result.IsSuccessful;
}
catch (Exception ex)
{
Console.WriteLine($"画像保存エラー: {ex.Message}");
return false;
}
}
}
IHttpClientFactoryをコンストラクタで受け取り(プライマリコンストラクタ構文)、CreateClientメソッドでHttpClientを取得します(1)。このHttpClientは内部で接続プールが管理され、効率的に再利用されます。GetByteArrayAsyncメソッドで画像URLからバイナリデータをダウンロードし(2)、FileSaverオブジェクトを使ってデバイスに保存します(3)。なお、jsRuntime引数はMAUI環境では使用しません。
また、UIで使う文言プロパティを設定しておきます(4)。
