2016-07-24 8 views
0

Ich versuche ActivityIndicator zu zeigen, wenn Spieler (Pufferung oder Laden) und wenn es zu spielen stoppt es ActivityIndicator. Auch wenn ich Player stoppe, wird er (removeObserver oder deallocObserver) von AVPlayer. Wenn ich Musik spiele, zeige ich ActivityIndicator bis es zum Abspielen bereit ist, aber es stoppt die Animation von ActivityIndicator 4,5 Sekunden vor dem Abspielen. Das Problem ist, dass wenn ich AVPlayer stoppe oder auf eine andere Play-Taste tippe, es mir einen Fehler gibt, wenn ich den AVPlayer-Beobachter entferne. Kann mir bitte jemand sagen, wo Fehler in meinem Code ist und wie ich es beheben kann, danke.Hinzufügen ActivityIndicator und Entfernen von addObserver auf AVPlayer

var selectIndex:Int = -1 

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell{ 
     let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! RadioCollectionViewCell 
     cell.backgroundColor = UIColor.yellowColor() 

     let object = objects[indexPath.row] 
     cell.img.image = UIImage(named: object["image"]!) 
     cell.btnPlay.addTarget(self, action: Selector("audioControlButtonAction:"), forControlEvents: UIControlEvents.TouchUpInside) 
     cell.btnPlay.tag = indexPath.row+1 


     return cell 
    } 

func audioControlButtonAction(sender: UIButton){ 

     if player != nil && player?.currentItem != nil { 
      deallocObservers(player!) 
     } 

     var btn:NSInteger 
     btn = sender.tag as NSInteger 

     let object = objects[btn-1] 
     let nurl = NSURL(string: "\(object["url"]!)")! 
     playerItem = AVPlayerItem(URL: nurl) 
     player=AVPlayer(playerItem: playerItem!) 

     print(selectIndex) 
     if selectIndex != -1 && selectIndex != sender.tag 
     { 
      let bt:UIButton = self.view.viewWithTag(selectIndex) as! UIButton 

      if bt.selected == true 
      { 
       bt.selected = false 
       deallocObservers(player!) 
      } 
     } 

     if sender.selected == false 
     { 
      player!.addObserver(self, forKeyPath: "status", options:NSKeyValueObservingOptions(), context: nil) 
      player!.addObserver(self, forKeyPath: "playbackBufferEmpty", options:NSKeyValueObservingOptions(), context: nil) 
      // player!.addObserver(self, forKeyPath: "playbackLikelyToKeepUp", options:NSKeyValueObservingOptions(), context: nil) 
      player!.addObserver(self, forKeyPath: "loadedTimeRanges", options: NSKeyValueObservingOptions(), context: nil) 

      player!.play() 
      sender.selected = true 
      selectIndex = sender.tag 
      activityView.startAnimating() 
      // self.view.userInteractionEnabled = false 


     } 
     else 
     { 

      deallocObservers(player!) 
      player?.pause() 
      sender.selected = false 
      selectIndex = -1 
     } 

     print(selectIndex) 

    } 

    func deallocObservers(player: AVPlayer) { 

     player.removeObserver(self, forKeyPath: "status") 
     player.removeObserver(self, forKeyPath: "playbackBufferEmpty") 
     // player.removeObserver(self, forKeyPath: "playbackLikelyToKeepUp") 
     player.removeObserver(self, forKeyPath: "loadedTimeRanges") 
    } 


    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>){ 

     if object?.isEqual(player) == true && keyPath == "status" { 
      print("status") 

      if player?.status == AVPlayerStatus.ReadyToPlay{ 
       print("AVPlayerStatus.ReadyToPlay") 
       activityView.stopAnimating() 
       // self.view.userInteractionEnabled = true 
      }else{ 
       print("AVPlayerStatus.NotReadyToPlay") 
       activityView.startAnimating() 
//    self.view.userInteractionEnabled = false 
      } 

      //if keyPath == "playbackLikelyToKeepUp" { 
       //activityView.stopAnimating() 
       ////self.view.userInteractionEnabled = true 
       //print("playbackLikelyToKeepUp") 
      //} 
      if keyPath == "playbackBufferEmpty" { 
       activityView.startAnimating() 
       self.view.userInteractionEnabled = false 

       let createAccountErrorAlert: UIAlertView = UIAlertView() 
       createAccountErrorAlert.delegate = self 
       createAccountErrorAlert.title = "No Internet Connection" 
       createAccountErrorAlert.message = "Make sure your device is connected to the internet." 
       createAccountErrorAlert.addButtonWithTitle("Dismiss") 

       createAccountErrorAlert.show() 

       print("playbackBufferEmpty") 
      } 

      if player?.status == AVPlayerStatus.Failed{ 
       print("Something went wrong . player.error should contain some information") 
      } 
     } 
    } 

Ausgabe

