I am trying to stream music from parse using Swift 2.0 in Xcode 7 (I have 3 audio files I uploaded in Parse). I have been following a tutorial that came out about 6 months ago but apparently a lot has changed. I have been able to conform to all of the changes except one. When I run the app and tap on a row (which is a song) I get the error:
Could not cast value of type 'PFFile' (0x10dda2d50) to 'NSURL' (0x10e6d1c10).
Here is my code:
import UIKit
import Parse
import AVFoundation
import AVKit
public var AudioPlayer = AVPlayer()
public var SelectedSongNumber = Int()
class TableViewController: UITableViewController, AVAudioPlayerDelegate {
var iDArray = [String]()
var NameArray = [String]()
override func viewDidLoad() {
super.viewDidLoad()
var ObjectIDQuery = PFQuery(className: "Songs")
ObjectIDQuery.findObjectsInBackgroundWithBlock {
(objectsArray: [PFObject]?, error: NSError?) -> Void in
//objectsArray!.count != 0
var objectIDs = objectsArray!
NSLog("\(objectIDs)")
for i in 0...objectIDs.count-1 {
self.iDArray.append(objectIDs[i].valueForKey("objectId") as! String)
self.NameArray.append(objectIDs[i].valueForKey("SongName") as! String)
self.tableView.reloadData()
}
}
}
func grabSong () {
var songQuery = PFQuery(className: "Songs")
songQuery.getObjectInBackgroundWithId(iDArray[SelectedSongNumber], block: {
(object: PFObject?, error : NSError?) -> Void in
if let AudioFileURLTemporary = object?.objectForKey("SongFile") {
AudioPlayer = AVPlayer(URL: AudioFileURLTemporary as! NSURL)
AudioPlayer.play()
}
})
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return iDArray.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("Cell")
cell?.textLabel!.text = NameArray[indexPath.row]
return cell!
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
SelectedSongNumber = indexPath.row
grabSong()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
The line that is giving me trouble is AudioPlayer = AVPlayer(URL: AudioFileURLTemporary as! NSURL)
. Originally the tutorial had this line written as AudioPlayer = AVPlayer(URL: NSURL(string: AudioFileURLTemporary!))
but that doesn't work either.
How do I fix that?
PFFiles aren't in the same class hierarchy as NSURL, so they can't be cast to NSURL. Instead, you need to get get the url string from the url property of the PFFile:
func grabSong () {
var songQuery = PFQuery(className: "Songs")
songQuery.getObjectInBackgroundWithId(iDArray[SelectedSongNumber], block: {
(object: PFObject?, error : NSError?) -> Void in
if let audioFile = object?["SongFile"] as? PFFile {
let audioFileUrlString: String = audioFile.url //This might be actually be a String?, I don't remember.
let audioFileUrl = NSURL(string: audioFileUrlString)!
AudioPlayer = AVPlayer(URL: audioFileUrl)
AudioPlayer.play()
}
})
}