Ludo Ludo - 1 month ago 15
iOS Question

Optional in file path Swift3

In swift3 I have problem to access local files that I downloaded then unzipped.

The path contains "Optional":

Users/name/Library/Developer/CoreSimulator/Devices/..../data/Containers/Data/Application/...
/Documents/Optional("folder-name")/Optional("file-name")


My code to create this path is:

let videoPath = fileManager!.appendingPathComponent("\(MyObj.folder)/\(MyObj.fileName)")
SpeedLog.print(videoPath.path)


The class MyObj is:

class MyObj : NSObject, NSCoding {
var fileName:String!
var folder:String!

required convenience init?(coder decoder: NSCoder) {
self.init()
self.fileName = decoder.decodeObject(forKey: "fileName") as! String
....
}
convenience init(id:Int,fileName:String,...) {
self.init()
self.fileName = fileName
....
}
func encode(with coder: NSCoder) {
if let fileName = fileName { coder.encode(fileName, forKey: "fileName") }
....
}


How to build the path without "Optional?

Answer

Seeing "Optional" in your string output means you're passing in an optional, a variable that might contain a value or might contain nil. If you're certain that it isn't nil when you want to use it, you can force unwrap it by adding ! to its name, which makes it no longer optional. If you do this to a variable that is nil, you'll get a runtime error. Alternatively you can unwrap using let.

var optional:String?            // optional, contains nil
print(optional)                 // 'nil'
optional = "something"          // still optional, contains "something"
print(optional)                 // 'Optional("something")'
print(optional!)                // 'something'
let nonOptional = optional!     // not optional, contains "something"
print(nonOptional)              // 'something'

There's a lot more about optionals in the Swift docs.

In the MyObj class definition you provided it looks like the fileName and folder instance variables are set up as non-optional, which is what you want. But in this line:

let videoPath = fileManager!.appendingPathComponent("\(MyObj.folder)/\(MyObj.fileName)")

you're using MyObj.folder and MyObj.fileName, which are static properties (properties of the class rather than an instance of the class). The MyObj class definition you provided does not define these as static variables, so this code would not compile as written.

For your case you can probably just force unwrap your optionals by adding !. But you'll have better luck in the long run if you take the time to read the documentation and understand optional variables.