首页 > 其他分享 >MauiBlazor iOS端多选照片以及显示本地照片

MauiBlazor iOS端多选照片以及显示本地照片

时间:2023-11-25 14:33:45浏览次数:35  
标签:MauiBlazor urlSchemeTask string await iOS 照片 var new

安卓端参考之前这篇文章:https://www.cnblogs.com/wecareu/p/17855415.html

iOS端,目前Maui提供的原生接口是MediaPicker 应该对应调用的是iOS原生的UIIMagePicker, 效果也不错,但是一次只能选择单张照片

在ios14以后,苹果推出了新的PHPickerViewController,支持多选照片,UI以弹窗的形式出现,效果十分不错。

 

1. 在Platform-iOS里新建IOSPhotoPIckerService.cs, 由于PHPickerViewController是新添加的,所以别忘记引进using PhotosUI;添加如下代码:

[assembly: Dependency(typeof(IOSPhotoPickerService))]
namespace AndroidPhotoPicker.Platforms.iOS
{
    public class IOSPhotoPickerService : IPhotoPickerService
    {
        class PPD : PHPickerViewControllerDelegate
        {
            public Action<PHPickerResult[]> CompletedHandler { get; set; }

            public override void DidFinishPicking(PHPickerViewController picker, PHPickerResult[] results) =>
                CompletedHandler?.Invoke(results?.Length > 0 ? results : null);
        }

        //TaskCompletionSource<Dictionary<string, string>> taskCompletionSource;
        //UIImagePickerController imagePicker;
        PHPickerViewController picPicker;

        async Task<Dictionary<string, string>> IPhotoPickerService.GetImageByIntent()
        {
            var dic = new Dictionary<string, string>();       
            picPicker = new PHPickerViewController(new PHPickerConfiguration
            {
                Filter = PHPickerFilter.ImagesFilter,
                SelectionLimit = 3,
                PreferredAssetRepresentationMode = PHPickerConfigurationAssetRepresentationMode.Automatic,
                
            });
            var window = UIApplication.SharedApplication.KeyWindow;
            var vc = window.RootViewController;
            while (vc.PresentedViewController != null)
            {
                vc = vc.PresentedViewController;
            }
            var tcs = new TaskCompletionSource<(List<string>, List<string>)>();

            picPicker.Delegate = new PPD
            {
                CompletedHandler = async res =>
                {
                    var resultd = await PickerResultsToMediaFile(res);
                    tcs.TrySetResult(resultd);
                }
            };
            await vc.PresentViewControllerAsync(picPicker, true);
            var resultTask = await tcs.Task;
            //var result = await resultTask;
            //var result = resultTask.Item1;
            //string base64String = Convert.ToBase64String(result);
            //var filename = resultTask.Item2;
            var base64Strings = resultTask.Item1;
            var filenames = resultTask.Item2;

            for (int i = 0; i < base64Strings.Count; i++)
            {
                dic.Add(filenames[i], base64Strings[i]);
            }

            await vc.DismissViewControllerAsync(true);
            picPicker?.Dispose();
            //return result;
            return dic;
        }
        private async Task<(List<string>, List<string>)> PickerResultsToMediaFile(PHPickerResult[] res)
        {
            var results = new List<string>();
            List<string> stringList = new List<string>();
            var tcs = new TaskCompletionSource<NSObject>();
            if (res != null)
            {
                foreach (var item in res)
                {
                    try
                    {
                        var provider = item.ItemProvider;
                        var suggestedName = provider.SuggestedName;
                        var identifiers = provider?.RegisteredTypeIdentifiers;

                        var identifier = (identifiers?.Any(i => i.StartsWith(UTType.LivePhoto)) ?? false)
                            && (identifiers?.Contains(UTType.JPEG) ?? false)
                            ? identifiers?.FirstOrDefault(i => i == UTType.JPEG)
                            : identifiers?.FirstOrDefault();
                        if (string.IsNullOrWhiteSpace(identifier))
                            continue;
                        var timestamp = DateTime.UtcNow.Ticks;
                        var fileName = $"{timestamp}{provider?.SuggestedName}.{GetTag(identifier, UTType.TagClassFilenameExtension)}";
                        stringList.Add(fileName);
                        var stream = (await provider.LoadDataRepresentationAsync(identifier))?.AsStream();
                        string tempFolderPath = Path.GetTempPath();
                        string filePath = Path.Combine(tempFolderPath, fileName);
                        using (FileStream fs = new FileStream(filePath, FileMode.Create))
                        {
                            stream.CopyTo(fs);
                            results.Add(filePath);
                            Console.WriteLine(filePath);
                        }

                    }
                    catch (Exception)
                    {
                        continue;
                    }
                }
            }
            
            return (results, stringList);
        }
        protected internal static string GetTag(string identifier, string tagClass)
        => UTType.CopyAllTags(identifier, tagClass)?.FirstOrDefault();

    }
}

 

