1
1
//
2
2
// FRadioPlayer.swift
3
- // FRadioPlayerDemo
3
+ // FRadioPlayer
4
4
//
5
5
// Created by Fethi El Hassasna on 2017-11-11.
6
- // Copyright © 2017 Fethi El Hassasna. All rights reserved.
6
+ // Copyright © 2017 Fethi El Hassasna (@fethica) . All rights reserved.
7
7
//
8
8
9
9
import AVFoundation
@@ -211,6 +211,12 @@ open class FRadioPlayer: NSObject {
211
211
}
212
212
}
213
213
214
+ /// Reachability for network interruption handling
215
+ private let reachability = Reachability ( ) !
216
+
217
+ /// Current network connectivity
218
+ private var isConnected = false
219
+
214
220
// MARK: - Initialization
215
221
216
222
private override init ( ) {
@@ -225,6 +231,11 @@ open class FRadioPlayer: NSObject {
225
231
226
232
// Check for headphones
227
233
checkHeadphonesConnection ( outputs: AVAudioSession . sharedInstance ( ) . currentRoute. outputs)
234
+
235
+ // Reachability config
236
+ try ? reachability. startNotifier ( )
237
+ NotificationCenter . default. addObserver ( self , selector: #selector( reachabilityChanged ( note: ) ) , name: . reachabilityChanged, object: reachability)
238
+ isConnected = reachability. connection != . none
228
239
}
229
240
230
241
// MARK: - Control Methods
@@ -380,6 +391,11 @@ open class FRadioPlayer: NSObject {
380
391
} )
381
392
}
382
393
394
+ private func reloadItem( ) {
395
+ player? . replaceCurrentItem ( with: nil )
396
+ player? . replaceCurrentItem ( with: playerItem)
397
+ }
398
+
383
399
private func resetPlayer( ) {
384
400
stop ( )
385
401
playerItem = nil
@@ -419,6 +435,34 @@ open class FRadioPlayer: NSObject {
419
435
}
420
436
}
421
437
438
+ @objc func reachabilityChanged( note: Notification ) {
439
+
440
+ guard let reachability = note. object as? Reachability else { return }
441
+
442
+ // Check if the internet connection was lost
443
+ if reachability. connection != . none, !isConnected {
444
+ checkNetworkInterruption ( )
445
+ }
446
+
447
+ isConnected = reachability. connection != . none
448
+ }
449
+
450
+ // Check if the playback could keep up after a network interruption
451
+ private func checkNetworkInterruption( ) {
452
+ guard
453
+ let item = playerItem,
454
+ !item. isPlaybackLikelyToKeepUp,
455
+ reachability. connection != . none else { return }
456
+
457
+ player? . pause ( )
458
+
459
+ // Wait 1 sec to recheck and make sure the reload is needed
460
+ DispatchQueue . main. asyncAfter ( deadline: DispatchTime . now ( ) + 1 ) {
461
+ if !item. isPlaybackLikelyToKeepUp { self . reloadItem ( ) }
462
+ self . isPlaying ? self . player? . play ( ) : self . player? . pause ( )
463
+ }
464
+ }
465
+
422
466
// MARK: - Responding to Route Changes
423
467
424
468
private func checkHeadphonesConnection( outputs: [ AVAudioSessionPortDescription ] ) {
@@ -464,7 +508,10 @@ open class FRadioPlayer: NSObject {
464
508
465
509
case " playbackBufferEmpty " :
466
510
467
- if item. isPlaybackBufferEmpty { self . state = . loading }
511
+ if item. isPlaybackBufferEmpty {
512
+ self . state = . loading
513
+ self . checkNetworkInterruption ( )
514
+ }
468
515
469
516
case " playbackLikelyToKeepUp " :
470
517
@@ -480,4 +527,3 @@ open class FRadioPlayer: NSObject {
480
527
}
481
528
}
482
529
}
483
-
0 commit comments