My users are facing this crash that got reported inside Firebase Crashlytics. I can see the Class and Method where the crash took place but couldn't figure out the reason for the crash. Everything works fine inside simulator and on the real device that I have.
I need some help figuring out the actual cause of this crash. Here is the crash log.
Crashed: com.apple.main-thread
0 OK Tested 0x1049dc4a0 closure #1 in VideoPlayerController.setProgressLabel() + 336 (VideoPlayerController.swift:336)
1 OK Tested 0x1049da494 thunk for @escaping @callee_guaranteed (@unowned CMTime) -> () + 4308100244 (<compiler-generated>:4308100244)
2 AVFoundation 0x1abaefd9c -[AVPeriodicTimebaseObserver _fireBlockForTime:] + 60
3 AVFoundation 0x1abaf03a4 -[AVPeriodicTimebaseObserver _handleTimeDiscontinuity] + 164
4 AVFoundation 0x1abaf125c __AVTimebaseObserver_timebaseNotificationCallback_block_invoke + 112
5 libdispatch.dylib 0x1a158e9a8 _dispatch_call_block_and_release + 24
6 libdispatch.dylib 0x1a158f524 _dispatch_client_callout + 16
7 libdispatch.dylib 0x1a15726fc _dispatch_main_queue_callback_4CF$VARIANT$armv81 + 860
8 CoreFoundation 0x1a1847748 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
9 CoreFoundation 0x1a184261c __CFRunLoopRun + 1724
10 CoreFoundation 0x1a1841c34 CFRunLoopRunSpecific + 424
11 GraphicsServices 0x1ab98b38c GSEventRunModal + 160
12 UIKitCore 0x1a597422c UIApplicationMain + 1932
13 OK Tested 0x104901480 main + 21 (GoogleAds.swift:21)
14 libdyld.dylib 0x1a16c9800 start + 4
And the actual code. This part of code is used to set the progress slider and labels to indicate the progress of an AVPlayerItem
private func setProgressLabel() {
player.addPeriodicTimeObserver(forInterval: CMTimeMakeWithSeconds(1/30.0, preferredTimescale: Int32(NSEC_PER_SEC)), queue: DispatchQueue.main) { [unowned self] time in
// guard let self = self else { return }
if let playerItem = self.player.currentItem {
let totalDuration : CMTime = playerItem.asset.duration
let totalDurationInSeconds : Float64 = CMTimeGetSeconds(totalDuration)
let totalDurationInString = Functions.stringFromTimeInterval(interval: totalDurationInSeconds)
let duration : CMTime = playerItem.currentTime()
let seconds : Float64 = CMTimeGetSeconds(duration)
let currentDurationInString = Functions.stringFromTimeInterval(interval: seconds)
self.progressLabel.text = "\(currentDurationInString)/\(totalDurationInString)"
self.progressSlider.maximumValue = Float(totalDurationInSeconds)
self.progressSlider.setValue(Float(seconds), animated: true)
// For Analytics: video tracking
let percentageComplete = Float(seconds / totalDurationInSeconds * 100)
if percentageComplete.isNaN {
return
}
if Int(seconds) == 5 || Int(seconds) == 10 {
if Int(seconds) != self.eventSentForQuartile {
self.quartile = Int(seconds)
self.eventSentForQuartile = self.quartile
// send event for quartile
print("Send event for quartile \(self.quartile) at time \(Int(seconds))")
self.trackVideoOnPlay(firstPlay: false, watchDuration: "\(Int(seconds))")
}
}
if Int(seconds) == 30 && !self.isCustomEventFor30SecondsSent {
AppAnalytics.playVideoEvent(video: self.video)
self.isCustomEventFor30SecondsSent = true
}
if Int(percentageComplete) == 25 || Int(percentageComplete) == 50 || Int(percentageComplete) == 75 || Int(percentageComplete) == 95 {
if Int(percentageComplete) != self.eventSentForQuartile {
self.quartile = Int(percentageComplete)
self.eventSentForQuartile = self.quartile
// send event for quartile
print("Send event for quartile \(self.quartile) at time \(Int(seconds))")
self.trackVideoOnPlay(firstPlay: false, watchDuration: "\(Int(seconds))")
}
}
}
}
}
Don't use unowned self. Because self can be nil. Follow the code:
private func setProgressLabel() {
player.addPeriodicTimeObserver(forInterval: CMTimeMakeWithSeconds(1/30.0, preferredTimescale: Int32(NSEC_PER_SEC)), queue: DispatchQueue.main) { [weak self] time in
guard let self = self else { return }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With