You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TLPhotoPicker中dismissPhotoPicker无法获取视频,请教无崩溃解决方案

问题

我尝试从系统相册中获取并添加视频文件,目前可正常选择并添加图片文件,但尝试获取视频时,withTLPHAssets会忽略视频,仅返回图片内容。我使用的是TLPhotoPicker pod,以下是实现的dismissPhotoPicker方法代码,请问如何无崩溃地获取视频文件?

extension TLPhotoPickerManager: TLPhotosPickerViewControllerDelegate {

func dismissPhotoPicker(withTLPHAssets: [TLPHAsset]) {
    selectedTLPHAssets = withTLPHAssets
    didSelectTLPHAsset?(withTLPHAssets, videoUrl)
    if selectedTLPHAssets.contains(where: { $0.fullResolutionImage == nil && $0.type != .video }) {
        var assets = selectedTLPHAssets.filter {
            $0.fullResolutionImage != nil || $0.type == .video
        }
        // MARK: Bunu yazan kör oldu... elleme...
        if assets.count > 0 {
            for i in 0...assets.count - 1 {
                assets[i].selectedOrder = i + 1
            }
        }
        /// END ///
        Dialog.shared.showTopAlert(body: "newsfeed_post.share.getting.image.fail".localized)
        didSelectTLPHAsset?(assets, videoUrl)
    } else {
        didSelectTLPHAsset?(withTLPHAssets, videoUrl)
    }
}
解决方案

1. 先确保TLPhotoPicker允许选择视频

这是最容易遗漏的前提:初始化picker时必须开启视频选择权限,否则picker本身不会返回视频资产:

let picker = TLPhotosPickerViewController()
picker.delegate = self
picker.mediaType = .all // 或者明确设置为 [.image, .video]
picker.maxSelectedAssets = 你的最大选择数量
// 其他自定义配置(如是否允许原图等)
present(picker, animated: true)

如果只设置了.image类型,无论怎么处理代理方法都拿不到视频。

2. 修正代理方法的视频处理逻辑

你的原代码存在重复回调、视频URL未正确获取的问题,调整后既可以拿到视频,又能避免崩溃:

extension TLPhotoPickerManager: TLPhotosPickerViewControllerDelegate {
    func dismissPhotoPicker(withTLPHAssets: [TLPHAsset]) {
        selectedTLPHAssets = withTLPHAssets
        
        // 过滤无效资产:保留视频,或有完整图片的资产
        let validAssets = selectedTLPHAssets.filter { asset in
            asset.type == .video || asset.fullResolutionImage != nil
        }
        
        // 重新设置选中顺序,避免索引越界
        if !validAssets.isEmpty {
            validAssets.enumerated().forEach { index, asset in
                asset.selectedOrder = index + 1
            }
        }
        
        // 异步获取视频URL,避免主线程阻塞崩溃
        var collectedVideoUrls: [URL] = []
        let dispatchGroup = DispatchGroup()
        
        validAssets.forEach { asset in
            if asset.type == .video {
                dispatchGroup.enter()
                asset.requestVideoURL { url, error in
                    defer { dispatchGroup.leave() }
                    if let url = url {
                        collectedVideoUrls.append(url)
                    } else {
                        Dialog.shared.showTopAlert(body: "获取视频失败".localized)
                    }
                }
            }
        }
        
        // 所有视频请求完成后统一回调
        dispatchGroup.notify(queue: .main) {
            self.didSelectTLPHAsset?(validAssets, collectedVideoUrls)
        }
        
        // 仅当存在无效资产时提示用户
        if validAssets.count != selectedTLPHAssets.count {
            Dialog.shared.showTopAlert(body: "newsfeed_post.share.getting.image.fail".localized)
        }
    }
}

3. 关键崩溃规避点

  • 必须异步获取视频URL:requestVideoURL是耗时操作,同步调用会阻塞主线程导致崩溃
  • 用DispatchGroup管理多视频请求:避免部分视频还没获取到就回调,导致数据不全
  • 用enumerated()遍历设置顺序:替代手动索引遍历,彻底避免数组越界崩溃
  • 回调参数videoUrl建议改为数组:支持多选视频的场景,原代码的单个URL无法满足

内容的提问来源于stack exchange,提问作者Mert Köksal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 13:01:55