无法将 PFFile 类型的值转换为 NSURL

Posted

技术标签:

【中文标题】无法将 PFFile 类型的值转换为 NSURL【英文标题】:Could not cast value of type PFFile to NSURL 【发布时间】:2015-11-10 01:26:39 【问题描述】:

我正在尝试使用 Xcode 7 中的 Swift 2.0 从解析流式传输音乐(我在 Parse 中上传了 3 个音频文件)。我一直在关注大约 6 个月前发布的教程,但显然发生了很多变化。我已经能够遵守除一项之外的所有更改。当我运行应用程序并点击一行(这是一首歌曲)时,我收到错误:

无法将“PFFile”(0x10dda2d50)类型的值转换为“NSURL”(0x10e6d1c10)。

这是我的代码:

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.
    



给我带来麻烦的线路是AudioPlayer = AVPlayer(URL: AudioFileURLTemporary as! NSURL)。最初教程将此行写为AudioPlayer = AVPlayer(URL: NSURL(string: AudioFileURLTemporary!)),但这也不起作用。

我该如何解决这个问题?

【问题讨论】:

请注意,Xcode 标签仅用于与 Xcode IDE 相关的问题。 【参考方案1】:

PFFiles 与 NSURL 不在同一个类层次结构中,因此它们不能转换为 NSURL。相反,您需要从 PFFile 的 url 属性中获取 url 字符串:

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()
        
    )

【讨论】:

感谢您的快速回复。看起来这就是答案,但是当我尝试在 // let audioFileUrlString: String = audioFile.url ... (ambiguous ref...) 对不起。我忘了对“SongFile”数据进行类型转换。我会更新我的答案。希望它能解决问题。 嘿,我正在尝试同样的事情。我从此链接中获取了代码,当我点击didSelectRowAtIndexPath 时,它会进行查询,但没有播放音乐。 @ConfusedByCode【参考方案2】:

我用过这个版本。

item[index].parseFile.getFilePathInBackground  (urlStr, error) in
if (error == nil)

    self.SPB.startAnimation()

    guard let url = NSURL(fileURLWithPath: urlStr!) as URL? else 
        return
    
    self.player = AVPlayer(url: url)

    let videoLayer = AVPlayerLayer(player: self.player)
    videoLayer.frame = self.view.bounds
    videoLayer.videoGravity = .resizeAspect
    self.videoView.layer.addSublayer(videoLayer)

    let asset = AVAsset(url: url)
    let duration = asset.duration
    let durationTime = CMTimeGetSeconds(duration) + 5

    self.SPB.duration = durationTime
    self.player.play()


【讨论】:

以上是关于无法将 PFFile 类型的值转换为 NSURL的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中将 NSURL 转换为字符串

解析加载图像 Swift 3.0

无法将 NSString 转换为 NSURL

在for循环中将PFFile数组转换为UIImage返回空数组Swift

如何将 PFFile 数组转换为 UIImage 数组?

从 Parse 将 PFFile 转换为 NSData