通过UIActivityController共享视​​频PHAsset

我正尝试使用requestAVAsset通过UIActivityController共享videoPHAsset 。 这适用于消息传递,但不适用于AirDrop,指示为“失败”。

PHCachingImageManager.default().requestAVAsset(forVideo: asset, options: nil, resultHandler: { (givenAsset, audioMix, info) in let videoAsset = givenAsset as! AVURLAsset let videoURL = videoAsset.url DispatchQueue.main.async { let activityViewController = UIActivityViewController( activityItems: [videoURL], applicationActivities: nil) activityViewController.excludedActivityTypes = [UIActivityType.saveToCameraRoll] if let popoverPresentationController = activityViewController.popoverPresentationController { popoverPresentationController.barButtonItem = (sender) } self.present(activityViewController, animated: true, completion: nil) } }) 

这似乎正确地build立了UIActivityController ,只能用于某些活动:

  • 消息 – ✔️Works,正确导出video。
  • AirDrop – ✖️Shows“失败”
  • Dropbox – ✖️放置正确的Dropbox视图,但说“发生未知错误”

在这里输入图像说明

使用PHAssets时,我遇到了类似的奇怪行为。 我的猜测是这是一个(故意)没有logging的安全/沙箱限制。

我能够通过将底层文件复制到用户目录,然后对复制的文件执行操作来解决此问题。

我做了这个循环。 偶尔,复制失败,模糊的文件权限错误。 当它发生时,我会在几秒后重试它(使用DispatchQueue.main.asyncAfter )。 最终,它的工作!

这是我的答案,这个想法与被接受的答案是一样的,但我提供了代码。 我总是写入相同的url,所以我希望总是有一个文件的urlpath扩展temp.movvideo,但每次我发送一个新的video这个数据被覆盖。

 PHImageManager.default().requestPlayerItem(forVideo: phAsset, options: nil, resultHandler: { playerItem, info in if let playerAsset = playerItem?.asset as? AVURLAsset{ let url = playerAsset.url var videoData = Data() var tempURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! tempURL.appendPathComponent("temp.mov") do{ videoData = try Data(contentsOf: url) }catch{ print("error with the video data \(error)") } do{ try videoData.write(to: tempURL) }catch{ print("could not write to tempURL\(error)") } let activityController = UIActivityViewController(activityItems: [tempURL], applicationActivities: nil) DispatchQueue.main.async { self.present(activityController, animated: true) } } })