首页 > 解决方案 > RequestContentEditingInput completionHandler 不运行

问题描述

我有一个应用程序,我需要从手机中选择图像并按照用户选择它们的顺序显示它们(我需要按选择的顺序显示 img,而不是“最近编辑的”,这就是我不使用 UIImagePickerController 的原因)

为此,我有一个页面显示最新的 50 张图片,并且可以加载更多图片。

我正在使用下面的代码获取图像路径和方向。

我的问题:CompletionHandler(在 RequestContentEditingInput 中)只会运行 17 次......我可以看到每个图像都调用了 RequestContentEditingInput(在这部手机上 138 次)

我试图等待,但没有任何反应。

当我的图像少于 17 张时,代码按预期工作......

我试图在 CompletionHandler 代码中实现 SemaphoreSlim 锁,以控制我当时只处理 10 个图像,但最终结果是相同的或根本没有处理任何图像。

UpdateInfo:似乎所有未处理的 LivePhotos。

有人知道这里发生了什么吗?

修复的想法?

还有另一种方法可以获得所有图像路径和方向吗?

还是完全其他的解决方案,让用户从手机中挑选图像并获得用户挑选它们的顺序?

    public class GalleryHelper : IGalleryHelper
    {
        private List<(string, string, string)> _retval;
        private nint _numberofImg = 0;
        private nint _currentImg = 0;

        public List<(string, string, string)> GetAllImgFromGallery()
        {
            _retval = new List<(string, string, string)>();
            _currentImg = 0;
            GetAllImg();
            return _retval;
        }

        private void GetAllImg()
        {
            var fetchOptions = new PHFetchOptions();

            PHFetchResult allPhotos = PHAsset.FetchAssets(PHAssetMediaType.Image, fetchOptions);
            _numberofImg = allPhotos.Count;

            Debug.WriteLine("Total img no + " + _numberofImg);

            for (nint i = 0; i < allPhotos.Count; i++)
            {
                Debug.WriteLine("Starting " + i);
                (allPhotos[i] as PHAsset).RequestContentEditingInput(new PHContentEditingInputRequestOptions(), CompletionHandler);
            }
        }

        private void CompletionHandler(PHContentEditingInput contentEditingInput, NSDictionary requestStatusInfo)
        {
            Debug.WriteLine("Starting CompletionHandler " + (1 + _currentImg));
            var path = contentEditingInput.FullSizeImageUrl.Path;
            if (path != null)
            {
                var orientation = contentEditingInput.FullSizeImageOrientation;

                switch (orientation)
                {
                    case CIImageOrientation.TopLeft:
                        //Standard position
                        _retval.Add((path, null, "0"));
                        break;

                    case CIImageOrientation.LeftBottom:
                        //Rotate 90 degrees clockwise
                        _retval.Add((path, null, "-90"));
                        break;

                    case CIImageOrientation.RightTop:
                        //Rotate 90 degrees counterclockwise
                        _retval.Add((path, null, "90"));
                        break;

                    case CIImageOrientation.BottomRight:
                        //Rotate 180 degrees
                        _retval.Add((path, null, "180"));
                        break;

                    case CIImageOrientation.BottomLeft:
                        //Mirror image rotated 180 degrees
                        _retval.Add((path, null, "180"));
                        break;

                    case CIImageOrientation.TopRight:
                        //Mirror image
                        _retval.Add((path, null, "0"));
                        break;

                    case CIImageOrientation.LeftTop:
                        //Mirror image rotate 90 degrees clockwise
                        _retval.Add((path, null, "-90"));
                        break;

                    case CIImageOrientation.RightBottom:
                        //Mirror image rotate 90 degrees counterclockwise.
                        _retval.Add((path, null, "90"));
                        break;

                    default:
                        _retval.Add((path, null, "0"));
                        break;
                }
            }
            _currentImg++;
            Debug.WriteLine("Images done " + _currentImg);
            MessagingCenter.Send((App)Xamarin.Forms.Application.Current, "ImagesReady", _retval);

        }
    }

运行时从我的调试输出粘贴:

[0:] Total img no + 138
[0:] Starting 0
[0:] Starting 1
(...)
[0:] Starting 137
[0:] Starting CompletionHandler 1
[0:] Images done 1
[0:] Starting CompletionHandler 2
[0:] Images done 2
[0:] Starting CompletionHandler 3
[0:] Images done 3
(...)
[0:] Starting CompletionHandler 15
[0:] Images done 15
[0:] Starting CompletionHandler 16
[0:] Images done 16
[0:] Starting CompletionHandler 17
[0:] Images done 17
Thread started: #17
Thread finished: #15
The thread 0xf has exited with code 0 (0x0).
Thread finished: #3

标签: c#xamarin.formsxamarin.iosphotosframework

解决方案


如果以后有人遇到同样的问题。使用 PHImageManager.DefaultManager.RequestImageData() 而不是 PHAsset.RequestContentEditingInput() 因为如果您要求它处理大量图像,它不会崩溃。

我做类似的事情:

    var fetchOptions = new PHFetchOptions();
    PHFetchResult allPhotos = PHAsset.FetchAssets(PHAssetMediaType.Image, fetchOptions);
    _numberofImg = allPhotos.Count;
    Debug.WriteLine("Total img no + " + _numberofImg);
    await Task.Yield();
    await Task.Run(() => ImgProcess(allPhotos));
    return true;

private void ImgProcess(PHFetchResult allPhotos)
{
    //await Task.Run(() =>
    //{
        for (nint i = 0; i < allPhotos.Count; i++)
        {
            Debug.WriteLine("Starting " + i);
            var phasset = allPhotos[i] as PHAsset;
            var options = new PHImageRequestOptions()
            {
                Synchronous = true,
                NetworkAccessAllowed = false,
                DeliveryMode = PHImageRequestOptionsDeliveryMode.FastFormat
            };
            PHImageManager.DefaultManager.RequestImageData(phasset, options, ComplManager);
        }
    //});
    //return;
}

即使这个解决方案在图像数量超过 300 个时仍然存在问题......


推荐阅读