Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Andy Williams
4,436 PointsSwift: Music intros
Hi
I want to right an app that will take the first 15 seconds of each of my song library and play them in turn (or randomly).
I have created a MusicLibrary struct:
import Foundation
import MediaPlayer
struct MusicLibrary {
var musicLibrary: [SongItem] = []
let query = MPMediaQuery.songsQuery()
var mediaCollection : MPMediaItemCollection {
return MPMediaItemCollection(items: query.items!)
}
mutating func addSongs() {
for index in 0..<mediaCollection.count {
let mediaItem = mediaCollection.items[index]
let songItem = SongItem(
title: mediaItem.title!,
album: mediaItem.albumTitle!,
artist: mediaItem.artist!,
artwork: mediaItem.artwork!,
persistentID: mediaItem.persistentID,
genre: mediaItem.genre!
)
musicLibrary.append(songItem)
}
}
func getSong(index: Int)->SongItem {
return musicLibrary[index]
}
func getSongs()->[SongItem] {
return musicLibrary
}
}
.. And a SongItem struct
struct SongItem {
var title: String
var album: String
var artist: String
var artwork: MPMediaItemArtwork
var persistentID: UInt64
var genre: String
init(title: String, album: String, artist: String, artwork: MPMediaItemArtwork, persistentID: UInt64, genre: String) {
self.title = title
self.album = album
self.artist = artist
self.artwork = artwork
self.persistentID = persistentID
self.genre = genre
}
}
This successfully has all the song info in it and I can play a song from it using the MPMusicPlayerController, using a for loop to go through each song in turn using the PersistentID of the song.
let myMusicPlayer = MPMusicPlayerController()
let songs:[SongItem] = MusicPlayer.getSongs()
for index in 0..<songs.count {
let songToPlay: SongItem = songs[index]
let predicate = MPMediaPropertyPredicate(value: Int(songToPlay.persistentID), forProperty: MPMediaItemPropertyPersistentID)
let songQuery = MPMediaQuery()
songQuery.addFilterPredicate(predicate)
myMusicPlayer.setQueueWithItemCollection(songQuery.collections![0])
myMusicPlayer.play()
}
This successfully plays each song in turn, but whenever I try and add a timer to skip to the next song after 15 seconds, nothing happens.
The closest I have got is getting the first song to stop after 15 seconds.
Adding a timer like below
var clock = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "countdown", userInfo: nil, repeats: true)
func countdown() {
timer--
countdownLabel.text = String(timer)
// When the countdown hits zero we should stop the song.
if timer==0 {
myMusicPlayer.stop()
clock.invalidate()
timer = 15
}
}
Anyone got any ideas or point me in the right direction for reading? Any help would be wonderful.
-- A
2 Answers
jcorum
71,830 PointsInteresting project. But I'm puzzled. You say it plays successfully. But you have:
let myMusicPlayer = MPMusicPlayerController()
but then, in the next line, you say:
let songs:[SongItem] = MusicPlayer.getSongs()
Shouldn't it be myMusicPlayer.getSongs()
But even with that change, it still gets an error because MPMuscPlayerController has no getSongs() method.
I'm probably missing something. But I just copied your code into Xcode and these errors popped up.
Andy Williams
4,436 PointsHi jcorum,
Thanks for taking some time on this. The MusicLibrary is basically a store for all the information about the music on your phone. You then need to pass the persistent ID of each song to the MPMusicPlayerController which plays the songs.
You could extend the MPMusicPlayerController I guess to get the songs, but I did it this way.
Note this doesn't work in the simulator as there is no music in it.