cchacholiades cchacholiades - 3 months ago 14
iOS Question

Downcast from 'String?' to 'String' only unwraps optionals

I am new to iOS development. I am trying to read a

.mid
file from the
DocumentDirectory
. I tried this:

var path = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first as! String
var midiFileURL = NSURL.fileURLWithPath(path)


The problem is:


Downcast from 'String?' to 'String' only unwraps optionals; did you mean to use '!'?


Once I read the file from the
DocumentsDirectory
I want to be able to play it back with this:

guard let bankURL = NSBundle.mainBundle().URLForResource("gs_instruments", withExtension: "dls") else {
fatalError("\"gs_instruments.dls\" file not found.")
}

do {
try self.midiPlayer = AVMIDIPlayer(contentsOfURL: midiFileURL, soundBankURL: bankURL)
print("created midi player with sound bank url \(bankURL)")
} catch let error as NSError {
print("Error \(error.localizedDescription)")
}

self.midiPlayer.prepareToPlay()

self.midiPlayer.play({
print("midi done")
})


How do I fix the error? Many thanks.

Answer

NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first is returning you an Optional<String> (a.k.a. String?). You're trying to cast this to String. The warning is telling you that you're doing this in a cumbersome way. You can just force unwrap it with !:

var path = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first!

Of course, because you're force unwrapping, you risk your application crashing in case the value returned is nil (in the case that there is no first... when the collection is empty).

I highly advice you read about Optionals in the Swift Language Guide - The Basics.