2017-05-30 4 views
0

Ich versuche, Werte (MP3-Dateien aus dem Dokumentverzeichnis) zu NSMutableArray hinzuzufügen. Ich erstelle einen Musik-Player. Wenn ein Song fertig ist, sollte meine Methode den nächsten Song über AVAudioPlayer Delegate abspielen. Ich schrieb eine if Anweisung und prüft, ob die aktuelle Spur größer als ist, sollte es erste Lied spielen, deren Index 0 ist.Index von NSMutableArray startet nicht mit 0

Das Problem ist, App abstürzt aufgrund dieses Fehlers: fatal error: Array index out of range

Dann drucke ich meine Array und etwas Seltsames geschieht hier:

print("all files are :\(player.MP3DirectoryFiles.count)") 
print("all files :\(player.MP3DirectoryFiles.description)") 

alle Dateien: 2

alle Dateien :("Kuchen durch The Ocean.mp3", "LoveSong.mp3")

Es scheint, dass das Zählen OK ist! Es gibt 2 Dateien, aber das Problem ist Index des Arrays beginnt mit 0 so in diesem Fall player.MP3DirectoryFiles.count sollte sein: 1 was bedeutet: 0,1. [IN TABLE VIEW]

Ich muss sagen, alles funktioniert gut in der Tabellenansicht, um Zellen auszuwählen und Lieder abzuspielen, aber nachdem die Musik fertig ist, passiert das. ich brauche etwas Hilfe dieses Problem zu beheben hier mehr Code ist, wenn es hilft:

2 Editiert:

func playMusic(at:Int) { 

     let musicFile = MP3DirectoryFiles[at] as! NSString 

     let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! 
     let musicURL = documentsDirectory.appendingPathComponent(musicFile.lastPathComponent) 

     getDataFromTrack(file: musicURL) 

     do { 

      player = try AVAudioPlayer(contentsOf: musicURL) 
      player.prepareToPlay() 
      player.delegate = self 
      appDefaults.setTrack(duration: Float(player.duration)) 


     } catch let error as NSError { 

      print(error.description) 
     } 


    } 



    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) { 

     NotificationCenter.default.post(name: NSNotification.Name("musicIsFinished"), object: nil) 
    } 

Another Viewcontroller:

func musicIsFinished(notification:Notification) { 

     _trackRow = appDefaults.loadTrackNumber() 


     if _trackRow > player.MP3DirectoryFiles.count { 

      _trackRow = 0 


     } else { 

      _trackRow! += 1 

     } 

       player.playMusic(at: _trackRow!) 
       prepareToPlay() 


    } 
+2

"' player.MP3DirectoryFiles.count' sollte sein: 1 was bedeutet: 0,1 ", eigentlich sollte die Anzahl 2 sein, da das Array 2 Objekte enthält. –

+0

@JamesP also was ist mit der Anzahl der Indizes? –

+0

Sie wollen wahrscheinlich 'wenn currentTrack == array.count-1 {// ist der letzte Track}' –

Antwort

2

Ok, so dass Sie zwei Songs in deinem Array.

Wenn Sie das erste Lied, das Sie sagen, anfangen zu spielen ... an Position den Song spielen 0 (als NSMutableArrays Null ... basiert sind, wie Sie bereits wissen :))

Sobald der Song ist Ihr musicIsFinished Verfahren endet namens.

Hier überprüfen Sie, was als nächstes zu spielen ist. _trackRow

Im Moment ist 0, weil das der Song Sie gespielt und player.MP3DirectoryFiles.count ist 2.

Ihr Code wie folgt aussieht:

if _trackRow > player.MP3DirectoryFiles.count { 
    _trackRow = 0 
} else { 
    _trackRow! += 1 
} 

So Sie in else enden. _trackRow wird erhöht und ist jetzt 1.

Weiter Sie playSong(at: 1) stellen und das funktioniert (ich hoffe :))

OK ... nächste Song fertig ist, und wir sind auf musicIsFinished zurück._trackRow 1 und player.MP3DirectoryFiles.count noch 2

Also, Sie wieder überprüfen:

if _trackRow > player.MP3DirectoryFiles.count

es ist nicht so _trackRow-2 erhöht wird, und dann fragen Sie Ihre Array Sie den Song am Index geben 2

aber ... es gibt kein Lied im Index zwei richtig? Ihr Array ist nullbasiert, Sie haben also einen Song bei Index 0 und Index 1, aber nicht bei Index 2 ... also wird Ihre App durcheinander gebracht und stürzt ab.

Sie benötigen if _trackRow > player.MP3DirectoryFiles.count umdrehen und stattdessen fragen:

if _trackRow < player.MP3DirectoryFiles.count - 1

Was bedeutet, dass:

Die erste Mal musicIsFinished geben Sie seit

im else Teil am Ende
  • _trackRow ist 0
  • player.MP3DirectoryFiles.count - 1 ist 1

und 0 kleiner als 1

Die Sekunden Zeit um Sie im if Teil am Ende da

  • _trackRow 1 ist
  • player.MP3DirectoryFiles.count - 1 ist 1

und 1 ist nicht kleiner als 1

Lange Geschichte, die ich kenne, aber versuchen Sie Ihr musicIsFinished zu diesem Wechsel:

func musicIsFinished(notification:Notification) { 
    _trackRow = appDefaults.loadTrackNumber() 

    if _trackRow < player.MP3DirectoryFiles.count - 1 { 
     _trackRow += 1 
    } else { 
     _trackRow = 0 
    } 
    player.playMusic(at: _trackRow!) 
    prepareToPlay() 
} 

Hoffnung, das Ihnen hilft.

+0

Danke für Ihre Hilfe! es funktioniert jetzt gut –

+0

@ Mc.Lover froh, dass es funktioniert :) – pbodsk

Verwandte Themen