2017-01-23 9 views
0

I PHCachingImageManager().requestAVAsset bin mit ein paar Videos von der Kamera Rolle zu laden.Absturz bei der Verwendung von 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) 
} 

Allerdings, wenn ich das Programm ausführen es an der PHCachingImageManager().requestAVAsset Linie pausiert und zeigt:

THREAD 1: EXC_BREAKPOINT

(grün markiert)

Ich bin mir nicht sicher, was passiert und kann nichts finden, was ich in der Dokumentation verstehe. Wie behebe ich das?

+0

Sie haben zwei Force-Unwrap-Operationen in einem der Parameter für diesen Aufruf ('(vidLocation? [VideoSender]!)!"). Wahrscheinlich ist mindestens einer von ihnen gleich Null. Auch wenn es nichts mit Ihrem Absturz zu tun hat, haben Sie eine falsche Annahme - der Completion-Handler für 'requestAVAsset' ist asynchron und führt * nach * dem Code aus, der Ihr' playerItem' festlegt, so dass 'asset2' immer Null ist die Zeit, die Sie versuchen, es zu verwenden. – rickster

Antwort

0

Es gibt ein paar Dinge, die Sie hier tun möchten, um dies zum Laufen zu bringen.

  1. Sie müssen die PHCachingImageManager als eine Eigenschaft auf einem Objekt, das am Leben bleiben wird, zwischenspeichern. Wenn Sie es einfach erstellen, ohne es irgendwo zu speichern, werden die ARC-Regeln dazu führen, dass es weggeworfen wird. Im folgenden Code verwende ich eine Lazy Var, aber das ist nicht die einzige Möglichkeit.
  2. Sie sollten alle erzwungenen unverpackten Optionals ! in Ihrem Code entfernen. Die Verwendung der guard let ... oder if let ... Muster mag sich anfühlen wie mehr Tipparbeit, aber es wird Ihnen am Ende viel Zeit und Frustration ersparen. Denken Sie an die ! als ein Gefahrenzeichen, das sagt "CRASH HIER!".
  3. Sie müssen den AVPlayerItem aus dem resultHandler Completion Block einrichten. requestAVAsset ist asynchron, so dass es Ihren Hauptthread nicht blockiert, während es die potenziell teure Arbeit zum Abrufen Ihres Assets erledigt. Grundsätzlich, sobald Sie requestAVAsset anrufen, geht ein separater Thread und funktioniert für Sie, während der Hauptthread weiter an dem Rest des Codes in der viewDidLoad Methode arbeitet. Wenn die AVAsset erfolgreich abgerufen wurde, ruft sie den Code auf, den Sie ursprünglich (im Hauptthread) bereitgestellt haben, damit Sie mit der Verarbeitung fortfahren können.

Hier ist der Code neu geschrieben, um die Änderungen übernehmen Ich schlage:

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) 
} 

Lassen Sie mich wissen, wenn etwas unklar ist.

+1

Perfekt - das hat den Job gemacht. Die einzige Änderung an dem Code ist in dieser Zeile: 'guard let phAsset = vidLocation? [VideoSender] else {return // Kein Video}' Ich musste es ändern: 'guard let phAsset = vidLocation? [VideoSender] else { return} // Kein Video 'Sonst ist die schließende Klammer des else auskommentiert. – ZiEiTiA

+0

Ah, natürlich. Ich werde die Antwort aktualisieren. –

Verwandte Themen