Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何在重新加载采集视图的数据之前等待图像完成处理?_Ios_Swift - Fatal编程技术网

Ios 如何在重新加载采集视图的数据之前等待图像完成处理?

Ios 如何在重新加载采集视图的数据之前等待图像完成处理?,ios,swift,Ios,Swift,我正在iOS 14中使用新的图像选择器API,希望能够在调用底部的代码之前完成图像的for-loop处理,该代码更新我的数据源,然后最终重新加载采集视图的数据。目前,底部的代码在totalConversionsCompleted达到1之前被调用 func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { dismiss(animated: true, comple

我正在iOS 14中使用新的图像选择器API,希望能够在调用底部的代码之前完成图像的for-loop处理,该代码更新我的数据源,然后最终重新加载采集视图的数据。目前,底部的代码在totalConversionsCompleted达到1之前被调用

func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {

    dismiss(animated: true, completion: nil)

    var selectedImageDatas = [Data?](repeating: nil, count: results.count) // Awkwardly named, sure
    var totalConversionsCompleted = 0

    for (index, result) in results.enumerated() {
        result.itemProvider.loadFileRepresentation(forTypeIdentifier: UTType.image.identifier) { (url, error) in
            guard let url = url else {
                totalConversionsCompleted += 1
                return
            }

            let sourceOptions = [kCGImageSourceShouldCache: false] as CFDictionary

            guard let source = CGImageSourceCreateWithURL(url as CFURL, sourceOptions) else {
                totalConversionsCompleted += 1
                return
            }

            let downsampleOptions = [
                kCGImageSourceCreateThumbnailFromImageAlways: true,
                kCGImageSourceCreateThumbnailWithTransform: true,
                kCGImageSourceThumbnailMaxPixelSize: 2_000,
            ] as CFDictionary

            guard let cgImage = CGImageSourceCreateThumbnailAtIndex(source, 0, downsampleOptions) else {
                totalConversionsCompleted += 1
                return
            }

            let data = NSMutableData()

            guard let imageDestination = CGImageDestinationCreateWithData(data, kUTTypeJPEG, 1, nil) else {
                totalConversionsCompleted += 1
                return
            }

            // Don't compress PNGs, they're too pretty
            let isPNG: Bool = {
                guard let utType = cgImage.utType else { return false }
                return (utType as String) == UTType.png.identifier
            }()

            let destinationProperties = [
                kCGImageDestinationLossyCompressionQuality: isPNG ? 1.0 : 0.75
            ] as CFDictionary

            CGImageDestinationAddImage(imageDestination, cgImage, destinationProperties)
            CGImageDestinationFinalize(imageDestination)

            selectedImageDatas[index] = data as Data
            totalConversionsCompleted += 1
        }
    }


    //I want to wait for the processing of images and then do this

    self.images.append(contentsOf: selectedImageDatas)

    RxBus.shared.post(event: Events.AlbumUpdated(images: self.images, indexPath: self.selectedIndexPath))

    self.collectionView.reloadData()

}

我建议在哪里调用leave(),就好像我在递增totalConversionsCompleted后调用它一样,我放在wait:block底部的代码会被多次调用
    let g = DispatchGroup()
    for (index, result) in results.enumerated() {
        g.enter()
        result.itemProvider.loadFileRepresentation(forTypeIdentifier: UTType.image.identifier) { (url, error) in
            ...
            g.leave()
        }
    }
    g.notify(queue: .main) {
        // completed here
    }