I am using PHCachingImageManager().requestAVAsset
to load some videos from the camera roll:
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)
}
However when I run the program it pauses at the PHCachingImageManager().requestAVAsset
line and shows:
THREAD 1 : EXC_BREAKPOINT
(highlighted in green)
I'm not sure what is happening and can't find anything I understand in the documentation. How do I fix this?
There are a couple of things you're going to want to do here in order to get this working.
PHCachingImageManager
as a property on an object that will stay alive. If you just create it without storing it somewhere, ARC rules will cause it to be thrown away. In the code below, I use a lazy var, but that's not the only way to do it. !
in your code. Using the guard let ...
or if let ...
patterns may feel like more typing but it will save you a lot of time and frustration in the end. Think of the !
as a danger sign that says "CRASH HERE!". AVPlayerItem
from the resultHandler
completion block. requestAVAsset
is asynchronous so that it doesn't block your main thread while it does the potentially expensive work of retrieving your asset. Basically, as soon as you call requestAVAsset
a separate thread goes and does work for you, while the main thread continues working on the rest of the code in the viewDidLoad
method. When it has successfully retrieved the AVAsset
it calls back to the block of code you provided originally (on the main thread) so you can continue processing. Here's your code rewritten to incorporate the changes I'm suggesting:
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)
}
Let me know if anything is unclear.