Swift - NSURL fileURLWithPath没有解包?

时间:2014-11-30 15:24:58

标签: swift nsurl optional

非常简单:我在这两行中获得"Value of optional type 'NSURL?' not unwrapped.",我试图从我现有的Objective-C应用程序中翻译出来:

func urlForScene(sceneID:Scene) -> NSURL {
    var filename:NSString = "Whatever"
    let path = NSBundle.mainBundle().pathForResource(filename, ofType: "m4a")
    return NSURL.fileURLWithPath(path)
} 

我认为这对于path为零的可能性来说可能是一件非常简单的事情,但我还没有找到任何让我知道我应该在这里做什么的其他问题。如果这是一个愚蠢的问题,请道歉。

如果NSURL没有打开,我应该打开它吗?我需要以不同方式致电fileURLWithPath:吗?

提前致谢。

5 个答案:

答案 0 :(得分:2)

NSURL.fileURLWithPath(path)会返回一个可选的NSURL,正如您在声明中所看到的那样。

class func fileURLWithPath(path: String) -> NSURL?

但是您的urlForScene方法会返回非可选的NSURL。 如果您确定将返回一个URL,您可以通过在末尾添加感叹号来解开它(别名:解包)

return NSURL.fileURLWithPath(path)!

但是,出于安全原因,我建议您在返回值之前检查nil:

let returningURL : NSURL? = NSURL.fileURLWithPath("http://www.lombax.it")
if let url = returningURL
{
    return url
} else {
    // do something else
}

答案 1 :(得分:2)

正确答案取决于你未提及的几件事。

您是否知道该文件将存在于捆绑包中:

func urlForScene(sceneID:Scene) -> NSURL {
    var filename = "Whatever"
    let path = NSBundle.mainBundle().pathForResource(filename, ofType: "m4a")
    return NSURL(fileURLWithPath:path!)!
}

如果您不确定该文件是否存在于捆绑包中,那么最好传回一个可选项:

func urlForScene(sceneID:Scene) -> NSURL? {
    var result: NSURL?
    var filename = "Whatever"
    if let path = NSBundle.mainBundle().pathForResource(filename, ofType: "m4a") {
        result = NSURL(fileURLWithPath:path)
    }
    return result
}

答案 2 :(得分:1)

问题在于:urlForScene返回NSURL,而fileURLWithPath:返回可选:NSURL?,(根据doc

所以,问题是,fileURLWithPath:可能会返回nil(这就是它返回NSURL?的原因),并返回一个非零对象(NSURL )。

编译器会告诉您打开它,但我告诉您最好返回NSURL?并稍后在代码中进行检查。

另外,您不应该使用NSObject.someInitializer(anObject),而是NSObject(initializer:anObject)。在您的情况下,请将NSURL.fileURLWithPath(path)替换为NSURL(fileURLWithPath:path)

总结一下,这是工作代码:

func urlForScene(sceneID:Scene) -> NSURL? {
    let filename = "Whatever"

    let path = NSBundle.mainBundle().pathForResource(filename, ofType: "m4a")
    if let path = path {
        return NSURL(fileURLWithPath:path)
    } else {
        return nil
    }

/* this would also work, it's a matter of taste :
if let path = NSBundle.mainBundle().pathForResource(filename, ofType: "m4a") {
    return NSURL(fileURLWithPath:path)
}
return nil
*/

} 

let mySceneURL = urlForScene(someScene)
if let mySceneURL = mySceneURL {
    /* use the scene */
} else {
    /* the scene couldn't be intialized */
}

答案 3 :(得分:1)

通过返回NSURL类型,您声明该方法必须在所有情况下返回NSURL。该方法的唯一替代方法是崩溃。

通过返回NSURL(...)很容易实现!带有感叹号。您的代码将返回NSURL,否则它将崩溃。如果那就是你想要的......或者如果绝对是百分百肯定的话,那个fileURLWithPath就不会失败。

答案 4 :(得分:1)

如果您的文件是本地的,并且没有机会成为零,请转到目标>构建阶段并确保将其添加到Copy Bundle Resources。