-1 
1 
status 
AVPlayerStatus.ReadyToPlay 
1 
2016-07-24 21:51:00.585 Radio[777:23560] *** Terminating app due to uncaught exception 'NSRangeException', reason: 'Cannot remove an observer <Radio.RadioCollectionViewController 0x7fbe39d47f70> for the key path "status" from <AVPlayer 0x7fbe39e67410> because it is not registered as an observer.' 
*** First throw call stack: 
(
    0 CoreFoundation      0x00000001019b2e65 __exceptionPreprocess + 165 
    1 libobjc.A.dylib      0x0000000103b51deb objc_exception_throw + 48 
    2 CoreFoundation      0x00000001019b2d9d +[NSException raise:format:] + 205 
    3 Foundation       0x0000000101fc4d51 -[NSObject(NSKeyValueObserverRegistration) _removeObserver:forProperty:] + 504 
    4 Foundation       0x0000000101fc4abd -[NSObject(NSKeyValueObserverRegistration) removeObserver:forKeyPath:] + 84 
    5 Radio        0x00000001014a935d _TFC5Radio29RadioCollectionViewController16deallocObserversfS0_FCSo8AVPlayerT_ + 141 
    6 Radio        0x00000001014a8fbe _TFC5Radio29RadioCollectionViewController24audioControlButtonActionfS0_FCSo8UIButtonT_ + 5326 
    7 Radio        0x00000001014a92ba _TToFC5Radio29RadioCollectionViewController24audioControlButtonActionfS0_FCSo8UIButtonT_ + 58 
    8 UIKit        0x0000000102630194 -[UIApplication sendAction:to:from:forEvent:] + 92 
    9 UIKit        0x000000010279f6fc -[UIControl sendAction:to:forEvent:] + 67 
    10 UIKit        0x000000010279f9c8 -[UIControl _sendActionsForEvents:withEvent:] + 311 
    11 UIKit        0x000000010279eaf8 -[UIControl touchesEnded:withEvent:] + 601 
    12 UIKit        0x000000010269f49b -[UIWindow _sendTouchesForEvent:] + 835 
    13 UIKit        0x00000001026a01d0 -[UIWindow sendEvent:] + 865 
    14 UIKit        0x000000010264eb66 -[UIApplication sendEvent:] + 263 
    15 UIKit        0x0000000102628d97 _UIApplicationHandleEventQueue + 6844 
    16 CoreFoundation      0x00000001018dea31 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17 
    17 CoreFoundation      0x00000001018d495c __CFRunLoopDoSources0 + 556 
    18 CoreFoundation      0x00000001018d3e13 __CFRunLoopRun + 867 
    19 CoreFoundation      0x00000001018d3828 CFRunLoopRunSpecific + 488 
    20 GraphicsServices     0x0000000106247ad2 GSEventRunModal + 161 
    21 UIKit        0x000000010262e610 UIApplicationMain + 171 
    22 Radio        0x00000001014afd5d main + 109 
    23 libdyld.dylib      0x000000010468892d start + 1 
) 
libc++abi.dylib: terminating with uncaught exception of type NSException 

Ich habe Lösung zum Entfernen von status observer von diesem Link gefunden, aber did't wissen, wie es in raschen wandeln.

Lösung

@try { [player removeObserver:self forKeyPath:@"status"]; } @catch (NSException *exception) { } @finally { } – 

Antwort

0

ich Überprüfung auf diesem hinzufügen Bedingungen.

var check = true 
func audioControlButtonAction(sender: UIButton){ 

     if check == false { 
      deallocObservers(player!) 
     } 
     if sender.selected == false{ 
      check = false 
     } 
     else{ 
      check = true 
     }   
    } 
1

Das Problem ist, dass die "deallocObservers" Verfahren ohne Zugabe von Beobachtern zwischen diesen beiden Anrufe zweimal aufgerufen wird. Ich denke einmal hier:

if player != nil && player?.currentItem != nil { 
     deallocObservers(player!) 
    } 

Der Spieler Variable und das aktuelle Element nicht Null das zweite Mal, wenn Sie diese Methode aufrufen sein. Und der zweite Aufruf von deallocObservers könnte hier sein:

 if bt.selected == true 
     { 
      bt.selected = false 
      deallocObservers(player!) 
     } 

ich einen Haltepunkt in der deallocObservers Methode setzen würde, um zu sehen, wie oft diese Methode aufgerufen wird und wer es nennt (Blick in die Stacktrace).

+0

jetzt lösche ich "deallocObservers" aus 'if bt.selected == true' und aus der Pause-Methode. Ich habe gesehen, mit Haltepunkt, dass, wenn ich Pause Beobachter entfernen, aber wenn ich es wieder spielen, es geht wieder 'If Player! = Nil && Spieler? .CurrentItem! = Nil' Methode so Beobachter sind bereits gelöscht, so dass dies Grund es gibt mir dieselben Fehler. Haben Sie eine Idee, was ich Bedingung hinzufügen muss? Danke – ZAFAR007

+0

Ich würde den deallocObservers (player!) Aufruf von der if bt.selected == true entfernen. Ist das wirklich nötig? – vladiulianbogdan

+0

lösche ich es schon und auch aus pause? – ZAFAR007

1

schnelle Version von

Objective C

@try { [player removeObserver:self forKeyPath:@"status"]; } @catch (NSException *exception) { } @finally { } 

Swift

Error Handling in Swift2

do { 
      try player.removeObserver(self, forKeyPath: "status") 
     } 

    catch { 
    print("error") 
    } 
    defer{ 
     print("finally statement here") 
    } 
+0

Dank Chandan Prajapati. Jetzt habe ich gesehen, dass dieses Problem wieder auf 'deallocObservers (player!)' Zurückzuführen ist, wenn ich wieder Musik spiele. Denn wenn ich wieder Musik spiele. es geht in 'if player! = nil && player ?.currentItem! = nil { deallocObserver (player!) } ' – ZAFAR007

Verwandte Themen