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
相关产品推荐
相关产品推荐

