从照片中获取后,视频及其缩略图未按顺序保存

Videos and its thumbnails not saved in sequence after fetching From Photos

我正在使用以下代码获取视频(URL、时长、缩略图)。获取数据后,我将其显示在 CollectionView 上。 主要问题是,某些视频与其缩略图不匹配。谁能告诉我如何解决它,或任何其他更好的解决方案? 谢谢

  override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell

        cell.imgV.image = photoLibrary[indexPath.row]

        let duration: TimeInterval = videosDuration[indexPath.row] // 2 minutes, 30 seconds
        let formatter = DateComponentsFormatter()
        formatter.unitsStyle = .positional
        formatter.allowedUnits = [ .minute, .second ]
        formatter.zeroFormattingBehavior = [ .pad ]
        let formattedDuration = formatter.string(from: duration)
        cell.duration.text = "\(String(describing: formattedDuration!))"

        return cell
    }

    func grabPhotos(){
        let imgManager = PHImageManager.default()

        let requestOptions = PHImageRequestOptions()
        requestOptions.isSynchronous = false
        requestOptions.deliveryMode = .highQualityFormat

        let fetchOptions = PHFetchOptions()
        fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
        if let fetchResult : PHFetchResult = PHAsset.fetchAssets(with: .video, options: fetchOptions) {
            if fetchResult.count > 0 {
                for i in 0..<fetchResult.count{
                    //Used for fetch Image//
                    imgManager.requestImage(for: fetchResult.object(at: i) as PHAsset , targetSize: CGSize(width: 100, height: 100), contentMode: .aspectFill, options: requestOptions, resultHandler: {
                        image, error in
                        let imageOfVideo = image! as UIImage
                        self.photoLibrary.append(imageOfVideo)
                    })
                    //Used for fetch Video//
                    imgManager.requestAVAsset(forVideo: fetchResult.object(at: i) as PHAsset, options: PHVideoRequestOptions(), resultHandler: {(avAsset, audioMix, info) -> Void in
                        if let asset = avAsset as? AVURLAsset {
                            self.videoURL.append(asset.url)
                            let duration : CMTime = asset.duration
                            let durationInSecond = CMTimeGetSeconds(duration)
                            self.videosDuration.append(durationInSecond)
                        }
                    })
                }
            }
            else{
                //showAllertToImportImage()//A function to show alert
            }
        }

    }

由于照片是异步获取的,因此图像和视频数组中没有维护顺序,因此要获取视频的相应图像,您可以使用字典来存储结果

我对你的代码做了一些修改,请检查

var imageDictionary = [String: AnyObject]()
var videoDictionary = [String: AnyObject]()

func fetchData(){
        let imgManager = PHImageManager.default()

        let requestOptions = PHImageRequestOptions()
        requestOptions.isSynchronous = false
        requestOptions.deliveryMode = .highQualityFormat

        let fetchOptions = PHFetchOptions()
        fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
        if let fetchResult : PHFetchResult = PHAsset.fetchAssets(with: .video, options: fetchOptions) {
            if fetchResult.count > 0 {
                for i in 0..<fetchResult.count{
                    //Used for fetch Image//

                    imgManager.requestImage(for: fetchResult.object(at: i) as PHAsset , targetSize: CGSize(width: 100, height: 100), contentMode: .aspectFill, options: requestOptions, resultHandler: {
                        image, error in
                        let imageOfVideo = image! as UIImage
                        //self.photoLibrary.append(imageOfVideo)
                        let key = "\(i)"
                        self.imageDictionary[key] = imageOfVideo
                    })
                    //Used for fetch Video//
                    imgManager.requestAVAsset(forVideo: fetchResult.object(at: i) as PHAsset, options: PHVideoRequestOptions(), resultHandler: {(avAsset, audioMix, info) -> Void in
                        if let asset = avAsset as? AVURLAsset {
                            //let videoData = NSData(contentsOf: asset.url)
                            self.videoURL.append(asset.url)
                            //print(asset.url)
                            let duration : CMTime = asset.duration
                            let durationInSecond = CMTimeGetSeconds(duration)
                            //self.videosDuration.append(durationInSecond)
                            //print(durationInSecond)
                            let key = "\(i)"
                            self.videoDictionary[key] = ["VideoURL" : asset.url, "VideoDuration" : durationInSecond]
                        }
                    })
                }
            }
            else{
                //showAllertToImportImage()//A function to show alert
            }
        }

    }


    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.imageDictionary.count
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

               //You can access the values like this....

               let key = "\(indexPath.row)"

               cell.image = self.imageDictionary[key] as? UIImage
               let singleVideo = self.videoDictionary[key] as? [String: AnyObject]

               cell.videoURL = singleVideo["VideoURL"] as? URL
               cell.videoDuration = singleVideo["VideoDuration"] as? CMTime


    }