ios - Compartir video PHAsset a través de UIActivityController
swift uiactivityviewcontroller (2)
Estoy tratando de compartir video PHAsset a través de UIActivityController usando requestAVAsset. Esto funciona con Mensajería, pero no con AirDrop, lo que indica como "Fallido".
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)
}
})
Esto parece poner UIActivityController correctamente y solo funciona con ciertas actividades:
- Mensajería - ✔️ Trabajos, exporta video correctamente.
- AirDrop - ✖️ Muestra "Fallido"
- Dropbox - P️ Imprime la vista adecuada de Dropbox, pero dice "Error desconocido"
Me he encontrado con un comportamiento similarmente extraño cuando trabajo con PHAssets. Supongo que se trata de una restricción de sandboxing / seguridad indocumentada (a propósito).
Pude evitar este problema copiando el archivo subyacente a un directorio de usuario y luego realizando la operación en el archivo copiado.
Hice esto en un bucle. Ocasionalmente, la copia falla con un error de permisos de archivo impreciso. Cuando lo hace, lo intento de nuevo después de unos segundos (usando DispatchQueue.main.asyncAfter
). ¡Eventualmente, funciona!
Esta es mi respuesta, la idea es la misma que la aceptada, pero proporciono el código. Siempre escribo en la misma URL, así que espero tener siempre un video en la extensión de la ruta de acceso de los documentos url temp.mov, pero cada vez que envío un video nuevo, estos datos se sobrescriben.
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)
}
}
})