JohnK JohnK - 1 month ago 10
iOS Question

How to split filename from file extension in Swift?

Given the name of a file in the bundle, I want load the file into my Swift app. So I need to use this method:

let soundURL = NSBundle.mainBundle().URLForResource(fname, withExtension: ext)

For whatever reason, the method needs the filename separated from the file extension. Fine, it's easy enough to separate the two in most languages. But so far I'm not finding it to be so in Swift.

So here is what I have:

var rt: String.Index = fileName.rangeOfString(".", options:NSStringCompareOptions.BackwardsSearch)
var fname: String = fileName .substringToIndex(rt)
var ext = fileName.substringFromIndex(rt)

If I don't include the typing on the first line, I get errors on the two subsequent lines. With it, I'm getting an error on the first line:

Cannot convert the expression's type '(UnicodeScalarLiteralConvertible, options: NSStringCompareOptions)' to type 'UnicodeScalarLiteralConvertible'

How can I split the filename from the extension? Is there some elegant way to do this?

I was all excited about Swift because it seemed like a much more elegant language than Objective C. But now I'm finding that it has its own cumbersomeness.

Second attempt: I decided to make my own string-search method:

func rfind(haystack: String, needle: Character) -> Int {
var a = Array(haystack)

for var i = a.count - 1; i >= 0; i-- {
if a[i] == needle {
return i;
return -1

But now I get an error on the line
var rt: String.Index = rfind(fileName, needle: ".")

'Int' is not convertible to 'String.Index'

Without the cast, I get an error on the two subsequent lines.

Can anyone help me to split this filename and extension?

Answer Source

This is with Swift 2, Xcode 7: If you have the filename with the extension already on it, then you can pass the full filename in as the first parameter and a blank string as the second parameter:

let soundURL = NSBundle.mainBundle()
    .URLForResource("soundfile.ext", withExtension: "")

Alternatively nil as the extension parameter also works.

If you have a URL, and you want to get the name of the file itself for some reason, then you can do this: