2017-01-23 5 views
0

J'utilise PHCachingImageManager().requestAVAsset pour charger des vidéos à partir du rouleau de la caméra.crash lors de l'utilisation PHCachingImageManager() requestAVAsset

override func viewDidLoad() { 
    super.viewDidLoad() 
    print("SEGUE SUCCESSFUL") 
    view.backgroundColor = .black 
    avPlayerLayer = AVPlayerLayer(player: avPlayer) 
    view.layer.insertSublayer(avPlayerLayer, at: 0) 

    var asset2:AVAsset? = nil 

    PHCachingImageManager().requestAVAsset(forVideo: (vidLocation?[videoSender]!)!, options: nil, resultHandler: {(asset: AVAsset?, audioMix: AVAudioMix?, info: [AnyHashable : Any]?) in 
     asset2 = asset! as AVAsset 
     }) 


    let playerItem = AVPlayerItem(asset: asset2!) 
    avPlayer.replaceCurrentItem(with: playerItem) 
} 

Cependant quand je lance le programme, il fait une pause sur la ligne PHCachingImageManager().requestAVAsset et montre:

THREAD 1: EXC_BREAKPOINT

(en vert)

Je ne suis pas sûr de ce qui se passe et je ne trouve rien de ce que je comprends dans la documentation. Comment puis-je réparer ça?

+0

Vous avez deux opérations de dépliage forcé dans l'un des paramètres de cet appel ('(vidLocation? [VideoSender]!)!'). Probablement au moins l'un d'entre eux est nul. De plus, bien que cela ne soit pas lié à votre crash, vous avez une fausse supposition - le gestionnaire d'achèvement de 'requestAVAsset' est asynchrone, donc il exécutera * après * le code qui définit votre' playerItem', donc 'asset2' sera toujours nul à le moment où vous essayez de l'utiliser. – rickster

Répondre

0

Il y a plusieurs choses que vous voulez faire ici pour que cela fonctionne.

  1. Vous devez mettre en cache le PHCachingImageManager en tant que propriété sur un objet qui restera actif. Si vous le créez simplement sans le stocker quelque part, les règles ARC le rejetteront. Dans le code ci-dessous, j'utilise un var paresseux, mais ce n'est pas la seule façon de le faire.
  2. Vous devez éliminer toutes les options non dépliées forcées ! dans votre code. L'utilisation des modèles guard let ... ou if let ... peut donner l'impression d'être plus typée, mais elle vous fera gagner beaucoup de temps et de frustration à la fin. Pensez à la ! comme un signe de danger qui dit "CRASH ICI!". Vous devez configurer le AVPlayerItem à partir du bloc d'achèvement resultHandler. requestAVAsset est asynchrone de sorte qu'il ne bloque pas votre thread principal pendant qu'il effectue le travail potentiellement coûteux de récupération de votre actif. Fondamentalement, dès que vous appelez requestAVAsset un thread séparé va et travaille pour vous, tandis que le thread principal continue à travailler sur le reste du code dans la méthode viewDidLoad. Quand il a réussi à récupérer le AVAsset, il rappelle le bloc de code que vous avez fourni à l'origine (sur le thread principal) afin que vous puissiez continuer le traitement.

Voilà votre code réécrite pour intégrer les changements que je suggère:

lazy var imageManager = { 
    return PHCachingImageManager() 
}() 

override func viewDidLoad() { 
    super.viewDidLoad() 
    print("SEGUE SUCCESSFUL") 
    view.backgroundColor = .black 
    avPlayerLayer = AVPlayerLayer(player: avPlayer) 
    view.layer.insertSublayer(avPlayerLayer, at: 0) 

    var asset2:AVAsset? = nil 
guard let phAsset = vidLocation?[videoSender] else { return } //No video 

imageManager.requestAVAsset(forVideo: phAsset, options: nil, resultHandler: {(asset: AVAsset?, audioMix: AVAudioMix?, info: [AnyHashable : Any]?) in 
    if let avAsset = asset { 
     self.play(asset: avAsset) 
    } 
}) 

func play(asset: AVAsset) { 
    let playerItem = AVPlayerItem(asset: asset) 
    avPlayer.replaceCurrentItem(with: playerItem) 
} 

Laissez-moi savoir si quelque chose ne sait pas.

+1

Parfait - cela a fait le travail. La seule modification au code est dans cette ligne: 'guard let phAsset = vidLocation? [VideoSender] else {return // Pas de vidéo}' Je devais le changer: 'guard let phAsset = vidLocation? [VideoSender] else { return} // Pas de vidéo 'Sinon, le crochet de fermeture de l'autre est mis en commentaire. – ZiEiTiA

+0

Ah, bien sûr. Je vais mettre à jour la réponse pour correspondre. –