2. 在上一片文章的基础上,我们在MauiProgram.cs里注册iOS的接口:

#if IOS
builder.Services.AddSingleton<IPhotoPickerService, IOSPhotoPickerService>();
#endif

3. 同样在MainPage.xaml.cs里,补上上一篇文章提到的iOS需要的代码:

    void blazorWebView_BlazorWebViewInitializing(System.Object sender, Microsoft.AspNetCore.Components.WebView.BlazorWebViewInitializingEventArgs e)
    {
#if IOS
        e.Configuration.SetUrlSchemeHandler(new MySchemeHandler(), "myfile");
#endif

    }

#if IOS
    private class MySchemeHandler : NSObject, IWKUrlSchemeHandler
    {
        [Export("webView:startURLSchemeTask:")]
        public void StartUrlSchemeTask(WKWebView webView, IWKUrlSchemeTask urlSchemeTask)
        {
            if (urlSchemeTask.Request.Url == null)
            {
                return;
            }

            var path = urlSchemeTask.Request.Url?.Path ?? "";
            if (File.Exists(path))
            {
                byte[] bytes = File.ReadAllBytes(path);
                using var response = new NSHttpUrlResponse(urlSchemeTask.Request.Url, 200, "HTTP/1.1", null);
                urlSchemeTask.DidReceiveResponse(response);
                urlSchemeTask.DidReceiveData(NSData.FromArray(bytes));
                urlSchemeTask.DidFinish();
            }
        }

        [Export("webView:stopURLSchemeTask:")]
        public void StopUrlSchemeTask(WKWebView webView, IWKUrlSchemeTask urlSchemeTask)
        {
        }
#endif

 4. 在Index.razor里,添加如下测试代码:

@page "/"
@using AndroidPhotoPicker.Service

<h1>Hello, world!</h1>

Welcome to your new app.

<button @onclick="GetImageAsync3">添加图片INTENT</button>


@if (_phoneDictionary.Any())
{
    @foreach (var phone in _phoneDictionary)
    {
        <div style="height: 100%; width: 100%;">
            <img src="@phone.Value" style="height:90px;width:90px;object-fit:cover;" />
        </div>
        <div>图片名称: @phone.Key</div>
    }
}

@code{

    [Inject]
    private IPhotoPickerService _photoPickerService { get; set; } //注入服务接口

    private Dictionary<string, string> _phoneDictionary { get; set; } = new Dictionary<string, string>();//图片路径字典
    private async Task GetImageAsync3()
    {
        var photoDic = await _photoPickerService.GetImageAsyncByIntent();
        foreach (var photo in photoDic)
        {
             string iosUrl = "myfile://" + photo.Value;
            _phoneDictionary.Add(photo.Key, iosUrl ;
        }
        await InvokeAsync(StateHasChanged);
    }

}

 

标签:MauiBlazor,urlSchemeTask,string,await,iOS,照片,var,new
From: https://www.cnblogs.com/wecareu/p/17855489.html

相关文章

  • uniapp IOS从打包到上架流程(详细简单) 原创
    ​uniappIOS从打包到上架流程(详细简单)原创1.登入苹果开发者网站,打开AppStoreConnect   ​ 2.新App的创建点击我的App可以进入App管理界面,在右上角点击➕新建App即可创建新的App,如下图: ​ 3.app基本信息填写新建完App后,需要填写App的基本信息,比如App的......
  • ios 开发
    1.申请一个邮箱,然后申请苹果appid。可以在手机上申请。2.把这个appid设置为开发者3. 下载AppUploader, 依次如下:记号证书的密码! 4,下载证书和描述文件,在uniapp上......
  • iOS开发_UIKit框架使用总结
    1、经常使用的1.1基础UIView、UILabel、UIImage、UIColor、UIImageView、UITextField、UIButton、UIFont1.2列表UIScrollView、UITableView、UICollectionView、UITextViewUICollectionViewCell、UITableViewCell1.3其他UIViewController2、偶尔使用的......
  • iOS APP包分析工具
    介绍分享一款用于分析iOSipa包的脚本工具,使用此工具可以自动扫描发现可修复的包体积问题,同时可以生成包体积数据用于查看。这块工具我们团队内部已经使用很长一段时间,希望可以帮助到更多的开发同学更加效率的优化包体积问题。工具下载地址背景APPAnalyze工具最早诞生主要是为......
  • iOS信号量造成线程优先级反转
    在并发队列使用信号量会可能会造成线程优先级反转一、在iOS16&XCode14上遇到-使用信号量造成线程优先级反转问题提醒经过查询资料,发现是在XCode14上增加了工具,比如:ThreadPerformanceChecker(XCode14上默认开启的),这个工具会让APP在运行的时候,发现有例如线程优先级反转......
  • iostat
    参考:https://zhuanlan.zhihu.com/p/649946956安装#默认已安装yuminstallsysstat-y选项参数iostat<options><devicename>-c显示CPU使用情况-d显示磁盘使用情况--dec={0|1|2}指定要使用的小数位数,默认为2-gGROUP_NAME{DEVICE[...]|ALL......
  • uniapp 使用axios 二次封装
    uniapp使用axios二次封装importVuefrom'vue'importaxiosfrom'axios'constbaseUrl='http://127.0.0.1:8080'//服务器地址constimageUrl=baseUrlconststaticVariables={BASE_URL:baseUrl,TIME_OUT:10000,SSL_VERIFY:f......
  • 联想小新通过高级BIOS开启S3睡眠模式
    电脑型号:联想小新Air142021锐龙版(R5500U)BIOS版本:G5CN61WW(v2.07)(2022.01.28)Windows版本:Windows1122631前言为什么我们需要S3睡眠模式?Windows在最近几年大力推行ModernStandby睡眠模式,其存在一定程度上的Bug,不如S3睡眠模式稳定、耗电严重等。而且Linux系统并不支持Monder......
  • 家宽-5- BIOS 更新
     不推荐玩这个,没事做闲的很你可以玩一下. 一:准备好空白U盘,如果有数据请先保存好数据,等下会格式化U盘 二: Rufus官网下载Rufus:https://rufus.ie,也可以蓝奏云直接下载:https://shaun.lanzouq.com/iKKb71bh4b8d 三: 插入空白U盘,找到刚刚下载的rufus,双击打开 ......
  • 如何在App里建立一个小程序?(IOS篇)
    要实现这个架构最基本的就是要能在App里拉起小程序,我司是用的FinClip小程序容器,本期给大家分享实操经验。先从原理开始吧。最近和同事们讨论的最多的技术架构就是 「Native+小程序」,作为混合开发的一种新模式,确实有非常多的优势。一方面,小程序天然具备跨平台能力,一套代码可以在......